This commit is contained in:
2024-04-14 18:38:39 +08:00
commit af0dfbbbb8
593 changed files with 212903 additions and 0 deletions

380
Source/EC800M_4G.c Normal file
View File

@@ -0,0 +1,380 @@
#include "EC800M_GPS.h"
#include "EC800M_4G.h"
int _r = 0;
int _timeout = 1;
// 存放4G数据
char _4G_DATA[_4G_DATA_LENGTH];
int _4G_DATA_LEN;
// 重置4G数据缓冲区
void _4g_reset_data()
{
memset(_4G_DATA, 0, _4G_DATA_LENGTH);
_4G_DATA_LEN = 0;
}
void uart_send_string(const char *str)
{
size_t len = strlen(str);
uart_write_blocking(EC800M_4G_UART, (const uint8_t *)str, len);
return;
}
int _4G_uart_read_string(char *_4G_DATA, int *_4G_DATA_LEN)
{
int _time = 0;
int timeout = 3000; // 设置超时时间为3秒单位为毫秒
while (1) {
// 检查是否超时
if (_time >= timeout) {
printf("EC800M _4G_uart_read_string() 读取超时\n");
return -1;
}
if (uart_is_readable(EC800M_4G_UART)) {
if (*_4G_DATA_LEN < _4G_DATA_LENGTH - 1) {
char c = uart_getc(EC800M_4G_UART);
_4G_DATA[(*_4G_DATA_LEN)++] = c;
_4G_DATA[*_4G_DATA_LEN] = '\0';
}
} else {
break;
}
sleep_ms(1); // 稍微延迟一下,等待下一个循环
_time++;
}
return 0;
}
int _4G_uart_read_string_until_response(char *DATA, int *DATA_LEN, const char *expected_response)
{
int timeout = 10000; // 设置超时时间为10秒单位为毫秒
*DATA_LEN = 0;
int _time = 0;
while (1) {
while (uart_is_readable(EC800M_4G_UART)) {
if (*DATA_LEN < _4G_DATA_LENGTH) {
char c = uart_getc(EC800M_4G_UART);
DATA[(*DATA_LEN)++] = c;
DATA[*DATA_LEN] = '\0'; // 添加字符串结束符
}
if (strstr(DATA, expected_response) != NULL) {
return 0; // 找到了预期的响应,退出循环
} else {
//printf("%s\n", DATA);
}
}
_time++;
sleep_ms(1); // 等待一小段时间再继续读取
if (_time >= timeout) {
_time = 0;
printf("EC800M _4G_uart_read_string_until_response() 读取超时\n");
return -1;
}
}
}
int EC800M_4G_INIT()
{
// AT+CFUN=1,1
//uart_send_string("AT+CFUN=1,1\r\n");
// AT+CGREG=2
uart_send_string("AT+CGREG=2\r\n");
sleep_ms(10);
if (-1 == _4G_uart_read_string_until_response(_4G_DATA, &_4G_DATA_LEN, "OK")) {
printf("EC800M Module 4G AT+QIACT? Timeout!\n");
return -1;
}
printf("%s %d\n", _4G_DATA, _4G_DATA_LEN);
// AT+CGATT=1
uart_send_string("AT+CGATT=1\r\n");
sleep_ms(10);
if (-1 == _4G_uart_read_string_until_response(_4G_DATA, &_4G_DATA_LEN, "OK")) {
printf("EC800M Module 4G AT+CGATT=1 Timeout!\n");
return -1;
}
printf("%s %d\n", _4G_DATA, _4G_DATA_LEN);
// AT+CEREG=2
uart_send_string("AT+CEREG=2\r\n");
sleep_ms(10);
if (-1 == _4G_uart_read_string_until_response(_4G_DATA, &_4G_DATA_LEN, "OK")) {
printf("EC800M Module 4G AT+CEREG=2 Timeout!\n");
return -1;
}
printf("%s %d\n", _4G_DATA, _4G_DATA_LEN);
// AT+QICSGP=1
uart_send_string("AT+QICSGP=1\r\n");
//sleep_ms(10);
if (-1 == _4G_uart_read_string_until_response(_4G_DATA, &_4G_DATA_LEN, "OK")) {
printf("EC800M Module 4G AT+QICSGP=1 Timeout!\n");
return -1;
}
printf("%s %d\n", _4G_DATA, _4G_DATA_LEN);
// AT+QIACT=1
uart_send_string("AT+QIACT=1\r\n");
sleep_ms(10);
if (-1 == _4G_uart_read_string(_4G_DATA, &_4G_DATA_LEN)) {
return -1;
}
printf("%s %d\n", _4G_DATA, _4G_DATA_LEN);
// AT+QIACT?
uart_send_string("AT+QIACT?\r\n");
if (-1 == _4G_uart_read_string_until_response(_4G_DATA, &_4G_DATA_LEN, "OK")) {
printf("EC800M Module 4G AT+QIACT? Timeout!\n");
return -1;
}
printf("%s %d\n", _4G_DATA, _4G_DATA_LEN);
// AT+QIDEACT=1
uart_send_string("AT+QIDEACT=1\r\n");
if (-1 == _4G_uart_read_string_until_response(_4G_DATA, &_4G_DATA_LEN, "OK")) {
printf("EC800M Module 4G AT+QIDEACT=1 Timeout!\n");
return -1;
}
printf("%s %d\n", _4G_DATA, _4G_DATA_LEN);
// AT+QIOPEN=1,0,"TCP","47.240.75.93",8009,0,1
uart_send_string("AT+QIOPEN=1,0,\"TCP\",\"123.60.29.178\",8009,0,1\r\n");
if (-1 == _4G_uart_read_string_until_response(_4G_DATA, &_4G_DATA_LEN, "0,0")) {
printf("EC800M Module 4G \"AT+QIOPEN=1,0,\"TCP\",\"123.60.29.178\",8009,0,1\r\n\" Timeout!\n");
return -1;
}
printf("%s %d\n", _4G_DATA, _4G_DATA_LEN);
/*
// AT+QISTATE=1,0
uart_send_string("AT+QISTATE=1,0\r\n");
if (-1 == _4G_uart_read_string(_4G_DATA, &_4G_DATA_LEN)) {
printf("EC800M Module 4G AT+QISTATE=1,0 Timeout!\n");
return -1;
}
printf("%s %d\n", _4G_DATA, _4G_DATA_LEN);
*/
return 1;
}
int receive_data(char *input_string)
{
char temp_buffer[270] = { 0 };
char received_data[270] = { 0 };
int received_data_length = 0;
int step = 1;
char *token = NULL;
char *start = NULL;
char *end = NULL;
size_t temp_length = 0;
// 在指针不为NULL时才进行后续操作
start = strstr(input_string, "QIURC");
if (start == NULL) {
printf("Error: 'QIURC' not found\n");
return -1; // 返回错误代码
}
end = strstr(start, "\r\n");
if (end == NULL) {
printf("Error: '\\r\\n' not found\n");
return -1; // 返回错误代码
}
temp_length = end - start; // 计算子字符串的长度
if (temp_length >= sizeof(temp_buffer)) {
printf("Error: Substring length exceeds buffer size\n");
return -1; // 返回错误代码
}
// 复制子字符串到 TEMP 中
memcpy(temp_buffer, start, temp_length);
temp_buffer[temp_length] = '\0'; // 添加字符串结束标志
// 使用 strtok 解析 TEMP 字符串
token = strtok(temp_buffer, ",");
while (token != NULL) {
if (step == 3) {
received_data_length = atoi(token);
}
token = strtok(NULL, ",");
step++;
}
// 检查 received_data_length 是否为有效值
if (received_data_length <= 0 || received_data_length >= (int)sizeof(received_data)) {
printf("Error: Invalid received_data_length value\n");
return -1; // 返回错误代码
}
// 复制数据到 received_data 中
memcpy(received_data, end + 2, received_data_length);
received_data[received_data_length] = '\0'; // 添加字符串结束标志
printf("%s", received_data);
return 0; // 返回成功代码
}
// 查询Socket状态
int CHECK_TCP_STATUS()
{
char RECV[270] = { 0 };
int RECV_LEN = 0;
int step = 1;
int socket_state = 0;
printf("Query Socket status!!!\n");
uart_send_string("AT+QISTATE=1,0\r\n");
if (-1 == _4G_uart_read_string_until_response(RECV, &RECV_LEN, "OK")) {
printf("EC800M Module 4G AT+QISTATE=1,0 Timeout!\n");
return -1;
}
printf("%s %d\n", RECV, RECV_LEN);
char *token = strtok(RECV, ",");
while (token != NULL) {
if (step == 7) {
socket_state = atoi(token);
}
token = strtok(NULL, ",");
step++;
}
printf("socket_state: %d\n", socket_state);
return socket_state;
}
// 重新连接TCP
int TCP_RESTART()
{
char RECV[270] = { 0 };
int RECV_LEN = 0;
printf("Re-establish TCP!!!\n");
uart_send_string("AT+QICLOSE=0\r\n");
if (-1 == _4G_uart_read_string_until_response(RECV, &RECV_LEN, "OK")) {
printf("EC800M Module 4G AT+QICLOSE=0 Timeout!\n");
return -1;
}
printf("%s %d\n", RECV, RECV_LEN);
uart_send_string("AT+QIOPEN=1,0,\"TCP\",\"123.60.29.178\",8009,0,1\r\n");
if (-1 == _4G_uart_read_string_until_response(RECV, &RECV_LEN, "0,0")) {
printf("EC800M Module 4G AT+QICLOSE=0 Timeout!\n");
return -1;
}
printf("%s %d\n", RECV, RECV_LEN);
sleep_ms(3000);
return 0;
}
#include <stdbool.h>
// 全局变量表示TCP连接是否已经成功建立过
bool tcp_connection_established = false;
int establish_tcp_connection()
{
// 如果TCP连接已经成功建立过则直接返回成功
if (tcp_connection_established) {
printf("TCP connection already established.\n");
return 0;
}
int _r = EC800M_4G_INIT(); // 第一次建立TCP
int retry_count = 0; // 重试计数器
while (_r == -1 && retry_count < TCP_MAX_RETRY) {
printf("TCP establishment failed! Retrying...\n");
_r = EC800M_4G_INIT(); // 重新建立TCP连接
retry_count++;
sleep_ms(9000); // 等待一段时间后重试
}
if (_r == -1) {
printf("Failed to establish TCP connection after %d retries.\n", TCP_MAX_RETRY);
return -1; // 返回连接失败
} else {
printf("TCP connection established successfully.\n");
// 标记TCP连接已经成功建立过
tcp_connection_established = true;
return 0; // 返回连接成功
}
}
int EC800M_4G_RECV(char *string)
{
char RECV[1024] = { 0 };
int RECV_LEN = 0;
uint8_t CTRLZ[1];
uart_send_string("AT+QISEND=0\r\n");
sleep_ms(100);
uart_send_string(string);
CTRLZ[0] = 0X1A;
uart_write_blocking(EC800M_4G_UART, CTRLZ, 1);
if (-1 == _4G_uart_read_string_until_response(RECV, &RECV_LEN, "SEND OK")) {
printf("EC800M Module 4G AT+QISEND=0 Timeout!\n");
_timeout++;
if (2 != CHECK_TCP_STATUS()) {
if (-1 == TCP_RESTART()) {
printf("TCP RESTART ERROR!\n");
}
}
} else {
receive_data(RECV);
if (2 != CHECK_TCP_STATUS()) {
if (-1 == TCP_RESTART()) {
printf("TCP RESTART ERROR!\n");
}
}
}
sleep_ms(3000);
return 0;
}
void EC800M_4G(void *p)
{
(void)p;
EC800M_UART_INIT();
while (1) {
printf("EC800M Module 4G\n");
int result = establish_tcp_connection();
if (result == 0) {
;
}
EC800M_4G_RECV("abcd\r\n");
EC800M_4G_RECV("aixiao.me\r\n");
EC800M_GPS(NULL);
vTaskDelay(pdMS_TO_TICKS(3000)); // 非阻塞延时
}
return;
}

40
Source/EC800M_4G.h Normal file
View File

@@ -0,0 +1,40 @@
#ifndef EC800M_4G_H
#define EC800M_4G_H
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/clocks.h"
#include "hardware/watchdog.h"
#include "pico/multicore.h"
#include "hardware/i2c.h"
#include "pico/binary_info.h"
#include "hardware/uart.h"
#include "hardware/pwm.h"
#include "hardware/adc.h"
#define EC800M_4G_UART uart1
#define EC800M_4G_UART_TX 9 // 接EC800M TX 上
#define EC800M_4G_UART_RX 8 // 接EC800M RX 上
#define EC800M_4G_DATA_BITS 8
#define EC800M_4G_STOP_BITS 1
#define EC800M_4G_UART_BAUD_RATE 115200
#define TCP_MAX_RETRY 3 // TCP建立最大重试次数
#define _4G_DATA_LENGTH 8192
extern void EC800M_4G(void *p);
#endif

253
Source/EC800M_GPS.c Normal file
View File

@@ -0,0 +1,253 @@
#include "EC800M_GPS.h"
// 存放GPS数据
char GPSDATA[GPSDATA_LENGTH];
int GPSDATA_LEN;
// 重置GPS数据缓冲区
void gps_reset_data()
{
memset(GPSDATA, 0, GPSDATA_LENGTH);
GPSDATA_LEN = 0;
}
// 初始化 EC800M 串口
int EC800M_UART_INIT()
{
uart_init(EC800M_GPS_UART, GPS_UART_BAUD_RATE);
gpio_set_function(GPS_UART_TX, GPIO_FUNC_UART);
gpio_set_function(GPS_UART_RX, GPIO_FUNC_UART);
uart_set_hw_flow(EC800M_GPS_UART, false, false);
uart_set_format(EC800M_GPS_UART, GPS_DATA_BITS, GPS_STOP_BITS, UART_PARITY_NONE);
return 0;
}
void _gps_uart_send_string(const char *str)
{
size_t len = strlen(str);
uart_write_blocking(EC800M_GPS_UART, (const uint8_t *)str, len);
return;
}
int _gps_uart_read_string()
{
int _time = 0;
int timeout = 3000; // 设置超时时间为7秒单位为毫秒
while (1) {
if (uart_is_readable(EC800M_GPS_UART)) {
char c = uart_getc(EC800M_GPS_UART);
if (GPSDATA_LEN < GPSDATA_LENGTH - 1) {
GPSDATA[GPSDATA_LEN++] = c;
GPSDATA[GPSDATA_LEN] = '\0';
}
} else {
return 0;
}
// 检查是否超时
if (_time >= timeout) {
printf("EC800M _gps_uart_read_string() 读取超时\n");
return -1;
}
sleep_ms(1); // 稍微延迟一下,等待下一个循环
_time++;
}
return 0;
}
int _gps_uart_read_string_until_response(const char *expected_response)
{
gps_reset_data();
int timeout = 3000; // 设置超时时间为7秒单位为毫秒
int i = 0;
int _time = 0;
while (1) {
while (uart_is_readable(EC800M_GPS_UART)) {
char c = uart_getc(EC800M_GPS_UART);
GPSDATA[i++] = c;
GPSDATA[i] = '\0'; // 添加字符串结束符
if (strstr(GPSDATA, expected_response) != NULL) {
GPSDATA_LEN = i;
return 0; // 找到了预期的响应,退出循环
}
}
_time++;
sleep_ms(1); // 等待一小段时间再继续读取
if (_time >= timeout) {
_time = 0;
printf("EC800M _gps_uart_read_string_until_response() 读取超时\n");
return -1;
}
}
}
// GPS 经纬度转10进制
long double convertToDecimal(long double coordinate)
{
int degree = (int)(coordinate / 100);
long double minutes = coordinate - degree * 100;
return degree + minutes / 60;
}
// 解释GPS数据
int EC800M_GPS_DATA_PARSING(char *GPS_DATA, GPS_ * gps_)
{
int i = 1;
char *p;
char *p1;
char *token;
p = strchr(GPS_DATA, ':');
if (p == NULL) {
return -1;
}
p1 = strstr(p + 2, "\r\n");
if (p1 == NULL) {
return -1;
}
char GPS_DATA_[p1 - p];
memset(gps_->time, 0, 20);
memset(gps_->N, 0, 20);
memset(gps_->E, 0, 20);
memset(GPS_DATA_, 0, p1 - p);
memcpy(GPS_DATA_, p + 2, p1 - p - 2 + 1);
GPS_DATA_[p1 - p - 2 + 1] = '\0';
printf("%s\n", GPS_DATA_);
token = strtok(GPS_DATA_, ",");
while (token != NULL) {
if (i == 1) {
strcpy(gps_->time, token);
}
if (i == 2) {
strcpy(gps_->N, token);
}
if (i == 3) {
strcpy(gps_->E, token);
}
token = strtok(NULL, ",");
i++;
}
gps_->N[strlen(gps_->N) - 1] = '\0';
gps_->E[strlen(gps_->E) - 1] = '\0';
// 095921.00
char hours[3] = { 0 };
char minutes[3] = { 0 };
char seconds[9] = { 0 };
char *p2 = gps_->time;
memcpy(hours, p2, 2);
memcpy(minutes, p2 + 2, 2);
memcpy(seconds, p2 + 4, 2);
//printf("GPS 修正时间: %d:%s:%s\n", atoi(hours) + 8, minutes, seconds);
sprintf(gps_->time, "%d:%s:%s", atoi(hours) + 8, minutes, seconds);
sprintf(gps_->N, "%.6lf", convertToDecimal(atof(gps_->N)));
sprintf(gps_->E, "%.6lf", convertToDecimal(atof(gps_->E)));
return 0;
}
// 初始化 EC800M GPS
int EC800M_GPS_INIT()
{
_gps_uart_send_string("AT+QGPSCFG=\"outport\",\"uartdebug\"\r\n");
sleep_ms(100);
if (-1 == _gps_uart_read_string()) {
return -1;
}
_gps_uart_send_string("AT+QGPSCFG=\"nmeasrc\",1\r\n");
sleep_ms(100);
if (-1 == _gps_uart_read_string()) {
return -1;
}
_gps_uart_send_string("AT+QGPSCFG=\"gpsnmeatype\",63\r\n");
sleep_ms(100);
if (-1 == _gps_uart_read_string()) {
return -1;
}
_gps_uart_send_string("AT+QGPSCFG=\"gnssconfig\",1\r\n");
sleep_ms(100);
if (-1 == _gps_uart_read_string()) {
return -1;
}
_gps_uart_send_string("AT+QGPSCFG=\"autogps\",0\r\n");
sleep_ms(100);
if (-1 == _gps_uart_read_string()) {
return -1;
}
_gps_uart_send_string("AT+QGPSCFG=\"apflash\",0\r\n");
sleep_ms(100);
if (-1 == _gps_uart_read_string()) {
return -1;
}
_gps_uart_send_string("AT+QGPS=1\r\n");
sleep_ms(100);
if (-1 == _gps_uart_read_string()) {
return -1;
}
// 打印第一次初始化输出
//printf("%s %d\n", GPSDATA, strlen(GPSDATA));
return 0;
}
void EC800M_GPS(void *p)
{
(void)p;
//while (1) {
printf("EC800M Module GPS\n");
GPS_ gps_;
memset(gps_.time, 0, 20);
memset(gps_.N, 0, 20);
memset(gps_.E, 0, 20);
if (-1 == EC800M_GPS_INIT()) {
printf("EC800M_INIT() 第一次初始化失败\n");
}
_gps_uart_send_string("AT+QGPSLOC=0\r\n");
if (-1 == _gps_uart_read_string_until_response("OK")) {
printf("重启EC800M模块 GPS\n");
EC800M_GPS_INIT();
}
sleep_ms(300);
//printf("%s %d %d\n", GPSDATA, strlen(GPSDATA), GPSDATA_LEN);
if (NULL == strstr(GPSDATA, "ERROR") && GPSDATA_LEN > 0) {
EC800M_GPS_DATA_PARSING(GPSDATA, &gps_);
printf(" T: %s\n N: %s\n E: %s\n", gps_.time, gps_.N, gps_.E);
printf(" NE: %s, %s\n", gps_.N, gps_.E);
}
printf("\n");
vTaskDelay(pdMS_TO_TICKS(3000)); // 非阻塞延时
//}
return;
}

41
Source/EC800M_GPS.h Normal file
View File

@@ -0,0 +1,41 @@
#ifndef EC800M_GPS_H
#define EC800M_GPS_H
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/clocks.h"
#include "hardware/watchdog.h"
#include "pico/multicore.h"
#include "hardware/i2c.h"
#include "pico/binary_info.h"
#include "hardware/uart.h"
#include "hardware/pwm.h"
#include "hardware/adc.h"
#define EC800M_GPS_UART uart1
#define GPS_UART_TX 9 // 接EC800M TX 上
#define GPS_UART_RX 8 // 接EC800M RX 上
#define GPS_DATA_BITS 8
#define GPS_STOP_BITS 1
#define GPS_UART_BAUD_RATE 115200
#define GPSDATA_LENGTH 8192
typedef struct GPS_ {
char time[20];
char N[20];
char E[20];
} GPS_;
extern int EC800M_UART_INIT();
extern void EC800M_GPS(void *p);
#endif

137
Source/FreeRTOSConfig.h Normal file
View File

@@ -0,0 +1,137 @@
/*
* FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
/* Scheduler Related */
#define configUSE_PREEMPTION 1
#define configUSE_TICKLESS_IDLE 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 1
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES 32
#define configMINIMAL_STACK_SIZE ( configSTACK_DEPTH_TYPE ) 256
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
/* Synchronization Related */
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configUSE_QUEUE_SETS 1
#define configUSE_TIME_SLICING 1
#define configUSE_NEWLIB_REENTRANT 0
#define configENABLE_BACKWARD_COMPATIBILITY 0
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
/* System */
#define configSTACK_DEPTH_TYPE uint32_t
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
/* Memory allocation related definitions. */
#define configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE (128*1024)
#define configAPPLICATION_ALLOCATED_HEAP 0
/* Hook function related definitions. */
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS 0
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
/* Co-routine related definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES 1
/* Software timer related definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH 1024
/* Interrupt nesting behaviour configuration. */
/*
#define configKERNEL_INTERRUPT_PRIORITY [dependent of processor]
#define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application]
#define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application]
*/
/* SMP port only */
#define configNUMBER_OF_CORES 1
#define configTICK_CORE 0
#define configRUN_MULTIPLE_PRIORITIES 0
/* RP2040 specific */
#define configSUPPORT_PICO_SYNC_INTEROP 1
#define configSUPPORT_PICO_TIME_INTEROP 1
#include <assert.h>
/* Define to trap errors during development. */
#define configASSERT(x) assert(x)
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_xTaskResumeFromISR 1
#define INCLUDE_xQueueGetMutexHolder 1
/* A header file that defines trace macro can be included here. */
#endif /* FREERTOS_CONFIG_H */

105
Source/HC-04.c Normal file
View File

@@ -0,0 +1,105 @@
#include "HC-04.h"
#include "common.h"
uint8_t HC04_DATA[1024] = { 0 };
int HC04_DATA_LEN = 0;
int HC_04_UART_INIT(int pio)
{
// 初始化UART
if (pio == 1) {
uint tx_offset = pio_add_program(HC_04_PIO, &uart_tx_program);
uart_tx_program_init(HC_04_PIO, HC_04_PIO_SM_TX, tx_offset, HC_04_PIO_TX_PIN, HC_04_PIO_SERIAL_BAUD);
uint rx_offset = pio_add_program(HC_04_PIO, &uart_rx_program);
uart_rx_program_init(HC_04_PIO, HC_04_PIO_SM_RX, rx_offset, HC_04_PIO_RX_PIN, HC_04_PIO_SERIAL_BAUD);
}
return 0;
}
int HC_04_PIO_UART_TX_DATA(PIO pio, uint sm, char *DATA, int DATA_LEN)
{
for (int i = 0; i < DATA_LEN; i++) {
uart_tx_program_putc(pio, sm, DATA[i]);
sleep_ms(1);
}
return 0;
}
int HC_04_PIO_UART_RX_DATA(PIO pio, uint sm, uint8_t * DATA, int DATA_LEN)
{
char c = '\0';
int received_count = 0;
int timeout_ms = 1000; // 设置较长的超时时间
while (received_count < DATA_LEN && timeout_ms > 0) {
if (uart_rx_program_available(pio, sm)) {
c = uart_rx_program_getc(pio, sm);
DATA[received_count++] = c;
//printf("0x%X ", c);
} else {
// 没有接收到数据,继续等待
sleep_ms(2);
timeout_ms--;
}
}
if (received_count == 0) {
// 没有接收到有效数据
return -1;
}
return received_count;
}
void HC_04_UART_WRITE(void *p)
{
(void)p;
/*
AT+RESET // 重启
AT+RX // 查询模块多个参数
*/
char _CMD0[] = "AT+RX"; // 查询
// 发送数据
HC_04_PIO_UART_TX_DATA(HC_04_PIO, HC_04_PIO_SM_TX, _CMD0, sizeof(_CMD0));
}
void HC_04_UART_READ(void *p)
{
(void)p;
//printf("HC-04 Module\n");
memset(HC04_DATA, 0, 1024);
if (0 >= HC_04_PIO_UART_RX_DATA(HC_04_PIO, HC_04_PIO_SM_RX, HC04_DATA, 270)) {
;
} else {
if (0 < strlen((char *)HC04_DATA)) {
printf("%s\n", HC04_DATA);
memset(HC04_DATA, 0, 1024);
}
}
return;
}
void HC_04(void *p)
{
(void)p;
HC_04_UART_INIT(1);
while (1) {
HC_04_UART_WRITE(NULL);
HC_04_UART_READ(NULL);
printf("\n");
vTaskDelay(pdMS_TO_TICKS(3000)); // 非阻塞延时
}
return ;
}

36
Source/HC-04.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef HC_04_H
#define HC_04_H
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/clocks.h"
#include "hardware/watchdog.h"
#include "pico/multicore.h"
#include "hardware/i2c.h"
#include "pico/binary_info.h"
#include "hardware/uart.h"
#include "hardware/pwm.h"
#include "hardware/adc.h"
#include "uart_rx.pio.h"
#include "uart_tx.pio.h"
#define HC_04_PIO pio0
#define HC_04_PIO_TX_PIN 12 // 接 HC-04 (RX) PIN (需要反着接)
#define HC_04_PIO_RX_PIN 13 // 接 HC-04 (TX) PIN
#define HC_04_PIO_SM_TX 2
#define HC_04_PIO_SM_RX 3
#define HC_04_PIO_SERIAL_BAUD 9600
extern int HC_04_UART_INIT();
extern void HC_04_UART_WRITE(void *p);
extern void HC_04_UART_READ(void *p);
extern void HC_04(void *p);
#endif

256
Source/IM1253B.c Normal file
View File

@@ -0,0 +1,256 @@
#include "IM1253B.h"
#include "common.h"
int Read_ID = 0x01;
unsigned char Tx_Buffer[8];
unsigned char Rx_Buffer[40];
unsigned char read_enable, receive_finished, receive_number;
unsigned long Voltage_data, Current_data, Power_data, Energy_data, Pf_data, CO2_data, Temperature_data, Hz_data;
int sec;
int IM1253B_INIT(void)
{
uint tx_offset = pio_add_program(IM1253B_PIO, &uart_tx_program);
uart_tx_program_init(IM1253B_PIO, IM1253B_PIO_SM_TX, tx_offset, IM1253B_PIO_TX_PIN, IM1253B_PIO_SERIAL_BAUD);
uint rx_offset = pio_add_program(IM1253B_PIO, &uart_rx_program);
uart_rx_program_init(IM1253B_PIO, IM1253B_PIO_SM_RX, rx_offset, IM1253B_PIO_RX_PIN, IM1253B_PIO_SERIAL_BAUD);
return 0;
}
int IM1253B_PIO_UART_TX_DATA(PIO pio, uint sm, uint8_t * DATA, int DATA_LEN)
{
for (int i = 0; i < DATA_LEN; i++) {
uart_tx_program_putc(pio, sm, DATA[i]);
sleep_ms(1);
}
return 0;
}
int IM1253B_PIO_UART_RX_DATA(PIO pio, uint sm, uint8_t * DATA, int DATA_LEN)
{
char c = '\0';
int received_count = 0;
int timeout_ms = 1000; // 设置较长的超时时间
while (received_count < DATA_LEN && timeout_ms > 0) {
if (uart_rx_program_available(pio, sm)) {
c = uart_rx_program_getc(pio, sm);
DATA[received_count++] = c;
//printf("0x%X ", c);
/*
// 此处不能要对于 IM1253B
if (c == '\n') {
// 接收到换行符,停止接收数据
break;
}
*/
} else {
// 没有接收到数据,继续等待
sleep_ms(2);
timeout_ms--;
}
}
if (received_count == 0) {
// 没有接收到有效数据
return -1;
}
return received_count;
}
unsigned int calccrc(unsigned char crcbuf, unsigned int crc)
{
unsigned char i;
unsigned char chk;
crc = crc ^ crcbuf;
for (i = 0; i < 8; i++) {
chk = (unsigned char)(crc & 1);
crc = crc >> 1;
crc = crc & 0x7fff;
if (chk == 1)
crc = crc ^ 0xa001;
crc = crc & 0xffff;
}
return crc;
}
unsigned int chkcrc(unsigned char *buf, unsigned char len)
{
unsigned char hi, lo;
unsigned int i;
unsigned int crc;
crc = 0xFFFF;
for (i = 0; i < len; i++) {
crc = calccrc(*buf, crc);
buf++;
}
hi = (unsigned char)(crc % 256);
lo = (unsigned char)(crc / 256);
crc = (((unsigned int)(hi)) << 8) | lo;
return crc;
}
void Print_data(void)
{
float voltage_value = (float)Voltage_data * 0.0001;
printf("电压: %.2f V\n", voltage_value);
float current_data = (float)Current_data * 0.0001;
printf("电流: %.2f A\n", current_data);
float power_data = (float)Power_data * 0.0001;
printf("功率: %.2f W\n", power_data);
float energy_data = (float)Energy_data * 0.0001;
printf("电能: %.4f KWH\n", energy_data);
float pf_data = (float)Pf_data * 0.001;
printf("功率因数: %.2f \n", pf_data);
float cO2_data = (float)CO2_data * 0.0001;
printf("二氧化碳: %.2f KG\n", cO2_data);
printf("温度: %.2f ℃\n", (float)Temperature_data * 0.01);
printf("频率: %.2f HZ\n", (float)Hz_data * 0.01);
printf("\n");
return;
}
void Analysis_data(void)
{
union crcdata {
unsigned int word16;
unsigned char byte[2];
} crcnow;
if (receive_finished == 1) // 接收完成
{
receive_finished = 0;
if (Rx_Buffer[0] == Read_ID) // 确认 ID 正确
{
crcnow.word16 = chkcrc(Rx_Buffer, receive_number - 2); // receive_number 是接收数据总长度
if ((crcnow.byte[0] == Rx_Buffer[receive_number - 1]) && (crcnow.byte[1] == Rx_Buffer[receive_number - 2])) // 确认 CRC 校验正确
{
Voltage_data = (((unsigned long)(Rx_Buffer[3])) << 24) | (((unsigned long)(Rx_Buffer[4])) << 16) | (((unsigned long)(Rx_Buffer[5])) << 8) | Rx_Buffer[6];
Current_data = (((unsigned long)(Rx_Buffer[7])) << 24) | (((unsigned long)(Rx_Buffer[8])) << 16) | (((unsigned long)(Rx_Buffer[9])) << 8) | Rx_Buffer[10];
Power_data = (((unsigned long)(Rx_Buffer[11])) << 24) | (((unsigned long)(Rx_Buffer[12])) << 16) | (((unsigned long)(Rx_Buffer[13])) << 8) | Rx_Buffer[14];
Energy_data = (((unsigned long)(Rx_Buffer[15])) << 24) | (((unsigned long)(Rx_Buffer[16])) << 16) | (((unsigned long)(Rx_Buffer[17])) << 8) | Rx_Buffer[18];
Pf_data = (((unsigned long)(Rx_Buffer[19])) << 24) | (((unsigned long)(Rx_Buffer[20])) << 16) | (((unsigned long)(Rx_Buffer[21])) << 8) | Rx_Buffer[22];
CO2_data = (((unsigned long)(Rx_Buffer[23])) << 24) | (((unsigned long)(Rx_Buffer[24])) << 16) | (((unsigned long)(Rx_Buffer[25])) << 8) | Rx_Buffer[26];
Temperature_data = (((unsigned long)(Rx_Buffer[27])) << 24) | (((unsigned long)(Rx_Buffer[28])) << 16) | (((unsigned long)(Rx_Buffer[29])) << 8) | Rx_Buffer[30];
Hz_data = (((unsigned long)(Rx_Buffer[31])) << 24) | (((unsigned long)(Rx_Buffer[32])) << 16) | (((unsigned long)(Rx_Buffer[33])) << 8) | Rx_Buffer[34];
Print_data();
}
}
}
}
// 电能清零
void Electric_energy_(int *sec)
{
uint8_t RETURN_DATA[8] = { 0 };
uint8_t ELE_ZRRO[13] = { 0x01, 0x10, 0x00, 0x4B, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0xB6, 0x2C };
// 假如从开机算起60秒后
if (*sec >= 3) {
printf("电能清零\n");
IM1253B_PIO_UART_TX_DATA(IM1253B_PIO, IM1253B_PIO_SM_TX, ELE_ZRRO, 13);
sleep_ms(100);
IM1253B_PIO_UART_RX_DATA(IM1253B_PIO, IM1253B_PIO_SM_RX, RETURN_DATA, 8);
for (int i = 0; i < 8; i++) {
printf("0x%X ", RETURN_DATA[i]);
}
sleep_ms(100);
*sec = 0;
}
return;
}
void read_data(void)
{
static int i = 0;
union crcdata {
unsigned int word16;
unsigned char byte[2];
} crcnow;
if (read_enable == 1) // 到时间抄读模块,抄读间隔 1 秒钟(或其他)
{
read_enable = 0;
Tx_Buffer[0] = Read_ID; //模块的 ID 号,默认 ID 为 0x01
Tx_Buffer[1] = 0x03;
Tx_Buffer[2] = 0x00;
Tx_Buffer[3] = 0x48;
Tx_Buffer[4] = 0x00;
Tx_Buffer[5] = 0x08;
crcnow.word16 = chkcrc(Tx_Buffer, 6);
Tx_Buffer[6] = crcnow.byte[1]; //CRC 效验低字节在前
Tx_Buffer[7] = crcnow.byte[0];
// 发送数据
IM1253B_PIO_UART_TX_DATA(IM1253B_PIO, IM1253B_PIO_SM_TX, Tx_Buffer, 8);
sleep_ms(10);
// 接收数据
uint8_t _DATA[37] = { 0 };
IM1253B_PIO_UART_RX_DATA(IM1253B_PIO, IM1253B_PIO_SM_RX, _DATA, 37);
for (i = 0; i <= 37 - 1; i++) {
//printf("0x%X ", _DATA[i]);
Rx_Buffer[i] = _DATA[i];
}
sleep_ms(10);
}
}
void IM1253B(void *p)
{
(void)p;
IM1253B_INIT();
while (1) {
printf("IM1253B\n");
/*
// 官方软件内部按钮发送的数据
// 电能清零 TX[13]:01 10 00 4B 00 02 04 00 00 00 00 B6 2C
// RX[8]:01 10 00 4B 00 02 31 DE
// 读取 TX[8]:00 03 00 01 00 04 14 18
// RX[13]:01 03 08 02 35 01 08 41 30 01 05 44 BD (直流模块)
// 设置 TX[11]:00 10 00 04 00 01 02 01 05 6B D7
// RX[8]:01 10 00 04 00 01 40 08
*/
// 发送
read_enable = 1;
read_data();
sleep_ms(10);
// 发送完成后接收数据并处理
receive_number = 37;
receive_finished = 1;
Analysis_data();
// 打印处理后的数据
//Print_data();
vTaskDelay(pdMS_TO_TICKS(3000)); // 非阻塞延时
}
return;
}

35
Source/IM1253B.h Normal file
View File

@@ -0,0 +1,35 @@
#ifndef IM1253B_H
#define IM1253B_H
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/clocks.h"
#include "hardware/watchdog.h"
#include "pico/multicore.h"
#include "hardware/i2c.h"
#include "pico/binary_info.h"
#include "hardware/uart.h"
#include "hardware/pwm.h"
#include "hardware/adc.h"
#include "uart_rx.pio.h"
#include "uart_tx.pio.h"
#define IM1253B_PIO pio0
#define IM1253B_PIO_TX_PIN 19 // 接 IM1253B (RX) PIN (需要反着接)
#define IM1253B_PIO_RX_PIN 20 // 接 IM1253B (TX) PIN
#define IM1253B_PIO_SM_TX 0
#define IM1253B_PIO_SM_RX 1
#define IM1253B_PIO_SERIAL_BAUD 4800
extern int IM1253B_INIT(void);
extern void IM1253B(void *p);
#endif

70
Source/PN532.c Normal file
View File

@@ -0,0 +1,70 @@
#include "PN532.h"
int PN532_INIT(void)
{
// 初始化UART
uart_init(UART0, BAUD_RATE);
gpio_set_function(UART0_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(UART0_RX_PIN, GPIO_FUNC_UART);
uart_set_hw_flow(UART0, false, false);
uart_set_format(UART0, DATA_BITS, STOP_BITS, PARITY);
return 0;
}
void PN532(void *p)
{
(void)p;
PN532_INIT();
while (1) {
printf("PN532 Module\n");
uint8_t PN532_DATA[270] = { 0 };
//int PN532_DATA_LEN = 0;
// 24
// 55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 03 FD D4 14 01 17 00
uint8_t _CMD0[24] = { 0X55, 0X55, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0XFF, 0X03, 0XFD, 0XD4, 0X14, 0X01, 0X17, 0X00 };
// 11
// 00 00 FF 04 FC D4 4A 02 00 E0 00
uint8_t _CMD1[11] = { 0X00, 0X00, 0XFF, 0X04, 0XFC, 0XD4, 0X4A, 0X02, 0X00, 0XE0, 0X00 };
uart_write_blocking(UART0, _CMD0, 24);
sleep_ms(100);
uart_read_blocking(UART0, PN532_DATA, 15);
/*
for (int i = 0; i < 15; i++) {
printf("0X%X ", PN532_DATA[i]);
}
printf("\r\n");
*/
memset(PN532_DATA, 0, 270);
uart_write_blocking(UART0, _CMD1, 11);
sleep_ms(100);
uart_read_blocking(UART0, PN532_DATA, 6);
/*
for (int i = 0; i < 6; i++) {
printf("0X%X ", PN532_DATA[i]);
}
printf("\r\n");
*/
memset(PN532_DATA, 0, 270);
uart_read_blocking(UART0, PN532_DATA, 19);
/*
for (int i = 0; i < 19; i++) {
printf("0X%X ", PN532_DATA[i]);
}
printf("\r\n");
*/
printf("UID: 0X%X 0X%X 0X%X 0X%X\r\n", PN532_DATA[14 - 1], PN532_DATA[15 - 1], PN532_DATA[16 - 1], PN532_DATA[17 - 1]);
printf("\n");
vTaskDelay(pdMS_TO_TICKS(3000)); // 非阻塞延时
}
return;
}

28
Source/PN532.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef PN532_H
#define PN532_H
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "uart_tx.pio.h"
#include "uart_rx.pio.h"
#define UART0 uart0
#define BAUD_RATE 115200
#define DATA_BITS 8
#define STOP_BITS 1
#define PARITY UART_PARITY_NONE
#define UART0_TX_PIN 1 // PN532 SDA (TX) PIN
#define UART0_RX_PIN 0 // PN532 SCL (RX) PIN
extern int PN532_INIT(void);
extern void PN532(void *p);
#endif

61
Source/common.c Normal file
View File

@@ -0,0 +1,61 @@
#include "common.h"
void vApplicationMallocFailedHook(void)
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */
configASSERT((volatile void *)NULL);
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName)
{
(void)pcTaskName;
(void)pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
/* Force an assert. */
configASSERT((volatile void *)NULL);
}
void vApplicationTickHook(void)
{
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{
/* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */
#if (mainENABLE_TIMER_DEMO == 1)
vTimerPeriodicISRTests();
#endif
/* Call the periodic queue overwrite from ISR demo. */
#if (mainENABLE_QUEUE_OVERWRITE == 1)
vQueueOverwritePeriodicISRDemo();
#endif
/* Call the periodic event group from ISR demo. */
#if (mainENABLE_EVENT_GROUP == 1)
vPeriodicEventGroupsProcessing();
#endif
/* Call the code that uses a mutex from an ISR. */
#if (mainENABLE_INTERRUPT_SEMAPHORE == 1)
vInterruptSemaphorePeriodicTest();
#endif
/* Call the code that 'gives' a task notification from an ISR. */
#if (mainENABLE_TASK_NOTIFY == 1)
xNotifyTaskFromISR();
#endif
}
#endif
}

16
Source/common.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef COMMOM_H
#define COMMOM_H
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "hardware/pio.h"
static inline bool uart_rx_program_available(PIO pio, uint sm)
{
return !pio_sm_is_rx_fifo_empty(pio, sm);
}
#endif

92
Source/main.c Normal file
View File

@@ -0,0 +1,92 @@
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* Standard demo includes. */
#include "TimerDemo.h"
#include "QueueOverwrite.h"
#include "EventGroupsDemo.h"
#include "IntSemTest.h"
#include "TaskNotify.h"
#include "main.h"
#include "common.h"
#include "IM1253B.h"
#include "PN532.h"
#include "EC800M_GPS.h"
#include "EC800M_4G.h"
#include "HC-04.h"
void Led_Blinky(void *pvParameters)
{
(void)pvParameters;
const uint LED_PIN = PICO_DEFAULT_LED_PIN;
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (1) {
vTaskDelay(pdMS_TO_TICKS(500));
gpio_put(LED_PIN, 1);
vTaskDelay(pdMS_TO_TICKS(500));
gpio_put(LED_PIN, 0);
}
}
void Read_Onboard_Temperature(void *pvParameters)
{
(void)pvParameters;
adc_init();
adc_set_temp_sensor_enabled(true);
adc_select_input(4); // Input 4 is the onboard temperature sensor.
while (1) {
const float conversionFactor = 3.3f / (1 << 12);
float adc = (float)adc_read() * conversionFactor;
float tempC = 27.0f - (adc - 0.706f) / 0.001721f;
printf("Onboard temperature %.02f°C %.02f°F\n", tempC, (tempC * 9 / 5 + 32));
vTaskDelay(pdMS_TO_TICKS(3000)); // 非阻塞延时
}
}
int main(void)
{
stdio_init_all();
sleep_ms(1000);
//set_sys_clock_khz(250000, true);
BaseType_t xReturned;
TaskHandle_t Led_Blinky_xHandle = NULL;
TaskHandle_t Read_Onboard_Temperature_xHandle = NULL;
TaskHandle_t IM1253B_xHandle = NULL;
TaskHandle_t EC800M_4G_xHandle = NULL;
TaskHandle_t PN532_xHandle = NULL;
TaskHandle_t HC_04_xHandle = NULL;
// 板载LED闪烁
xReturned = xTaskCreate(Led_Blinky, "Blinky task", 512, NULL, tskIDLE_PRIORITY, &Led_Blinky_xHandle);
// CPU温度
xReturned = xTaskCreate(Read_Onboard_Temperature, "Temperature task", 512, NULL, tskIDLE_PRIORITY, &Read_Onboard_Temperature_xHandle);
// IM1253B 电压、功率模块
xReturned = xTaskCreate(IM1253B, "IM1253B task", 1024, NULL, tskIDLE_PRIORITY, &IM1253B_xHandle);
// EC800M 4G 模块
xReturned = xTaskCreate(EC800M_4G, "EC800M 4G task", 1024, NULL, tskIDLE_PRIORITY, &EC800M_4G_xHandle);
// PN532 NFC 模块
xReturned = xTaskCreate(PN532, "PN532 task", 512, NULL, tskIDLE_PRIORITY, &PN532_xHandle);
// HC-04 蓝牙模块
xReturned = xTaskCreate(HC_04, "HC_04 task", 512, NULL, tskIDLE_PRIORITY, &HC_04_xHandle);
vTaskStartScheduler();
return 0;
}

17
Source/main.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef MAIN_H
#define MAIN_H
#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/clocks.h"
#include "hardware/watchdog.h"
#include "pico/multicore.h"
#include "hardware/i2c.h"
#include "pico/binary_info.h"
#include "hardware/uart.h"
#include "hardware/pwm.h"
#include "hardware/adc.h"
#endif

94
Source/uart_rx.pio Normal file
View File

@@ -0,0 +1,94 @@
;
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
;
; SPDX-License-Identifier: BSD-3-Clause
;
.program uart_rx_mini
; Minimum viable 8n1 UART receiver. Wait for the start bit, then sample 8 bits
; with the correct timing.
; IN pin 0 is mapped to the GPIO used as UART RX.
; Autopush must be enabled, with a threshold of 8.
wait 0 pin 0 ; Wait for start bit
set x, 7 [10] ; Preload bit counter, delay until eye of first data bit
bitloop: ; Loop 8 times
in pins, 1 ; Sample data
jmp x-- bitloop [6] ; Each iteration is 8 cycles
% c-sdk {
#include "hardware/clocks.h"
#include "hardware/gpio.h"
static inline void uart_rx_mini_program_init(PIO pio, uint sm, uint offset, uint pin, uint baud) {
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, false);
pio_gpio_init(pio, pin);
gpio_pull_up(pin);
pio_sm_config c = uart_rx_mini_program_get_default_config(offset);
sm_config_set_in_pins(&c, pin); // for WAIT, IN
// Shift to right, autopush enabled
sm_config_set_in_shift(&c, true, true, 8);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
// SM transmits 1 bit per 8 execution cycles.
float div = (float)clock_get_hz(clk_sys) / (8 * baud);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
%}
.program uart_rx
; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and
; break conditions more gracefully.
; IN pin 0 and JMP pin are both mapped to the GPIO used as UART RX.
start:
wait 0 pin 0 ; Stall until start bit is asserted
set x, 7 [10] ; Preload bit counter, then delay until halfway through
bitloop: ; the first data bit (12 cycles incl wait, set).
in pins, 1 ; Shift data bit into ISR
jmp x-- bitloop [6] ; Loop 8 times, each loop iteration is 8 cycles
jmp pin good_stop ; Check stop bit (should be high)
irq 4 rel ; Either a framing error or a break. Set a sticky flag,
wait 1 pin 0 ; and wait for line to return to idle state.
jmp start ; Don't push data if we didn't see good framing.
good_stop: ; No delay before returning to start; a little slack is
push ; important in case the TX clock is slightly too fast.
% c-sdk {
static inline void uart_rx_program_init(PIO pio, uint sm, uint offset, uint pin, uint baud) {
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, false);
pio_gpio_init(pio, pin);
gpio_pull_up(pin);
pio_sm_config c = uart_rx_program_get_default_config(offset);
sm_config_set_in_pins(&c, pin); // for WAIT, IN
sm_config_set_jmp_pin(&c, pin); // for JMP
// Shift to right, autopush disabled
sm_config_set_in_shift(&c, true, false, 32);
// Deeper FIFO as we're not doing any TX
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
// SM transmits 1 bit per 8 execution cycles.
float div = (float)clock_get_hz(clk_sys) / (8 * baud);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
static inline char uart_rx_program_getc(PIO pio, uint sm) {
// 8-bit read from the uppermost byte of the FIFO, as data is left-justified
io_rw_8 *rxfifo_shift = (io_rw_8*)&pio->rxf[sm] + 3;
while (pio_sm_is_rx_fifo_empty(pio, sm))
tight_loop_contents();
return (char)*rxfifo_shift;
}
%}

61
Source/uart_tx.pio Normal file
View File

@@ -0,0 +1,61 @@
;
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
;
; SPDX-License-Identifier: BSD-3-Clause
;
.program uart_tx
.side_set 1 opt
; An 8n1 UART transmit program.
; OUT pin 0 and side-set pin 0 are both mapped to UART TX pin.
pull side 1 [7] ; Assert stop bit, or stall with line in idle state
set x, 7 side 0 [7] ; Preload bit counter, assert start bit for 8 clocks
bitloop: ; This loop will run 8 times (8n1 UART)
out pins, 1 ; Shift 1 bit from OSR to the first OUT pin
jmp x-- bitloop [6] ; Each loop iteration is 8 cycles.
% c-sdk {
#include "hardware/clocks.h"
static inline void uart_tx_program_init(PIO pio, uint sm, uint offset, uint pin_tx, uint baud) {
// Tell PIO to initially drive output-high on the selected pin, then map PIO
// onto that pin with the IO muxes.
pio_sm_set_pins_with_mask(pio, sm, 1u << pin_tx, 1u << pin_tx);
pio_sm_set_pindirs_with_mask(pio, sm, 1u << pin_tx, 1u << pin_tx);
pio_gpio_init(pio, pin_tx);
pio_sm_config c = uart_tx_program_get_default_config(offset);
// OUT shifts to right, no autopull
sm_config_set_out_shift(&c, true, false, 32);
// We are mapping both OUT and side-set to the same pin, because sometimes
// we need to assert user data onto the pin (with OUT) and sometimes
// assert constant values (start/stop bit)
sm_config_set_out_pins(&c, pin_tx, 1);
sm_config_set_sideset_pins(&c, pin_tx);
// We only need TX, so get an 8-deep FIFO!
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
// SM transmits 1 bit per 8 execution cycles.
float div = (float)clock_get_hz(clk_sys) / (8 * baud);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
static inline void uart_tx_program_putc(PIO pio, uint sm, char c) {
pio_sm_put_blocking(pio, sm, (uint32_t)c);
}
static inline void uart_tx_program_puts(PIO pio, uint sm, const char *s) {
while (*s)
uart_tx_program_putc(pio, sm, *s++);
}
%}