活动介绍

OneNet_SendData

时间: 2025-07-29 20:37:09 浏览: 1
<think>好的,我现在需要解决用户提到的OneNet_SendData函数中参数类型不兼容的问题,具体错误是char*与int16不匹配,错误号为#167。用户提供了之前的回答和一些引用内容,包括ONEnet.h的头文件定义和一段Lua脚本代码。 首先,我需要回顾用户提供的引用内容。在引用1中,ONEnet.h里声明的函数如OneNet_Publish使用的是const char*作为参数,没有提到OneNet_SendData函数。这可能意味着用户提到的OneNet_SendData可能不是标准API的一部分,或者是用户自定义的函数。引用2中的Lua脚本涉及设备连接,但使用的是MQTT协议,可能与C代码中的问题关联不大,但设备ID等信息可能相关。 用户之前的问题是关于onenet.c中的参数类型错误,现在又提到了OneNet_SendData的类似问题。根据之前的回答,错误通常源于函数声明与实际调用时的参数类型不匹配。需要确定OneNet_SendData的函数原型是否正确定义,比如是否将某个参数错误地声明为int16,而实际传递的是char*。 接下来,我应该检查ONEnet.h中是否有OneNet_SendData的声明。根据引用1,头文件中没有这个函数,可能用户自定义了这个函数,或者可能使用了不同版本的SDK。如果是自定义函数,用户需要确保函数声明中的参数类型与实际调用一致。例如,如果函数期望的是int16类型的设备ID,但调用时传递的是char*字符串,就会导致类型不匹配。 此外,用户之前的回答提到了显式类型转换、检查SDK版本以及使用安全转换函数如strtol。这些方法可能同样适用于当前问题。需要建议用户检查OneNet_SendData的声明和调用,确保参数类型匹配,必要时进行类型转换,并确认设备ID的数值是否在int16的范围内。 还可能涉及设备ID的表示方式。例如,在Lua脚本中,设备ID是字符串,但在C函数中可能需要转换为整数。如果SDK更新后改变了参数类型,用户需要调整代码以适应新的类型。 总结可能的解决步骤:1. 检查OneNet_SendData的函数原型,确认参数类型;2. 比较调用时传递的参数类型是否匹配;3. 进行必要的类型转换;4. 验证设备ID的数值范围;5. 查看SDK文档或更新日志,确认是否有变更。 需要注意用户可能在移植代码或使用不同版本的SDK时出现了类型不兼容的问题,特别是设备ID从字符串改为整型或反之。应建议用户查阅最新的SDK文档,确保函数签名正确,并调整调用方式。</think>### 针对`OneNet_SendData`参数类型不兼容错误(char*与int16)的解决方案 --- #### 一、核心问题分析 根据错误信息`error #167: argument of type "char *" is incompatible with parameter of type "int16"`,**根本原因是函数`OneNet_SendData`的参数类型声明与调用时传递的实际类型不匹配**。结合引用[1]中的`ONEnet.h`头文件定义,推测问题可能源于以下场景: 1. **函数原型未正确定义**:`OneNet_SendData`在头文件中声明为接收`int16`参数,但实际调用时传递了`char*` 2. **设备标识符格式冲突**:ONENet新版接口可能要求设备ID为字符串类型(如引用[2]中Lua代码的`DeviceId = "123456789"`),但代码中仍使用旧版数值类型标识 3. **隐式类型转换失败**:未正确处理字符串到整型的转换(如`"123456"`转换为`int16`可能溢出) --- #### 二、分步解决方案 ##### 1. 验证函数原型声明 检查`ONEnet.h`中`OneNet_SendData`的函数声明: ```c // 错误声明示例(假设存在不匹配声明) int OneNet_SendData(int16 dev_id, char* data); // 正确声明应匹配ONENet当前规范(参考引用[1]中Publish函数) int OneNet_SendData(const char* dev_id, const char* data); // 设备ID应为字符串类型 ``` ##### 2. 修正调用代码 **若函数原型应为字符串类型**(与引用[2]的Lua脚本一致): ```c // 错误调用示例 int16_t device_id = 167; OneNet_SendData(device_id, "sensor_data"); // 传递int16导致类型错误 // 正确调用方式(直接使用字符串ID) const char* device_id = "167"; // 与Lua脚本中DeviceId格式一致 OneNet_SendData(device_id, "temperature=25.6"); ``` ##### 3. 类型强制转换(仅限必要场景) **若必须使用int16类型参数**(如兼容旧版SDK): ```c #include <stdint.h> #include <stdlib.h> char* str_id = "167"; int16_t num_id = (int16_t)strtol(str_id, NULL, 10); // 安全转换 // 添加数值范围校验 if(num_id < INT16_MIN || num_id > INT16_MAX) { fprintf(stderr, "Device ID超出int16范围: %s", str_id); return; } OneNet_SendData(num_id, "humidity=60%"); // 确保函数原型接受int16 ``` ##### 4. SDK版本适配 对比SDK更新日志,确认接口变更: - **旧版SDK**:可能使用`int16`作为设备标识符(如物联网卡编号) - **新版SDK**:通常改用字符串ID(如引用[2]中`DeviceId`的字符串格式) --- #### 三、配置验证示例 ```c // 修正后的安全调用流程 void send_to_onenet() { const char* device_id = "MQ9-167"; // 字符串类型ID(符合新版规范) const char* payload = "{\"CO\": 50}"; // 直接调用字符串接口 OneNet_SendData(device_id, payload); /* 若必须使用数值ID的特殊场景 */ // int16_t id = 167; // OneNet_SendData(itoa(id), payload); // 需要实现itoa() } ``` --- #### 四、深度调试建议 1. **头文件交叉验证**: ```c // 在onenet.c中添加类型检查 #ifdef DEBUG _Static_assert(sizeof(int16_t) == 2, "int16类型长度异常!"); #endif ``` 2. **编译器增强检查**: ```bash gcc -Wall -Wconversion -Wstrict-prototypes -DDEBUG onenet.c -o onenet ``` 3. **单元测试用例**: ```c void test_type_compatibility() { // 应触发编译错误的测试 // OneNet_SendData("167", 25); // 测试第二个参数类型 } ``` --- ### 相关问题 1. 如何判断ONENet接口参数应使用字符串还是数值类型? 2. C语言中字符串与整型转换时如何避免缓冲区溢出? 3. 物联网设备标识符设计有哪些最佳实践?
阅读全文

相关推荐

#include "stm32f10x.h" #include "onenet.h" #include "esp8266.h" #include "sys.h" #include "delay.h" #include "usart.h" #include "dht11.h" #include "oled.h" #include <string.h> #define ESP8266_ONENET_INFO "AT+CIPSTART=\"TCP\",\"mqtts.heclouds.com\",1883\r\n" u8 temperature=0,humidity=0; int main(void) { unsigned short timeCount = 0; //发送间隔变量 unsigned char *dataPtr = NULL; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断控制器分组设置 Delay_Init(); //systick初始化 Usart1_Init(115200); //串口1,打印信息用 Usart2_Init(115200); //串口2,驱动ESP8266用 OLED_Init(); UsartPrintf(USART_DEBUG, " Hardware init OK\r\n"); while(DHT11_Init()) { delay_ms(200); } OLED_ShowString(20,24,"Networking",16,1); ESP8266_Init(); //初始化ESP8266 OLED_ShowString(0,24," ",16,1); OLED_ShowString(0,24," Connected to",16,1); OLED_ShowString(30,48,"ONENET",16,1); UsartPrintf(USART_DEBUG, "Connect MQTTs Server...\r\n"); while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT")) delay_ms(500); UsartPrintf(USART_DEBUG, "NET_OK\r\n"); while(OneNet_DevLink()) //接入OneNET delay_ms(500); OLED_Clear(); OLED_ShowChinese(0,0,0,16,1); //温 OLED_ShowChinese(18,0,1,16,1); //湿 OLED_ShowChinese(36,0,2,16,1); //度 OLED_ShowChinese(54,0,3,16,1); //检 OLED_ShowChinese(72,0,4,16,1); //测 OLED_ShowChinese(90,0,5,16,1); //装 OLED_ShowChinese(108,0,6,16,1);//置 OLED_ShowChinese(0,24,0,16,1); //温 OLED_ShowChinese(18,24,2,16,1); //度 OLED_ShowChinese(0,48,1,16,1); //湿 OLED_ShowChinese(18,48,2,16,1); //度 OLED_ShowString(80,24 ," C",16,1); OLED_ShowString(80,48 ," %",16,1); OLED_Refresh(); OneNET_Subscribe(); while(1) { if(++timeCount >= 50) //发送间隔0.5s { DHT11_Read_Data(&temperature,&humidity); //读取温湿度值 OLED_ShowNum(60,24,temperature,2,16,1);//显示温度 OLED_ShowNum(60,48,humidity,2,16,1);//显示湿度 UsartPrintf(USART_DEBUG,"TEMP:%d HUMI:%d\r\n",temperature,humidity); UsartPrintf(USART_DEBUG, "OneNet_SendData\r\n"); OneNet_SendData(); //发送数据 timeCount = 0; ESP8266_Clear(); } dataPtr = ESP8266_GetIPD(0); if(dataPtr != NULL) OneNet_RevPro(dataPtr); delay_ms(10); } }是否有问题

#include "esp8266.h" #include "main.h" // 添加此头文件以解决DebugPrint声明问题 #include <string.h> #include <stdio.h> // 全局变量定义 uint8_t wifiConnected = 0; uint8_t oneNetConnected = 0; uint8_t remote_led_command = 0; uint8_t remote_motor_command = 0; uint8_t new_remote_command = 0; uint32_t uploadSuccessCount = 0; uint32_t uploadFailCount = 0; // 使用串口3 (PB10, PB11) extern UART_HandleTypeDef huart3; // 私有函数声明 static void ESP8266_Transmit(const char *data); static void ESP8266_Flush(void); static uint8_t ESP8266_WaitResponse(const char *expected, uint32_t timeout); // 使用您提供的参数 const char* ONENET_HOST = "mqtts.heclouds.com"; const int ONENET_PORT = 1883; const char* ONENET_CLIENT_ID = "jiaju"; const char* ONENET_USERNAME = "3n8QY47l17"; const char* ONENET_PASSWORD = "version=2018-10-31&res=products%2F3n8QY47l17%2Fdevices%2Fjiaju&et=2052972807&method=md5&sign=s1lLnOPwHXQNilx%2FJrdi6g%3D%3D"; const char* ONENET_TOPIC_PUB = "$sys/3n8QY47l17/jiaju/thing/property/post"; const char* ONENET_TOPIC_CMD = "$sys/3n8QY47l17/jiaju/cmd/request/#"; // 修改后的命令主题 void ESP8266_Init(void) { // 确保串口已初始化 HAL_Delay(500); // 清空串口缓冲区 ESP8266_Flush(); // 发送复位命令 ESP8266_SendCommand("AT+RST\r\n", "ready", 3000); HAL_Delay(2000); // 设置WiFi模式为STA ESP8266_SendCommand("AT+CWMODE=1\r\n", "OK", 1000); // 关闭回显 ESP8266_SendCommand("ATE0\r\n", "OK", 500); // 启用MQTT透传模式 ESP8266_SendCommand("AT+MQTTCONNCFG=0,120,1,\"\"\r\n", "OK", 1000); // 设置MQTT协议版本为3.1.1 ESP8266_SendCommand("AT+MQTTUSERCFG=0,4,\"\",\"\",\"\",0,0,\"\"\r\n", "OK", 1000); } void ESP8266_ConnectWiFi(const char* ssid, const char* password) { char cmd[128]; sprintf(cmd, "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, password); if(ESP8266_SendCommand(cmd, "OK", 15000)) { wifiConnected = 1; } else { wifiConnected = 0; } } void ESP8266_ConnectOneNet(void) { char cmd[256]; sprintf(cmd, "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n", ONENET_CLIENT_ID, ONENET_USERNAME, ONENET_PASSWORD); if(!ESP8266_SendCommand(cmd, "OK", 2000)) { return; } sprintf(cmd, "AT+MQTTCONN=0,\"%s\",%d,1\r\n", ONENET_HOST, ONENET_PORT); if(ESP8266_SendCommand(cmd, "+MQTTCONNECTED", 10000)) { oneNetConnected = 1; // 订阅新的命令主题(带#通配符) sprintf(cmd, "AT+MQTTSUB=0,\"%s\",1\r\n", ONENET_TOPIC_CMD); ESP8266_SendCommand(cmd, "OK", 2000); } else { oneNetConnected = 0; } } void ESP8266_SendData(float temp, float humi, uint8_t led_status, uint8_t motor_status) { static uint32_t request_id = 1; char cmd[200]; char value_str[20]; // 1. 发送温度 snprintf(value_str, sizeof(value_str), "%.1f", temp); sprintf(cmd, "AT+MQTTPUB=0,\"%s\"," "\"{\\\"id\\\":\\\"%lu\\\"\\,\\\"params\\\":" "{\\\"temperature\\\":{\\\"value\\\":%s}}}\"," "1,0\r\n", ONENET_TOPIC_PUB, request_id++, value_str); ESP8266_SendCommand(cmd, "OK", 2000); // 2. 发送湿度 snprintf(value_str, sizeof(value_str), "%.1f", humi); sprintf(cmd, "AT+MQTTPUB=0,\"%s\"," "\"{\\\"id\\\":\\\"%lu\\\"\\,\\\"params\\\":" "{\\\"humidity\\\":{\\\"value\\\":%s}}}\"," "1,0\r\n", ONENET_TOPIC_PUB, request_id++, value_str); ESP8266_SendCommand(cmd, "OK", 2000); // 3. 发送LED状态 const char* led_value = led_status ? "true" : "false"; sprintf(cmd, "AT+MQTTPUB=0,\"%s\"," "\"{\\\"id\\\":\\\"%lu\\\"\\,\\\"params\\\":" "{\\\"led\\\":{\\\"value\\\":%s}}}\"," "1,0\r\n", ONENET_TOPIC_PUB, request_id++, led_value); ESP8266_SendCommand(cmd, "OK", 2000); // 4. 发送电机状态 sprintf(cmd, "AT+MQTTPUB=0,\"%s\"," "\"{\\\"id\\\":\\\"%lu\\\"\\,\\\"params\\\":" "{\\\"motor\\\":{\\\"value\\\":%d}}}\"," "1,0\r\n", ONENET_TOPIC_PUB, request_id++, motor_status); ESP8266_SendCommand(cmd, "OK", 2000); // 更新上传统计 uploadSuccessCount += 4; } uint8_t ESP8266_SendCommand(const char *cmd, const char *expected, uint32_t timeout) { ESP8266_Transmit(cmd); uint8_t result = ESP8266_WaitResponse(expected, timeout); // 增强错误处理 - 记录错误响应 if (!result) { // 使用串口直接输出错误信息(因为DebugPrint可能不可用) char errorMsg[128]; snprintf(errorMsg, sizeof(errorMsg), "CMD Error: %s\r\n", cmd); HAL_UART_Transmit(&huart3, (uint8_t *)errorMsg, strlen(errorMsg), HAL_MAX_DELAY); } return result; } static void ESP8266_Transmit(const char *data) { HAL_UART_Transmit(&huart3, (uint8_t *)data, strlen(data), HAL_MAX_DELAY); } static void ESP8266_Flush(void) { uint8_t dummy; while (HAL_UART_Receive(&huart3, &dummy, 1, 10) == HAL_OK) {} } static uint8_t ESP8266_WaitResponse(const char *expected, uint32_t timeout) { char response[256] = {0}; uint32_t start = HAL_GetTick(); uint8_t index = 0; uint8_t found = 0; while ((HAL_GetTick() - start) < timeout) { if (HAL_UART_Receive(&huart3, (uint8_t *)&response[index], 1, 10) == HAL_OK) { if (strstr(response, expected) != NULL) { found = 1; break; } if (strstr(response, "ERROR") != NULL || strstr(response, "FAIL") != NULL) { break; } if (index < sizeof(response) - 1) { index++; } else { memmove(response, response + 128, 128); index = 128; } } } return found; } void ESP8266_SendPing(void) { ESP8266_SendCommand("AT+MQTTPING=0\r\n", "OK", 1000); } void ESP8266_ProcessResponses(void) { static char response[512] = {0}; static uint8_t index = 0; uint8_t received; if (HAL_UART_Receive(&huart3, (uint8_t *)&received, 1, 0) == HAL_OK) { if (index < sizeof(response) - 1) { response[index++] = received; response[index] = '\0'; if (index >= 2 && response[index-2] == '\r' && response[index-1] == '\n') { response[index-2] = '\0'; // 检查连接状态消息 if (strstr(response, "WIFI GOT IP")) { wifiConnected = 1; } if (strstr(response, "+MQTTCONNECTED")) { oneNetConnected = 1; } if (strstr(response, "+MQTTDISCONNECTED")) { oneNetConnected = 0; } // 处理订阅的消息(使用新的命令主题) if (strstr(response, "+MQTTSUBRECV:") && strstr(response, "cmd/request")) { // 解析远程命令 ParseRemoteCommand(response); } index = 0; response[0] = '\0'; } } else { index = 0; response[0] = '\0'; } } } void ParseRemoteCommand(const char *message) { // 重置命令状态 remote_led_command = 0; remote_motor_command = 0; // 定义本地变量用于解析(修复未定义错误) char* led_ptr = NULL; char* motor_ptr = NULL; char received_command = 0; // 查找JSON消息体 char* msg_body = strstr(message, "\"body\":"); if (!msg_body) { // 尝试旧格式处理 led_ptr = strstr(message, "\"led\":"); if (led_ptr) { remote_led_command = (strstr(led_ptr, "true") || strstr(led_ptr, "1")) ? 1 : 0; } motor_ptr = strstr(message, "\"motor\":"); if (motor_ptr) { if (strstr(motor_ptr, "1")) { remote_motor_command = 1; } else if (strstr(motor_ptr, "2")) { remote_motor_command = 2; } } } else { // 新版JSON格式处理(带"body"结构) led_ptr = strstr(msg_body, "\"led\":"); if (led_ptr) { // 向前移动到值位置 char* value_start = strchr(led_ptr, ':') + 1; // 跳过空格 while (*value_start == ' ') value_start++; if (strncmp(value_start, "true", 4) == 0 || *value_start == '1') { remote_led_command = 1; } else if (strncmp(value_start, "false", 5) == 0 || *value_start == '0') { remote_led_command = 0; } } motor_ptr = strstr(msg_body, "\"motor\":"); if (motor_ptr) { // 向前移动到值位置 char* value_start = strchr(motor_ptr, ':') + 1; // 跳过空格 while (*value_start == ' ') value_start++; if (*value_start == '1') { remote_motor_command = 1; } else if (*value_start == '2') { remote_motor_command = 2; } else if (*value_start == '0') { remote_motor_command = 0; } } } // 检查是否接收到有效命令 if (led_ptr || motor_ptr) { new_remote_command = 1; received_command = 1; // 通过串口输出命令内容(因为DebugPrint可能不可用) char cmd_info[80]; snprintf(cmd_info, sizeof(cmd_info), "Received CMD: led=%d, motor=%d\r\n", remote_led_command, remote_motor_command); HAL_UART_Transmit(&huart3, (uint8_t *)cmd_info, strlen(cmd_info), HAL_MAX_DELAY); } // 检查平台属性设置响应 if (strstr(message, "SetProperty")) { // 通过串口输出属性设置响应 char response_msg[60]; snprintf(response_msg, sizeof(response_msg), "Property set: %s\r\n", strstr(message, "success") ? "Success" : "Failure"); HAL_UART_Transmit(&huart3, (uint8_t *)response_msg, strlen(response_msg), HAL_MAX_DELAY); } } 这是我现在的代码,还是报错1022,请检查哪里有错误

// 单片机头文件 #include "stm32f10x.h" // 网络设备驱动 #include "esp8266.h" // 硬件驱动 #include "delay.h" #include "usart.h" // C库 #include <string.h> #include <stdio.h> // #define ESP8266_WIFI_INFO "AT+CWJAP=\"ChinaNet-y3ir\",\"12345678\"\r\n" #define ESP8266_WIFI_INFO "AT+CWJAP=\"hhh\",\"12345678\"\r\n" #define ESP8266_ONENET_INFO "AT+CIPSTART=\"TCP\",\"183.230.40.39\",6002\r\n" unsigned char esp8266_buf[256]; unsigned short esp8266_cnt = 0, esp8266_cntPre = 0; void ESP8266_Clear(void) { memset(esp8266_buf, 0, sizeof(esp8266_buf)); esp8266_cnt = 0; } _Bool ESP8266_WaitRecive(void) { if (esp8266_cnt == 0) // 如果接收计数为0 则说明没有处于接收数据中,所以直接跳出,结束函数 return REV_WAIT; if (esp8266_cnt == esp8266_cntPre) // 如果上一次的值和这次相同,则说明接收完毕 { esp8266_cnt = 0; // 清0接收计数 return REV_OK; // 返回接收完成标志 } esp8266_cntPre = esp8266_cnt; // 置为相同 return REV_WAIT; // 返回接收未完成标志 } _Bool ESP8266_SendCmd(char *cmd, char *res, u16 time) { Usart3_SendString((unsigned char *)cmd, strlen((const char *)cmd)); while (time--) { if (ESP8266_WaitRecive() == REV_OK) // 如果收到数据 { if (strstr((const char *)esp8266_buf, res) != NULL) // 如果检索到关键词 { ESP8266_Clear(); // 清空缓存 return 0; } } delay_ms(10); } return 1; } void ESP8266_SendData(unsigned char *data, unsigned short len) { char cmdBuf[32]; ESP8266_Clear(); // 清空接收缓存 sprintf(cmdBuf, "AT+CIPSEND=%d\r\n", len); // 发送命令 if (!ESP8266_SendCmd(cmdBuf, ">", 200)) // 收到‘>’时可以发送数据 { Usart3_SendString(data, len); // 发送设备连接请求数据 } } unsigned char *ESP8266_GetIPD(unsigned short timeOut) { char *ptrIPD = NULL; do { if (ESP8266_WaitRecive() == REV_OK) // 如果接收完成 { ptrIPD = strstr((char *)esp8266_buf, "IPD,"); // 搜索“IPD”头 if (ptrIPD == NULL) // 如果没找到,可能是IPD头的延迟,还是需要等待一会,但不会超过设定的时间 { // printf("\"IPD\" not found\r\n"); } else { ptrIPD = strchr(ptrIPD, ':'); // 找到':' if (ptrIPD != NULL) { ptrIPD++; return (unsigned char *)(ptrIPD); } else return NULL; } } delay_ms(5); // 延时等待 } while (timeOut--); return NULL; // 超时还未找到,返回空指针 } void ESP8266_Init(void) { char str[125]; ESP8266_Clear(); printf("AT\r\n"); while (ESP8266_SendCmd("AT\r\n\r", "OK", 200)) delay_ms(300); printf("CWMODE\r\n"); while (ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK", 200)) delay_ms(300); printf("AT+CWDHCP\r\n"); while (ESP8266_SendCmd("AT+CWDHCP=1,1\r\n", "OK", 200)) delay_ms(300); printf("CWJAP\r\n"); memset(str, 0, sizeof(str)); sprintf(str, "AT+CWJAP=\"%s\",\"%s\"\r\n", SSID, PASS); while (ESP8266_SendCmd(str, "GOT IP", 200)) delay_ms(300); printf("CIPSTART\r\n"); memset(str, 0, sizeof(str)); sprintf(str, "AT+CIPSTART=\"TCP\",\"%s\",%d\r\n", ServerIP, ServerPort); while (ESP8266_SendCmd(str, "CONNECT", 200)) delay_ms(500); printf("ESP8266 Init OK\r\n"); // Sys_Restart();//软件复位 }解释代码

#include "stm32f10x.h" #include "Delay.h" #include "usart.h" #include <string.h> #include <stdio.h> #define REV_OK 0 //½ÓÊÕÍê³É±êÖ¾ #define REV_WAIT 1 //½ÓÊÕδÍê³É±êÖ¾ #define ESP8266_WIFI_INFO "AT+CWJAP=\"V30Pro\",\"lxz132530\"\r\n" //#define ESP8266_ONENET_INFO "AT+CIPSTART=\"TCP\",\"183.230.40.39\",6002\r\n" //¾É°æOneNETµØÖ· #define ESP8266_ONENET_INFO "AT+CIPSTART=\"TCP\",\"mqtts.heclouds.com\",1883\r\n" //аæOneNETµØÖ· //#define ESP8266_ONENET_INFO "AT+CIPSTART=\"TCP\",\"192.168.11.125\",8080\r\n" //µ÷ÊÔµØÖ· unsigned char esp8266_buf[128]; unsigned short esp8266_cnt = 0, esp8266_cntPre = 0; //========================================================== // º¯ÊýÃû³Æ£º ESP8266_Clear // // º¯Êý¹¦ÄÜ£º Çå¿Õ»º´æ // // Èë¿Ú²ÎÊý£º ÎÞ // // ·µ»Ø²ÎÊý£º ÎÞ // // ˵Ã÷£º //========================================================== void ESP8266_Clear(void) { memset(esp8266_buf, 0, sizeof(esp8266_buf)); esp8266_cnt = 0; } //========================================================== // º¯ÊýÃû³Æ£º ESP8266_WaitRecive // // º¯Êý¹¦ÄÜ£º µÈ´ý½ÓÊÕÍê³É // // Èë¿Ú²ÎÊý£º ÎÞ // // ·µ»Ø²ÎÊý£º REV_OK-½ÓÊÕÍê³É REV_WAIT-½ÓÊÕ³¬Ê±Î´Íê³É // // ˵Ã÷£º Ñ­»·µ÷Óüì²âÊÇ·ñ½ÓÊÕÍê³É //========================================================== _Bool ESP8266_WaitRecive(void) { if(esp8266_cnt == 0) //Èç¹û½ÓÊÕ¼ÆÊýΪ0 Ôò˵Ã÷ûÓд¦ÓÚ½ÓÊÕÊý¾ÝÖУ¬ËùÒÔÖ±½ÓÌø³ö£¬½áÊøº¯Êý return REV_WAIT; if(esp8266_cnt == esp8266_cntPre) //Èç¹ûÉÏÒ»´ÎµÄÖµºÍÕâ´ÎÏàͬ£¬Ôò˵Ã÷½ÓÊÕÍê±Ï { esp8266_cnt = 0; //Çå0½ÓÊÕ¼ÆÊý return REV_OK; //·µ»Ø½ÓÊÕÍê³É±êÖ¾ } esp8266_cntPre = esp8266_cnt; //ÖÃΪÏàͬ return REV_WAIT; //·µ»Ø½ÓÊÕδÍê³É±êÖ¾ } //========================================================== // º¯ÊýÃû³Æ£º ESP8266_SendCmd // // º¯Êý¹¦ÄÜ£º ·¢ËÍÃüÁî // // Èë¿Ú²ÎÊý£º cmd£ºÃüÁî // res£ºÐèÒª¼ì²éµÄ·µ»ØÖ¸Áî // // ·µ»Ø²ÎÊý£º 0-³É¹¦ 1-ʧ°Ü // // ˵Ã÷£º //========================================================== _Bool ESP8266_SendCmd(char *cmd, char *re

/************************************************************************ * 文件名称: LTE_DTU.c * 功能名称: DTU模块驱动 * 实验平台: 物联开发板STM32F103RBT6 * OneNET 多协议平台 MQTT: MQTT服务器IP: mqtt.heclouds.com MQTT服务器端口:6002 主题topic:IOT_LBW、IOT_TOPIC 产品ID:220520 设备ID:657554468 设备密钥:LBWIOT 用到的MQTT指令: 1. @config@[email protected],6002,657554468,60### --设置mqtt服务器IP和端口号,以及设备ID号和心跳保活时间 2. @config@user@220520,LBWIOT,0### ---设置MQTT账户名和密码 3. @config@remain@1,2018-10-31### -----设置会话 4. @config@will@0,0,0,0,0### ---设置无遗嘱模式 5. @config@sub@IOT_LBW,0### -----订阅主题 @config@sub@IOT_TOPIC,0### -----订阅主题 6. @config@pub@IOT_LBW,0,0,0### ---发布主题 @config@pub@IOT_TOPIC,0,0,0### ---发布主题 7. @config@para@save### ----保存参数 8. @get@platform connect state@ --查询登录平台状态 **************************************************************************/ #include "LTE_DTU.h" #include <stdio.h> #include "string.h" #include "USART1.h" #include "USART2.h" #include "DelayTime.h" /*变量声明*/ u8 TCP_Connectflag=0;//TCP连接标志,1 成功,0 失败 u8 Congfig_flag=0; //配置服务器参数标志 1 成功,0 失败 u8 DTU_Readyflag;//DTU运行状态标志;1 正常,0 异常 u8 Login_OneNET_flag=0; //登录OneNET平台标志(TCP模式),1 成功,0 失败 u8 Loginflag=0; //登录OneNET平台标志(mqtt模式),1 成功,0 失败 extern char Usart2_RX_Buf[]; //串口2缓存 extern u8 Usart2_RX_Data_Len; //串口2缓存首地址 extern char Usart2_TX_Buf[Usart2_TX_MAXLEN]; /* OneNET平台登陆报文格式示例:*产品ID号#鉴权信息#cupluas* (本次实验例程的鉴权信息使用模块IMEI号) 例如:*394915#868777055277606#cupluas* */ char LoginMessage[35]="*394915#";//初始值含有产品ID号 /*开辟缓存,注意设置的存储长度要=实际长度m+1*/ char Buf_IMEI[16]; //IMEI 缓存 char Buf_ICCID[21];//ICCID 缓存 char Buf_CSQ[3]; //信号质量 缓存 char Buf_longitude[13]={0}; //经度 char Buf_latitude[13]={0}; //纬度 /* TCP服务器配置参数*/ char tcp_agreement[]="tcp";//TCP协议 char DTU_HeartData[]="";//无需心跳包 char DTU_HeartTime[]="60";//心跳间隔默认60s char DTU_IP[]="183.230.40.40";//OneNET TCP服务器IP地址 char DTU_PORT[]="1811";//OneNET服务器:TCP透传端口号 /* MQTT服务器配置登录账号信息*/ // 当采用MCU配置MQTT参数,才会用到下列三元组信息 char mqtt_deviceclientid[]="657554468"; // mqtt 客户端:设备ID char mqtt_username[]="220520"; // mqtt 用户名:产品ID号 char mqtt_password[]="LBWIOT"; // mqtt 密码:设备密钥 //char mqtt_IP[]="183.230.40.39";//OneNET mqtt服务器域名mqtt.heclouds.com char mqtt_IP[]="119.3.236.206"; char mqtt_PORT[]="18083";//OneNET mqtt 端口号 char mqtt_HeartTime[]="60";//心跳保活时间 char MQTT_Encryptflag[]="0";//用户信息加密 //此处修改您需要订阅的主题 char mqtt_subtopic[]="IOT_LBW"; //mqtt 订阅主题 char mqtt_pubtopic[]="IOT_LBW"; //mqtt 发布主题 char MQTT_Qos[]="0";//主题等级0~2 char MQTT_Dup[]="0";//消息是否重发,0 不重发,1 重发 char MQTT_Retain[]="0";//遗嘱消息是否存储到服务器,0不需要,1 需要 /*********************************************************** 【函数名称】DTU_Initconfig() 【功 能】配置MQTT服务器连接初始化配置 【输入参数】无 【返回参数】Congfig_flag 【备 注】DTU_Mode:TCP=0、MQTT=1 ***********************************************************/ void DTU_Initconfig(int DTU_Mode) { //首先要配置模块所处的工作模式 //选择联网方式 if(DTU_Mode==1) { Usart2_SendString("AT+CFGNET=1\r\n");//mqtt模式 Delay_Ns(1); if(FindString(Usart2_RX_Buf,"AT+CFGNET=1\r\n")) { printf("已设置为MQTT模式,等待模块重启\n"); } else { printf("配置失败\n"); } Usart2_SendString("AT+CFGPARA=SAVE\r\n");//保存参数,并等待重启 Delay_Ns(6); MQTT_Initconfig(); } else { Usart2_SendString("AT+CFGNET=0\r\n");//mqtt模式 Delay_Ns(1); if(FindString(Usart2_RX_Buf,"AT+CFGNET?\r\n")) { printf("已设置为TCP模式,等待模块重启\n"); } Usart2_SendString("AT+CFGPARA=SAVE\r\n");//保存参数,并等待重启 Delay_Ns(6); NETCongfig(tcp_agreement,DTU_HeartData,DTU_HeartTime,DTU_IP,DTU_PORT); } } /*********************************************************** 【函数名称】MQTT_Initconfig 【功 能】配置MQTT服务器连接初始化配置 【输入参数】 【返回参数】Congfig_flag 【备 注】非阿里云平台登录例程 ***********************************************************/ void MQTT_Initconfig() { //配置服务器和客户端ID MQTT_ServerCongfig(mqtt_IP,mqtt_PORT,mqtt_deviceclientid,mqtt_HeartTime); //配置登录平台账户密码 MQTT_CountCongfig(mqtt_username,mqtt_password,MQTT_Encryptflag); //设置会话模式 MQTT_RemainCongfig(); //设置遗嘱模式 MQTT_WILLCongfig(); //设置订阅主题:如果存在更换平台,要使用清除订阅主题指令@clean@sub@,清除旧的订阅主题,清除时需要发保存指令才能生效。 MQTT_SubTopicConfig(mqtt_subtopic,MQTT_Qos); //设置发布主题 MQTT_PubTopicConfig(mqtt_pubtopic,MQTT_Qos,MQTT_Retain,MQTT_Dup); //保存参数设置 Usart2_SendString("AT+CFGPARA=SAVE");//保存参数,并等待重启 Delay_Ns(6); //延时等待,注意:只要是模块重启操作,延时等待时间要求10秒以上 } /*********************************************************** 【函数名称】NETCongfig 【功 能】配置远程服务器参数 【输入参数】Mode 协议,tcp HeartData 心跳包内容 Time 心跳间隔时间 IP 服务器IP地址 Port 端口号 【返回参数】Congfig_flag 【备 注】无 ***********************************************************/ void NETCongfig(char*Mode,char*HeartData,char*Time,char*IP,char*Port) { int i,j; //注意心跳包长度,Congfig_Server申请的空间长度要大于整条指令长度。 char Congfig_Server[50]="@config@server@"; char str2[]="###"; char str1[]=","; strcat(Congfig_Server,Mode); strcat(Congfig_Server,str1); strcat(Congfig_Server,HeartData); strcat(Congfig_Server,str1); strcat(Congfig_Server,Time); strcat(Congfig_Server,str1); strcat(Congfig_Server,IP); strcat(Congfig_Server,str1); strcat(Congfig_Server,Port); strcat(Congfig_Server,str2); //打印拼接后的服务器配置指令 j=strlen(Congfig_Server); //计算出长度 // printf("j=%d\n",j); for(i=0;i<=j;i++) { printf("%c",Congfig_Server[i]); } printf("\n"); // 清除串口2缓存数据 Clear_Usart2Buf(); Delay_Ns(1); //TCP连接--服务器配置指令 Usart2_SendString((char*)Congfig_Server); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"AT+CFGSERVER?")) { Usart2_SendString("AT+CFGPARA=SAVE"); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"AT+CFGPARA?")) { Congfig_flag=1; printf("Congfig_flag=%d\n",Congfig_flag); printf("IP和端口号已配置完成,等待模块重启\n"); } else { Congfig_flag=0; printf("Congfig_flag=%d\n",Congfig_flag); printf("配置失败,模组串口无响应,请检查串口\n"); } } else { Congfig_flag=0; // printf("Congfig_flag=%d\n",Congfig_flag); printf("配置指令无响应,请检查串口\n"); } } /*********************************************************** 【函数名称】MQTT_ServerCongfig 【功 能】配置远程MQTT服务器参数 【输入参数】 Time 心跳间隔时间 IP 服务器IP地址 Port 端口号 【返回参数】无 【备 注】示例@config@[email protected],6002,657554468,60### ***********************************************************/ void MQTT_ServerCongfig(char*IP,char*Port,char*MQTT_Client,char*Time) { int i,j; char Congfig_Server[50]="@config@server@"; char str2[]="###"; char str1[]=","; strcat(Congfig_Server,IP); strcat(Congfig_Server,str1); strcat(Congfig_Server,Port); strcat(Congfig_Server,str1); strcat(Congfig_Server,MQTT_Client); strcat(Congfig_Server,str1); strcat(Congfig_Server,Time); strcat(Congfig_Server,str2); //打印拼接后的服务器配置指令 j=strlen(Congfig_Server); //计算出长度 printf("j=%d\n",j); for(i=0;i<=j;i++) { printf("%c",Congfig_Server[i]); } printf("\n"); // 清除串口1缓存数据 Clear_Usart2Buf(); Delay_Ns(1); Usart2_SendString((char*)Congfig_Server); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"AT+CFGSERVER?")) { printf("Server Congfig OK\n"); } else { printf("Server Congfig fail!\n"); } } /*********************************************************** 【函数名称】MQTT_CountCongfig 【功 能】配置登录账户密码 【输入参数】 MQTT_User 用户名 MQTT_Keyword 秘钥 MQTT_Encrypt 用户信息加密 【返回参数】无 【备 注】示例@config@user@220520,LBWIOT,0### ***********************************************************/ void MQTT_CountCongfig(char*MQTT_User,char*MQTT_Keyword,char*MQTT_Encrypt) { int i,j; char Congfig_User[50]="@config@user@";//开辟的存储长度要根据账户密码所占长度需求设定 char str2[]="###"; char str1[]=","; strcat(Congfig_User,MQTT_User); strcat(Congfig_User,str1); strcat(Congfig_User,MQTT_Keyword); strcat(Congfig_User,str1); strcat(Congfig_User,MQTT_Encrypt); strcat(Congfig_User,str2); //打印拼接后的服务器配置指令 j=strlen(Congfig_User); //计算出长度 // printf("j=%d\n",j); for(i=0;i<=j;i++) { printf("%c",Congfig_User[i]); } printf("\n"); // 清除串口1缓存数据 Clear_Usart2Buf(); Delay_Ns(1); Usart2_SendString((char*)Congfig_User); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"@config@user@ok###")) { printf("UserCount Congfig OK\n"); } else { printf("UserCount Congfig fail!\n"); } } /*********************************************************** 【函数名称】MQTT_RemainCongfig 【功 能】配置MQTT会话 【输入参数】无 【返回参数】无 【备 注】示例@config@remain@1,2018-10-31### ***********************************************************/ void MQTT_RemainCongfig() { // 清除串口2缓存数据 Clear_Usart2Buf(); Delay_Ns(1); Usart2_SendString("@config@remain@1,2018-10-31###"); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"@config@remain@ok###")) { printf("Remain Congfig OK\n"); } else { printf("Remain Congfig fail!\n"); } } /*********************************************************** 【函数名称】MQTT_WILLCongfig 【功 能】配置MQTT遗嘱消息,默认无遗嘱模式 【输入参数】无 【返回参数】无 【备 注】示例@config@will@0,0,0,0,0### 若要遗嘱模式,请参考字节拼接函数的使用方法,用户自己定义一个函数 本示例只演示MQTT 无遗嘱模式连接服务器用法 ***********************************************************/ void MQTT_WILLCongfig() { // 清除串口2缓存数据 Clear_Usart2Buf(); Delay_Ns(1); Usart2_SendString("@config@will@0,0,0,0,0###"); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"@config@will@ok###")) { printf("WILL Congfig OK\n"); } else { printf("WILL Congfig fail!\n"); } } /*********************************************************** 【函数名称】 MQTT_SubTopicConfig 【功 能】 设置订阅主题 【输入参数】topicMode,对MQTT主题的操作,订阅或者取消订阅 topicname, 主题名 qos,主题等级,分别有三个 0/1/2 【返回参数】无 【备 注】订阅@config@sub@OK4ZS40G93619F5Y/+,0### 若想取消订阅,则要清除订阅主题即可 ***********************************************************/ void MQTT_SubTopicConfig(char*topicname,char*topic_qos) { int i,j; //注意心跳包长度,Congfig_Server申请的空间长度要大于整条指令长度。 char SUB_Topic[50]="@config@sub@"; char str1[]=","; char str2[]="###"; strcat(SUB_Topic,topicname); strcat(SUB_Topic,str1); strcat(SUB_Topic,topic_qos); strcat(SUB_Topic,str2); //打印拼接后的服务器配置指令 j=strlen(SUB_Topic); //计算出长度 printf("j=%d\n",j); for(i=0;i<=j;i++) { printf("%c",SUB_Topic[i]); } printf("\n"); //订阅主题 //清除串口2缓存数据 Clear_Usart2Buf(); Delay_Ns(1); Usart2_SendString((char*)SUB_Topic); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"@config@sub@ok###")||FindString(Usart2_RX_Buf,"@config@sub@repeat###"))//成功订阅主题 { printf("Subtopic set ok!"); } else { printf("Subtopic set fail!"); //订阅失败 } } /*********************************************************** 【函数名称】 MQTT_PubTopicConfig 【功 能】配置发布主题 【输入参数】topicname 主题 qos 主题等级 mqtt_retain 遗嘱消息是否存储到服务器 mqtt_dup 消息是否重发 mqtt_messge 要发送的消息内容 【返回参数】无 【备 注】无;@config@pub@topic,qos,retain,dup,messge### 例如@config@pub@OK4ZS40G93619F5Y,0,0,0### ***********************************************************/ void MQTT_PubTopicConfig(char*topicname,char*qos,char*mqtt_retain,char*mqtt_dup) { int i,j; //注意心跳包长度,Congfig_Server申请的空间长度要大于整条指令长度。 char PUB_PubTopic[50]="@config@pub@"; char str1[]=","; char str2[]="###"; strcat(PUB_PubTopic,topicname); strcat(PUB_PubTopic,str1); strcat(PUB_PubTopic,qos); strcat(PUB_PubTopic,str1); strcat(PUB_PubTopic,mqtt_retain); strcat(PUB_PubTopic,str1); strcat(PUB_PubTopic,mqtt_dup); strcat(PUB_PubTopic,str2); //打印拼接后的服务器配置指令 j=strlen(PUB_PubTopic);//计算出长度 printf("j=%d\n",j); for(i=0;i<=j;i++) { printf("%c",PUB_PubTopic[i]); } // 清除串口2缓存数据 Clear_Usart2Buf(); Delay_Ns(1); Usart2_SendString((char*)PUB_PubTopic); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"@config@pub@ok###")) { printf("Pubtopic set ok"); } else { printf("Pubtopic set fail"); } } /******************************************************************** 【函数名称】 GET_GNSS() 【功 能】获取GNSS定位信息 【输入参数】无 【返回参数】无 【备 注】E是东经 W是西经 N是北纬 S是南纬 假设返回:@get@[email protected],N27.3778766,0,01### ********************************************************************/ void GET_GNSS() { int i,j,lenth1,lenth2; char *pFind_1 = NULL;//指针,地址1 char *pFind_2 = NULL;//指针,地址2 char *p_buf= NULL; //分割后的字符指针 char *delim1 = ","; //分隔符 Clear_Usart2Buf(); // 清除串口2缓存数据 Delay_Ns(1); Usart2_SendString("@get@decode@"); Delay_Ns(5); //此时要等待,获取定位需要时间 if(FindString(Usart2_RX_Buf,"@get@gnss@NoFix###")==NULL ) { printf("GNSS Get Faile!\n"); } else { printf("GNSS Get sucess!\n"); //截取这段经度数据, E114.6027950 pFind_1=strstr(Usart2_RX_Buf, "@get@decode@"); pFind_2=strstr(Usart2_RX_Buf, ","); lenth1=pFind_2-pFind_1; //求出该地址区间数据长度 printf("lenth1=%d\n",lenth1); for(i=12;i<lenth1;i++) { Buf_longitude[i]=Usart2_RX_Buf[i]; printf("longitude=%c",Buf_longitude[i]); } //先分割字符串,分隔符为“ ,” p_buf = strtok(Usart2_RX_Buf,delim1); p_buf= strtok(NULL,delim1); lenth2=strlen(p_buf);//计算出该区间数据长度 printf("latitude_lenth2=%d\n",lenth2);//计算出该区间数据长度 printf("latitude="); //截取这段纬度数据,N27.3778766 for(j=0;j<lenth2;j++) { Buf_latitude[j]=p_buf[j]; printf("%c",Buf_latitude[j]); } } } /*********************************************************** 【函数名称】 GET_IMEI() 【功 能】获取IMEI号 【输入参数】无 【返回参数】无 【备 注】无;IMEI号长度15个字节 ***********************************************************/ void GET_IMEI() { int i,j=0,m; for(m=0;m<3;m++) { Clear_Usart2Buf(); // 清除串口1缓存数据 Delay_Ns(1); Usart2_SendString("@get@imei@"); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"@get@imei@error")) { printf("IMEI号获取失败!\n"); printf("故障提示:(1)请检查模块是否开机?\n"); printf("故障提示:(2)请检查串口通信是否故障?\n"); } else { printf("IMEI:"); for(i=10;i<25;i++) { Buf_IMEI[j]=Usart2_RX_Buf[i]; printf("%c",Buf_IMEI[j]); j++; } printf("\n"); break ; } } } /*********************************************************** 【函数名称】 GET_CSQ 【功 能】获取信号值 【输入参数】无 【返回参数】无 【备 注】无 ***********************************************************/ void GET_CSQ() { int i,j=0,m; for(m=0;m<3;m++)//查询5次 { Clear_Usart2Buf();//清除串口1缓存数据 Delay_Ns(1); Usart2_SendString("@get@csq@"); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"@get@csq@error")) { printf("4G信号CSQ值获取失败!\n"); printf("故障提示:(1)请检查模块是否开机?\n"); printf("故障提示:(2)请检查串口通信是否故障?\n"); printf("故障提示:(3)请检查SIM卡是否插入?\n"); } else { printf("4G信号CSQ="); for(i=9;i<11;i++) { Buf_CSQ[j]=Usart2_RX_Buf[i]; printf("%c",Buf_CSQ[j]); j++; } printf("\n"); break; } } } /*********************************************************** 【函数名称】 GET_SIM_ICCID() 【功 能】获取ICCID号 【输入参数】无 【返回参数】无 【备 注】1获取成功,0获取失败 ***********************************************************/ void GET_ICCID() { int i,j=0,m; for(m=0;m<3;m++)//查询3次 { Clear_Usart2Buf();// 清除串口2缓存数据 Delay_Ns(1); Usart2_SendString("@get@iccid@"); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"@get@iccid@error")) { printf("ICCID 获取失败!\n"); printf("故障提示:(1)请检查串口通信是否故障?\n"); printf("故障提示:(2)请检查SIM卡是否插入?\n"); } else { printf("SIM卡ICCID:"); for(i=12;i<31;i++) { Buf_ICCID[j]=Usart2_RX_Buf[i]; printf("%c",Buf_ICCID[j]); j++; } printf("\n"); break; } } } /*********************************************************** 【函数名称】 GET_AGPS_Position() 【功 能】获取基站定位信息 【输入参数】无 【返回参数】无 【备 注】1获取成功,0获取失败 DTU指令: @get@position@ 示例:模块反馈的信息 @get@[email protected],023.1598603### ***********************************************************/ void GET_AGPS_Position() { int i,k=0,j=0,m; char Buf_AGPS_LOG[]={0}; //经度 char Buf_AGPS_LAT[]={0}; //纬度 for(m=0;m<3;m++)//查询3次 { Clear_Usart2Buf();// 清除串口1缓存数据 Delay_Ns(1); Usart2_SendString("@get@position@"); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"@get@position@error")) { printf("AGPS_Position基站定位信息获取失败!\n"); printf("故障提示:(1)请检查串口通信是否故障?\n"); printf("故障提示:(2)请检查SIM卡是否插入?\n"); } else { printf("AGPS_Position基站定位信息:\n"); printf("经度:"); for(i=14;i<25;i++) { Buf_AGPS_LOG[j]=Usart2_RX_Buf[i];//获取经度 printf("%c",Buf_AGPS_LOG[j]); j++; } printf("\n"); printf("纬度:"); for(i=26;i<37;i++) { Buf_AGPS_LAT[k]=Usart2_RX_Buf[i];//获取纬度 printf("%c",Buf_AGPS_LAT[k]); k++; } printf("\n"); break; } } } /*********************************************************** 【函数名称】 GET_Version() 【功 能】获取版本号 【输入参数】无 【返回参数】无 【备 注】1获取成功,0获取失败 DTU指令: @get@version@ 示例:模块反馈的信息@get@[email protected]### ***********************************************************/ void GET_Version() { int i,j=0,m; for(m=0;m<3;m++) { Clear_Usart2Buf(); // 清除串口1缓存数据 Delay_Ns(1); Usart2_SendString("@get@version@"); Delay_Ns(1); if(FindString(Usart2_RX_Buf,"@get@position@error###")) { printf("版本号获取失败!\n"); printf("故障提示:(1)请检查模块是否开机?\n"); printf("故障提示:(2)请检查串口通信是否故障?\n"); } else { printf("模块固件版本号Version:"); for(i=14;i<23;i++) { Buf_IMEI[j]=Usart2_RX_Buf[i]; printf("%c",Buf_IMEI[j]); j++; } printf("\n"); break ; } } } /**************************************************************** 【函数名称】 Check_DTU_network 【功 能】 检测模块状态 【输入参数】num 检测次数 【返回参数】无 【备 注】检测模块是否已就绪。每间隔1秒查询一次 *****************************************************************/ void Check_DTU_network(u8 num) { int k; for(k=0;k<num;k++)//检测TCP连接状态 { Clear_Usart2Buf(); // 清除串口2缓存数据 Delay_Nms(100); Usart2_SendString("@get@netstate@");//查询网络连接状态 Delay_Nms(400); if(FindString(Usart2_RX_Buf,"@get@netstate@ok")) { TCP_Connectflag=1; printf("TCP_Connectflag=%d\n",TCP_Connectflag); printf("TCP连接成功!\n"); break; } else { TCP_Connectflag=0; printf("TCP_Connectflag=%d\n",TCP_Connectflag); printf("TCP连接失败!\n"); printf("故障提示:(1)请检查模块IP地址和端口是否正确?\n"); printf("故障提示:(2)请检查SIM卡是否欠费?是否被地域限制和机卡绑定?\n"); } } } /**************************************************************** 【函数名称】 Login_OneNET_Server 【功 能】 登陆OneNET服务器平台 【输入参数】number 次数 【返回参数】无 【备 注】发送登录包,重发number次 *****************************************************************/ void Login_OneNET_Server(u8 number) { u8 j,m; //如果登陆包发送成功,服务器会应答设备OK for(j=0;j<number;j++) { for(m=0;m<=strlen(LoginMessage);m++)//打印登录包信息 { printf("%c",LoginMessage[m]); } printf("\n"); Clear_Usart2Buf(); // 清除串口1缓存数据 Delay_Nms(100); Usart2_SendString(LoginMessage); Delay_Nms(400);//延时等待 if(FindString(Usart2_RX_Buf,"received")) { Login_OneNET_flag=1; printf("登陆包发送成功!\n"); break; } else { Login_OneNET_flag=0; printf("登陆包发送失败!\n"); printf("故障提示:(1)请检查服务器平台是否存在该设备编号?\n"); printf("故障提示:(2)请检登录包格式是否完整?\n"); } } } /**************************************************************** 【函数名称】 Login_Message 【功 能】 组建登录包 【输入参数】无 【返回参数】无 【备 注】检测模块是否已就绪。每间隔1秒查询一次,超时时间为20秒 使用strcat()函数向str1字符串追加内容的时候,由于str1空间比较小, 而追加的字符又很多,就会导致多出来的字符溢出到相邻的存储空间中, 导致软件运行奔溃。 *****************************************************************/ void Login_Message() { /*在OneNET平台上LUA脚本取名要与登录包中的脚本名称要一致*/ char str1[]="#cupluas*";//关联的LUA脚本名称:cupluas strcat(LoginMessage,Buf_IMEI);//拼接IMEI strcat(LoginMessage,str1);//拼接脚本名称 strcat(LoginMessage,"\0");//拼接结尾符 } /**************************************************************** 【函数名称】 FindString 【功 能】判断缓存中是否含有指定的字符串 【输入参数】字符串 p 【返回参数】整型值1或0 【备 注】调用extern char *strstr(char *str1, char *str2)该函数 *****************************************************************/ int FindString(char* p1,char* p2) { if(strstr(p1,p2)!=NULL) { return 1; } return 0; } /*********************************************************** 【函数名称】LTE_KEYGPIOConfig 【功 能】配置LTE_KEY GPIO端口 【输入参数】无 【返回参数】无 【备 注】电源通断引脚KEY GPIO配置 ***********************************************************/ void LTE_KEYGPIOConfig() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(LTE_PWRKEY_RCC, ENABLE); GPIO_InitStructure.GPIO_Pin = LTE_PWRKEY; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LTE_PWRKEY_PORT, &GPIO_InitStructure); } /*********************************************************** 【函数名称】LTE_RSTGPIOConfig 【功 能】配置LTE_RST GPIO端口 【输入参数】无 【返回参数】无 【备 注】推挽输出 ***********************************************************/ void LTE_RSTGPIOConfig() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(LTE_RST_RCC, ENABLE); GPIO_InitStructure.GPIO_Pin = LTE_RST; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LTE_RST_PORT, &GPIO_InitStructure); } /*********************************************************** 【函数名称】LTE_DTU_RESET 【功 能】复位DTU模块 【输入参数】无 【返回参数】无 【备 注】推挽输出 ***********************************************************/ void LTE_DTU_RESET() { LTE_RST_H;//拉高复位模块 Delay_Nms(200);//延时200ms LTE_RST_L;//拉低,禁止复位 Delay_Ns(5);//延时5秒,等待模块完成重启 } 在不更改原代码的情况下,将DTU指令更改为AT指令

//ÍøÂçÉ豸Çý¶¯ #include "esp8266.h" //Ó²¼þÇý¶¯ #include "delay.h" #include "oled.h" #include "led.h" //C¿â #include <string.h> #include <stdio.h> unsigned char esp8266_buf[buf_len]; unsigned char data_buf[buf_len]; unsigned short esp8266_cnt = 0; unsigned short esp8266_cntPre = 0; extern char Flagout; //========================================================== // º¯ÊýÃû³Æ£º ESP8266_Clear // // º¯Êý¹¦ÄÜ£º Çå¿Õ»º´æ // // Èë¿Ú²ÎÊý£º ÎÞ // // ·µ»Ø²ÎÊý£º ÎÞ // // ˵Ã÷£º //========================================================== void ESP8266_Clear(void) { memset(esp8266_buf, 0, sizeof(esp8266_buf)); esp8266_cnt = 0; } //========================================================== // º¯ÊýÃû³Æ£º ESP8266_Init // // º¯Êý¹¦ÄÜ£º ³õʼ»¯ESP8266 // // Èë¿Ú²ÎÊý£º ÎÞ // // ·µ»Ø²ÎÊý£º ÎÞ // // ˵Ã÷£º //========================================================= void ESP8266_Init(unsigned int bound) { #if Bamfa_USART1 //GPIO¶Ë¿ÚÉèÖà GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //ʹÄÜUSART1£¬GPIOAʱÖÓ //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //¸´ÓÃÍÆÍìÊä³ö GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA.9 //USART1_RX GPIOA.10³õʼ»¯ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//¸¡¿ÕÊäÈë GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA.10 //Usart1 NVIC ÅäÖà NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//ÇÀÕ¼ÓÅÏȼ¶3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //×ÓÓÅÏȼ¶3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀʹÄÜ NVIC_Init(&NVIC_InitStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷ //USART ³õʼ»¯ÉèÖà USART_InitStructure.USART_BaudRate = bound;//´®¿Ú²¨ÌØÂÊ USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö³¤Îª8λÊý¾Ý¸ñʽ USART_InitStructure.USART_StopBits = USART_StopBits_1;//Ò»¸öֹͣλ USART_InitStructure.USART_Parity = USART_Parity_No;//ÎÞÆæÅ¼Ð£Ñéλ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ÎÞÓ²¼þÊý¾ÝÁ÷¿ØÖÆ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //ÊÕ·¢Ä£Ê½ USART_Init(USART1, &USART_InitStructure); //³õʼ»¯´®¿Ú1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//¿ªÆô´®¿Ú½ÓÊÜÖÐ¶Ï USART_Cmd(USART1, ENABLE); //ʹÄÜ´®¿Ú1 #elif Bamfa_USART2 GPIO_InitTypeDef gpio_initstruct; USART_InitTypeDef usart_initstruct; NVIC_InitTypeDef nvic_initstruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //PA2 TXD gpio_initstruct.GPIO_Mode = GPIO_Mode_AF_PP; gpio_initstruct.GPIO_Pin = GPIO_Pin_2; gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &gpio_initstruct); //PA3 RXD gpio_initstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; gpio_initstruct.GPIO_Pin = GPIO_Pin_3; gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &gpio_initstruct); usart_initstruct.USART_BaudRate = bound; usart_initstruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //ÎÞÓ²¼þÁ÷¿Ø usart_initstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //½ÓÊպͷ¢ËÍ usart_initstruct.USART_Parity = USART_Parity_No; //ÎÞУÑé usart_initstruct.USART_StopBits = USART_StopBits_1; //1λֹͣλ usart_initstruct.USART_WordLength = USART_WordLength_8b; //8λÊý¾Ýλ USART_Init(USART2, &usart_initstruct); USART_Cmd(USART2, ENABLE); //ʹÄÜ´®¿Ú USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //ʹÄܽÓÊÕÖÐ¶Ï nvic_initstruct.NVIC_IRQChannel = USART2_IRQn; nvic_initstruct.NVIC_IRQChannelCmd = ENABLE; nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 1; nvic_initstruct.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&nvic_initstruct); #elif Bamfa_USART3 NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIOBʱÖÓ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); USART_DeInit(USART3); //¸´Î»´®? //USART2_TX PB10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //¸´ÓÃÍÆÍìÊä³ö GPIO_Init(GPIOB, &GPIO_InitStructure); //³õʼ»¯PB10 //USART3_RX PB11 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//¸¡¿ÕÊäÈë GPIO_Init(GPIOB, &GPIO_InitStructure); //³õʼ»¯PB11 USART_InitStructure.USART_BaudRate = bound;//Ò»°ãÉèÖÃΪ9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö³¤Îª8λÊý¾Ý¸ñʽ USART_InitStructure.USART_StopBits = USART_StopBits_1;//Ò»¸öֹͣλ USART_InitStructure.USART_Parity = USART_Parity_No;//ÎÞÆæÅ¼Ð£Ñéλ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ÎÞÓ²¼þÊý¾ÝÁ÷¿ØÖÆ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //ÊÕ·¢Ä£Ê½ USART_Init(USART3, &USART_InitStructure); //³õʼ»¯´®¿Ú 3 USART_Cmd(USART3, ENABLE); //ʹÄÜ´®¿Ú //ʹÄܽÓÊÕÖÐ¶Ï USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//¿ªÆôÖÐ¶Ï NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//ÇÀÕ¼ÓÅÏȼ¶2 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //×ÓÓÅÏȼ¶0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀʹÄÜ NVIC_Init(&NVIC_InitStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷ #endif GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(ESP01S_RST_RCC_CLK, ENABLE); //ʹÄÜA¶Ë¿ÚʱÖÓ GPIO_InitStructure.GPIO_Pin = ESP01S_RST_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //ÍÆÍìÊä³ö GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//ËÙ¶È50MHz GPIO_Init(ESP01S_RST_PROT, &GPIO_InitStructure); //³õʼ»¯GPIOA GPIO_ResetBits(ESP01S_RST_PROT,ESP01S_RST_PIN);//esp8266µÍµçƽ¸´Î» delay_ms(200); GPIO_SetBits(ESP01S_RST_PROT,ESP01S_RST_PIN); ESP8266_Clear(); OLED_ShowCHinese(0, 3,15);//Õý OLED_ShowCHinese(18,3,16);//ÔÚ OLED_ShowCHinese(36,3,17);//Á¬ OLED_ShowCHinese(54,3,18);//½Ó OLED_ShowString (72,3,"WIFI",16); OLED_ShowString (108,3,"..",16); OLED_ShowCHinese(0, 6, 19);//½ø OLED_ShowCHinese(18,6, 20);//¶È OLED_ShowCHinese(36,6,21);//£º // printf("1. AT\r\n"); OLED_ShowString(44,6,"10%",16); while(ESP8266_SendCmd("AT\r\n","OK")&&Flagout) delay_ms(100); // printf("2. CWMODE\r\n"); OLED_ShowString(44,6,"20%",16); while(ESP8266_SendCmd("AT+CWMODE=3\r\n", "OK")&&Flagout) delay_ms(100); // printf( "3. Á¬½Ó·ÓÉÆ÷¡£\r\n"); OLED_ShowString(44,6,"30%",16); while(ESP8266_SendCmd(ESP8266_WIFI_INFO, "OK")&&Flagout) delay_ms(100); // printf("4. ¿ªÆô͸Ã÷´«Êäģʽ¡£\r\n"); OLED_ShowString(44,6,"30%",16); while(ESP8266_SendCmd("AT+CIPMODE=1\r\n", "OK")&&Flagout) delay_ms(100); // printf( "5. Á¬½Ó°Í·¨ÔÆ¡£\r\n"); OLED_ShowString(44,6,"50%",16); while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT")&&Flagout) delay_ms(100); // printf( "6. ½øÈë͸´«Ä£Ê½£¬ÏÂÃæ·¢µÄ¶¼»áÎÞÌõ¼þ´«Êä¡£\r\n"); OLED_ShowString(44,6,"80%",16); while(ESP8266_SendCmd("AT+CIPSEND\r\n", "OK")&&Flagout) delay_ms(100); // printf( "7.¶©ÔÄÖ÷Ìâ¡£\r\n"); OLED_ShowString(44,6,"90%",16); while(ESP8266_SendCmd(ESP8266_TOPIC, "cmd=1&res=1")&&Flagout) delay_ms(100); Flagout=3; // printf("8. ESP8266 ³õʼ»¯Íê³É£¡\r\n"); OLED_ShowString(44,6,"100%",16); Flagout=0; delay_ms(2000); ESP8266_Clear(); OLED_Clear(0); } //========================================================== // º¯ÊýÃû³Æ£º ESP8266_WaitRecive // // º¯Êý¹¦ÄÜ£º µÈ´ý½ÓÊÕÍê³É // // Èë¿Ú²ÎÊý£º ÎÞ // // ·µ»Ø²ÎÊý£º REV_OK-½ÓÊÕÍê³É REV_WAIT-½ÓÊÕ³¬Ê±Î´Íê³É // // ˵Ã÷£º Ñ­»·µ÷Óüì²âÊÇ·ñ½ÓÊÕÍê³É //========================================================== _Bool ESP8266_WaitRecive(void) { if(esp8266_cnt == 0) //Èç¹û½ÓÊÕ¼ÆÊýΪ0 Ôò˵Ã÷ûÓд¦ÓÚ½ÓÊÕÊý¾ÝÖУ¬ËùÒÔÖ±½ÓÌø³ö£¬½áÊøº¯Êý return REV_WAIT; if(esp8266_cnt == esp8266_cntPre) //Èç¹ûÉÏÒ»´ÎµÄÖµºÍÕâ´ÎÏàͬ£¬Ôò˵Ã÷½ÓÊÕÍê±Ï { esp8266_cnt = 0; //Çå0½ÓÊÕ¼ÆÊý return REV_OK; //·µ»Ø½ÓÊÕÍê³É±êÖ¾ } esp8266_cntPre = esp8266_cnt; //ÖÃΪÏàͬ return REV_WAIT; //·µ»Ø½ÓÊÕδÍê³É±êÖ¾ } /************************************************************ * º¯ÊýÃû³Æ£º Usart_SendString * * º¯Êý¹¦ÄÜ£º ´®¿ÚÊý¾Ý·¢ËÍ * * Èë¿Ú²ÎÊý£º USARTx£º´®¿Ú×é * str£ºÒª·¢Ë͵ÄÊý¾Ý * len£ºÊý¾Ý³¤¶È * * ·µ»Ø²ÎÊý£º ÎÞ * * ˵Ã÷£º ************************************************************ */ void Usart_SendString(USART_TypeDef *USARTx, unsigned char *str, unsigned short len) { unsigned short count = 0; for(; count < len; count++) { USART_SendData(USARTx, *str++); //·¢ËÍÊý¾Ý while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET); //µÈ´ý·¢ËÍÍê³É } } //========================================================== // º¯ÊýÃû³Æ£º ESP8266_SendCmd // // º¯Êý¹¦ÄÜ£º ·¢ËÍÃüÁî // // Èë¿Ú²ÎÊý£º cmd£ºÃüÁî // res£ºÐèÒª¼ì²éµÄ·µ»ØÖ¸Áî // // ·µ»Ø²ÎÊý£º 0-³É¹¦ 1-ʧ°Ü // // ˵Ã÷£º //========================================================== _Bool ESP8266_SendCmd(char *cmd, char *res) { unsigned char timeOut = 200; Usart_SendString(Bamfa_USART, (unsigned char *)cmd, strlen((const char *)cmd)); while(timeOut--) { if(ESP8266_WaitRecive() == REV_OK) //Èç¹ûÊÕµ½Êý¾Ý { if(strstr((const char *)esp8266_buf, res) != NULL) //Èç¹û¼ìË÷µ½¹Ø¼ü´Ê { ESP8266_Clear(); //Çå¿Õ»º´æ return 0; } } delay_ms(10); } return 1; } //========================================================== // º¯ÊýÃû³Æ£º ESP8266_SendData // // º¯Êý¹¦ÄÜ£º ·¢ËÍÊý¾Ý // // Èë¿Ú²ÎÊý£º data£ºÊý¾Ý // len£º³¤¶È // // ·µ»Ø²ÎÊý£º ÎÞ // // ˵Ã÷£º //========================================================== void ESP8266_SendData(unsigned char *data) { ESP8266_Clear(); //Çå¿Õ½ÓÊÕ»º´æ Usart_SendString(Bamfa_USART, (unsigned char *)data, strlen((const char *)data)); //·¢ËÍÉ豸Á¬½ÓÇëÇóÊý¾Ý } //========================================================== // º¯ÊýÃû³Æ£º USART2_IRQHandler // // º¯Êý¹¦ÄÜ£º ´®¿Ú2ÊÕ·¢ÖÐ¶Ï // // Èë¿Ú²ÎÊý£º ÎÞ // // ·µ»Ø²ÎÊý£º ÎÞ // // ˵Ã÷£º //========================================================== #if Bamfa_USART1 void USART1_IRQHandler(void) { if(USART_GetITStatus(Bamfa_USART, USART_IT_RXNE) != RESET) //½ÓÊÕÖÐ¶Ï { if(esp8266_cnt >= sizeof(esp8266_buf)) esp8266_cnt = 0; //·ÀÖ¹´®¿Ú±»Ë¢±¬ esp8266_buf[esp8266_cnt++] = USART_ReceiveData(Bamfa_USART); } USART_ClearFlag(Bamfa_USART, USART_FLAG_RXNE); } #elif Bamfa_USART2 void USART2_IRQHandler(void) { if(USART_GetITStatus(Bamfa_USART, USART_IT_RXNE) != RESET) //½ÓÊÕÖÐ¶Ï { if(esp8266_cnt >= sizeof(esp8266_buf)) esp8266_cnt = 0; //·ÀÖ¹´®¿Ú±»Ë¢±¬ esp8266_buf[esp8266_cnt++] = USART_ReceiveData(Bamfa_USART); } USART_ClearFlag(Bamfa_USART, USART_FLAG_RXNE); } #elif Bamfa_USART3 void USART3_IRQHandler(void) { if(USART_GetITStatus(Bamfa_USART, USART_IT_RXNE) != RESET) //½ÓÊÕÖÐ¶Ï { if(esp8266_cnt >= sizeof(esp8266_buf)) esp8266_cnt = 0; //·ÀÖ¹´®¿Ú±»Ë¢±¬ esp8266_buf[esp8266_cnt++] = USART_ReceiveData(Bamfa_USART); } USART_ClearFlag(Bamfa_USART, USART_FLAG_RXNE); } #endif 帮我根据以上代码生成流程框图

/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2024 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "onchip_conf.h" #include "driver_conf.h" /* Private includes ----------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); #define USER_UART3 2 //0-无APP 1-蓝牙通信 2-WIFI通信 /* Private variables ---------------------------------------------------------*/ /*object*/ c_hx711 hx711; //定义 hx711 结构体变量 c_servo servo; //定义 servo 舵机结构体变量 c_my_gpio led; //创建 LED灯 控制结构体 c_esp8266 esp8266; //创建 ESP8266 控制结构体 /*variables*/ static float hx711_weight; //定义变量用于保存 hx711 获取到的重量 static char tx_buf[64]; //定义数组用于保存待发送的内容 static char rec_buf[64]; //定义数组用来接受串口数据 static uint8_t servo_flag=0; //舵机标志位 /* Private user code ---------------------------------------------------------*/ /*callback*/ int my_exti_callback(const char* key_name, uint8_t key_state) { if((strstr(key_name, "key1") != NULL)&&(key_state==1)){ servo_flag=!servo_flag; if(servo_flag) servo.set(&servo, 70); else servo.set(&servo, 0); } if((strstr(key_name, "inf") != NULL)&&(key_state==1)){ servo.set(&servo, 0); servo_flag=0; } else if((strstr(key_name, "inf") != NULL)&&(key_state==0)){ servo.set(&servo, 70); servo_flag=1; } } //接受数据处理函数 void User_UART3(){ char *pxIndex; //定义变量用于暂存分解得到的字符 if(strstr(rec_buf, "AT+DATA1") != NULL){ //判断数据包内是否含有包头 pxIndex = strtok(rec_buf, "="); pxIndex = strtok(NULL, ","); servo_flag = atoi(pxIndex); if(servo_flag) servo.set(&servo, 70); else servo.set(&servo, 0); } } int esp8266_recive_callback(void* param, char* key, char *value) { //对数据长度进行判断,超过64的认为是乱码,干扰 if(strlen(value) < 64){ memset(rec_buf, 0, sizeof(rec_buf)); memcpy(rec_buf, value, strlen(value)); } User_UART3(); return R_OK; } void bluetooth_interrupt(void* param, uint8_t* data, uint16_t data_len) { /*对数据长度进行判断,超过64的认为是乱码,干扰,不超过就保存到数组rec_buf中*/ if(data_len < 64){ memset(rec_buf, 0, sizeof(rec_buf)); //清空rec_buf memcpy(rec_buf, data, data_len); //将data的内容拷贝到rec_buf中 } char *pxIndex; //定义变量用于暂存分解得到的字符 if(strstr(rec_buf,"\r\n") != NULL){ //判断数据包内是否含有结束符 User_UART3(); } } /** * @brief The application entry point. * @retval int */ int main(void) { /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); // Device header /* Configure the system clock */ SystemClock_Config(); /* 延时100ms 等待时钟信号稳定 */ DelayMs(100); /*init*/ hx711 = hx711_create(GPIOB, GPIO_PIN_6, GPIOB, GPIO_PIN_7); //初始化 hx711 称重传感器 hx711.zero(&hx711); //hx711 校准 servo = servo_create(TIM_ID3, TIM_CHN3); //初始化 servo 舵机 servo.set(&servo, 0); led = my_gpio_create(GPIOA, GPIO_PIN_6, GPIO_OUT); //初始化 LED 用到的GPIO exti_list_t exti_list[] = { //创建外部中断列表 /*exti_list*/ {"key1",GPIOC, GPIO_PIN_15, MY_EXTI_FALLING}, //按键1, 下降沿触发,默认为高电平 {"inf1",GPIOA, GPIO_PIN_0, MY_EXTI_FALLING}, //按键2, 上升沿触发,默认为低电平 }; my_exti.init(exti_list, sizeof(exti_list)/sizeof(exti_list_t), my_exti_callback); //创建按键回调函数 if(USER_UART3 == 1){ my_uart.init(MY_UART3, 115200, UART_MODE_DMA); //初始化 蓝牙模块 用到的串口 my_uart.register_callback(MY_UART3, bluetooth_interrupt, NULL); //注册 蓝牙模块 的串口中断接收处理函数 }else if(USER_UART3 == 2){ //AP-TCP 模式 esp8266 = esp8266_creat(MY_UART3, //选择串口3 AP_TCP, //工作模式: STA + MQTT + ONENET "", //产品ID "", //设备名 ""); esp8266.set_recive_callback(&esp8266, esp8266_recive_callback, NULL); } /*Infinite loop*/ static uint32_t sys_cnt; while (1) { if(sys_cnt%500==0) { sys_cnt = 0; hx711.get(&hx711, &hx711_weight); //获取垃圾重量 if(hx711_weight>3500) led.set(&led, 1); //垃圾超重灯光提醒 else led.set(&led, 0); if(USER_UART3 == 1){ //通过蓝牙向APP发送数据 //通过串口给APP发送参数信息 memset(tx_buf, 0, sizeof(tx_buf)); sprintf(tx_buf,"AT+DATA1=%.1f,\r\n",hx711_weight); my_uart.send(MY_UART3,(uint8_t*)tx_buf,strlen(tx_buf)); } else if(USER_UART3==2){ //通过WIFI向APP发送数据 if(esp8266.state(&esp8266) == ESP8266_TCP_CONNECTED){ memset(tx_buf, 0, sizeof(tx_buf)); sprintf(tx_buf,"AT+DATA1=%.1f,\r\n",hx711_weight); esp8266.send(&esp8266, tx_buf); } } } /*运行系统周期任务*/ my_systick.period_task_running(); sys_cnt++; HAL_Delay(1); } } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ }

docx
内容概要:本文提出了一种融合多尺度Wavelet模型的跨文化英语交际智能模型系统(FL-DP-Wavelet),旨在通过多模态数据融合、多尺度特征提取与跨文化适应性建模,提升智能系统的文化敏感性和语境理解能力。该模型通过结合小波变换与深度学习优化语言信号的时频特征提取,基于跨文化敏感性发展模型(DMIS)构建文化适应性评估模块,并设计多模态数据融合框架,增强跨文化场景下的语义解析鲁棒性。实验结果显示,系统在跨文化语境下的语义理解准确率提升12.7%,文化适应性评分优于基线模型15.3%。 适合人群:从事跨文化交流、国际商务、外语教育的研究人员和技术开发者,特别是对智能系统在跨文化场景中的应用感兴趣的学者和工程师。 使用场景及目标:①跨文化商务谈判、教育合作和公共外交等场景中,需要提升智能系统的文化敏感性和语境理解能力;②帮助系统实现实时文化适应,减少因文化差异引起的语义误判和非语言行为冲突;③通过多模态数据融合,增强智能系统在复杂跨文化环境中的语义解析能力。 其他说明:该研究不仅提出了新的理论框架和技术路径,还在实际应用中验证了其有效性和优越性。未来将聚焦于小波-Transformer耦合、联邦学习隐私保护和在线学习算法,进一步推动系统向自主文化融合演进。

最新推荐

recommend-type

阿达啊是的租出去水电费水电费

企鹅请问阿西重置成本v啊阿萨达
recommend-type

2025全国特种作业操作证高处安装、维护、拆除真题及答案.docx

2025全国特种作业操作证高处安装、维护、拆除真题及答案.docx
recommend-type

### 融合多尺度Wavelet模型的跨文化英语交际智能模型系统构建研究(可实现或可复现-有问题请咨询博主)

内容概要:本文提出了一种融合多尺度Wavelet模型的跨文化英语交际智能模型系统(FL-DP-Wavelet),旨在通过多模态数据融合、多尺度特征提取与跨文化适应性建模,提升智能系统的文化敏感性和语境理解能力。该模型通过结合小波变换与深度学习优化语言信号的时频特征提取,基于跨文化敏感性发展模型(DMIS)构建文化适应性评估模块,并设计多模态数据融合框架,增强跨文化场景下的语义解析鲁棒性。实验结果显示,系统在跨文化语境下的语义理解准确率提升12.7%,文化适应性评分优于基线模型15.3%。 适合人群:从事跨文化交流、国际商务、外语教育的研究人员和技术开发者,特别是对智能系统在跨文化场景中的应用感兴趣的学者和工程师。 使用场景及目标:①跨文化商务谈判、教育合作和公共外交等场景中,需要提升智能系统的文化敏感性和语境理解能力;②帮助系统实现实时文化适应,减少因文化差异引起的语义误判和非语言行为冲突;③通过多模态数据融合,增强智能系统在复杂跨文化环境中的语义解析能力。 其他说明:该研究不仅提出了新的理论框架和技术路径,还在实际应用中验证了其有效性和优越性。未来将聚焦于小波-Transformer耦合、联邦学习隐私保护和在线学习算法,进一步推动系统向自主文化融合演进。
recommend-type

Typora下载问题解决:资源安装包实测可用

### 知识点:Typora下载与安装问题解决 #### 1. Typora 简介 Typora 是一款流行的轻量级Markdown编辑器,它将实时预览功能和源代码编辑结合在一起,为用户提供了一个简洁高效的写作环境。由于其独特的设计和出色的用户体验,Typora 迅速在开发者和内容创作者之间获得了普及。 #### 2. Markdown 简介 Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档。Markdown 被广泛用于编写 README 文件、撰写文章、创建富文本内容等。其特点在于简化了传统的排版语法,让写作更加专注于内容本身。 #### 3. Typora 的特点和优势 - **所见即所得编辑器**:Typora 结合了传统Markdown编辑器和富文本编辑器的优点,使得用户在编写文档时可以直接看到最终效果。 - **跨平台兼容性**:Typora 支持Windows、macOS以及Linux等多个操作系统。 - **简洁的界面**:它拥有简洁的用户界面,没有复杂的菜单,这有助于减少分心,专注于内容创作。 - **即时预览**:Typora 提供即时预览功能,用户可以立即看到其标记语法对应的视觉效果。 - **集成度高**:支持插入图片、代码块、表格、数学公式等多种格式。 - **扩展性**:支持多种主题和插件,可以进一步增强其功能。 #### 4. 关于标题:“关于Typora下载找不到资源” 当用户在寻找Typora的下载资源时,可能会遇到找不到官方下载链接或被错误资源误导的问题。这可能是由于网络环境限制、搜索关键词不当或者不正确的网站导航等原因导致的。为了解决这个问题,重要的是要知道如何辨别官方下载渠道,以及如何查找和验证可靠的资源。 #### 5. 官方资源的识别和下载 - **访问官方网站**:访问 Typora 的官方网站(https://typora.io/)获取最新版本的下载信息。官方网站是获取软件的最安全和最可靠的方式。 - **下载安装包**:官方网站通常会提供最新版本的安装包下载链接,例如,在此案例中,压缩包子文件名列表中的 typora-setup-x64-0.9.49.exe 对应了 Typora 的一个版本号为 0.9.49 的安装程序,适用于64位Windows系统。 - **检查版本更新**:在安装之前,用户应当确认是否是当前最新版本。如果不是,可从官方网站下载最新版本。 #### 6. 安装包文件名称解析 文件名 typora-setup-x64-0.9.49.exe 中的各部分含义: - **typora**:指的是要安装的软件名。 - **setup**:通常表示这是一个安装程序。 - **x64**:表示这个安装程序支持64位系统架构。 - **0.9.49**:表示这个版本号,用户可以通过这个版本号了解其更新历史和功能改进情况。 #### 7. 实测完成 “实测完成”这一描述表明此文件已经过测试,并确认可以正常下载和安装。实测的流程包括下载安装包、运行安装程序、完成安装以及验证软件功能是否正常。 #### 8. 安装流程详解 1. **下载**:从官方网站下载对应操作系统版本的 Typora 安装包。 2. **运行安装程序**:双击下载的安装程序文件(例如 typora-setup-x64-0.9.49.exe)。 3. **安装向导**:安装向导启动后,遵循提示完成安装。可能包含选择安装路径、接受许可协议、选择开始菜单文件夹等步骤。 4. **完成安装**:完成安装向导后,可能需要重启电脑以完成安装。 5. **验证安装**:启动 Typora 程序,检查软件是否能够正常打开,并确保可以正常使用Markdown编辑功能。 #### 9. 常见问题及解决方案 - **找不到下载资源**:确保访问官方网站或使用正规的软件分发平台获取资源。 - **安装程序无法运行**:检查文件是否有损坏,重新下载安装包。确认系统环境满足安装需求,如操作系统版本兼容性、运行库等。 - **软件无法打开**:尝试以管理员权限运行 Typora,或检查是否有系统安全软件阻止其运行。 - **功能异常或错误**:检查是否有可用的软件更新,或者查看 Typora 官方论坛获取帮助。 #### 10. Typora 的未来展望 由于 Typora 不断更新迭代,功能和用户界面可能会有所改变,包括对新特性的支持和旧特性的优化。同时,开发者社区也在不断地为 Typora 开发新的主题和插件,以提供更加丰富的写作体验和扩展功能。用户应定期访问官方网站或关注官方消息,以便获取最新动态和软件更新。 通过以上介绍和问题解答,用户应该可以更好地理解 Typora 的下载与安装过程,并在遇到相关问题时快速找到解决方法,从而顺利使用这款强大的Markdown编辑器。
recommend-type

网络嗅探器实战进阶:掌握高效数据捕获与准确分析的6大策略

# 1. 网络嗅探器基础原理与工具介绍 网络嗅探器,或称为网络分析器、包分析器,是一种用于捕获网络中的数据包并分析其内容的工具。它们通过直接连接到网络上,读取传输中的数据包信息,为网络安全、故障排除和网络性
recommend-type

system verilog task中用宏定义传参

<think>好的,用户现在想了解如何在SystemVerilog中使用宏定义向task传递参数。之前我已经回答了C/C++中宏定义传参的方法,现在需要迁移到SystemVerilog,同时结合用户提供的引用内容。 首先,我需要回忆SystemVerilog中宏的基本语法,确认是否与C/C++类似。SystemVerilog确实支持`define宏,带参数的形式应该也是类似的。用户提供的引用中提到`__FILE__`和`__LINE__`,这些可能和调试有关,所以可能需要考虑在宏中加入这些信息来帮助调试。 接下来,用户的问题是关于如何通过宏向task传参。这里的task应该是指System
recommend-type

Java开发的Help GUI 1.1源码:可视化组件库详解

在分析给定文件信息后,可以提取出如下知识点: 首先,标题中提到了“基于java的开发源码-帮助视图组件库 Help GUI 1.1源代码.zip”,这说明文件包含了一个Java开发的开源项目,该库被命名为Help GUI,版本为1.1。在此基础上,我们可以讨论以下几个方面: 1. Java开发: - Java是一种广泛使用的面向对象的编程语言,它具有跨平台的特性,即“一次编写,到处运行”的能力。Java通过Java虚拟机(JVM)来实现跨平台运行。 - Java的开发环境一般需要配置Java开发工具包(JDK)和集成开发环境(IDE),如Eclipse、IntelliJ IDEA或PyCharm。 - Java支持多线程编程,拥有丰富的类库和框架,如Spring、Hibernate等,用以简化开发流程。 - Java在企业级应用、移动开发(Android)、桌面应用和服务器端应用中都有广泛的应用。 2. 开源项目: - 开源项目是指源代码公开的软件项目,通常遵循特定的开源许可协议,如GPL、LGPL、Apache License等。 - 开源项目的优势在于可自由使用、修改和分发代码,能够促进技术的交流和创新。 - 通过参与开源项目,开发者可以提高自身的技术水平,贡献代码以回馈社区。 3. 组件库Help GUI 1.1: - Help GUI可能是一个为开发者提供的图形用户界面(GUI)组件库,用于简化Java桌面应用的帮助视图创建。 - 组件库一般会包含一系列预制的用户界面组件,例如按钮、文本框、列表框、对话框等,以帮助快速构建用户界面。 - 版本1.1表明这是组件库的一个更新版本,通常新版本会增加新的特性、修复bug、优化性能。 4. PyCharm配置Python环境: - 这部分描述似乎与主标题无关,但其可能涉及PyCharm这一IDE的使用。 - PyCharm是专为Python语言开发的IDE,但也可以配置Java开发环境。 - 在配置Python环境时,需要安装Python解释器,并设置相关的路径、环境变量等。 - PyCharm提供了代码高亮、代码自动完成、版本控制等功能,能够提升开发效率。 由于【压缩包子文件的文件名称列表】中只有一个“codefans.net”,这可能是一个网站地址,但没有提供足够的信息来推断与上述Java项目或组件库直接相关的内容。 综上所述,文件描述了一个基于Java的开源组件库Help GUI 1.1,该组件库用于帮助开发者创建帮助视图,且暗示了PyCharm这一IDE的使用。通过探讨Java开发、开源项目、组件库和IDE配置等知识点,可以更好地理解文件所指的项目背景和应用场景。
recommend-type

网络嗅探器全攻略:从入门到精通的15大技巧与实践案例

# 1. 网络嗅探器基础与重要性 在数字化的世界中,网络嗅探器是IT专业人员的重要工具,它允许我们监视和分析经过网络的数据包。本章将带您了解网络嗅探器的基本概念及其在网络安全和性能监控中的关键作用。 ## 网络嗅探器概述 网络嗅探器,通常被称为“抓包工具”或“协议分析器”,是一种可以监听、记录和分析网络流量的程序或设备。它们在排除网络问题、进行安全审计和协议分析时发挥着重要作用。 ##
recommend-type

RTL8720DN-VA1-CG后面的VA1-CG是什么意思

<think>嗯,用户这次的问题转向了具体的芯片型号解析,询问RTL8720DN-VA1-CG后缀的含义。这属于硬件标识领域的专业问题,需要结合芯片命名规则和行业惯例来分析。 从用户提问方式看,ta应该具备一定技术背景,可能是电子工程师或物联网开发者,正在做物料选型或故障排查。用户特意强调"参考站内引用"但实际没有引用源,说明需要权威解释而非普通科普。之前讨论Wi-Fi频段差异时用户表现出对技术参数的敏感,这次提问同样注重细节标识。 关于这个型号后缀,需要拆解三部分分析: VA1通常代表芯片修订版本(revision),比如初版叫VA0,改进版叫VA1。CG后缀可能有多种含义:最常见的是封
recommend-type

CCPD2019车牌数据集:10000张带YOLO标签图片

车牌检测是计算机视觉领域的一个重要应用,尤其在智能交通系统、监控视频分析以及车辆管理等方面具有广泛的应用。CCPD2019车牌数据集是专为车牌检测任务设计的数据集,包含了大量的实际场景中拍摄的车辆图片及其对应的标注信息,这些标注信息以YOLO(You Only Look Once)格式提供。 YOLO是一种流行的目标检测算法,因其速度和准确性相结合而受到广泛欢迎。在YOLO算法中,整个图像被一次性通过网络进行处理,同时预测出多个边界框和这些框所属的类别。YOLO将目标检测任务视为一个回归问题,直接从图像像素到边界框坐标和类别概率的映射,与其他基于区域的方法相比,YOLO在速度上有很大的优势,可以实现实时检测。 YOLO格式标签是一种特殊的标注格式,它提供了用于训练和验证模型的数据。这些标签通常包含每个目标的类别以及它的位置信息,通常在一张图片的标注文件中,对于每一个检测到的车辆,都会有一个对应的标注行,标注行中包含了该车辆车牌的位置、大小和类别信息。通常这些信息包括:标注物体在原图中的中心点坐标(x,y)、宽度、高度以及类别ID。 使用CCPD2019车牌数据集,研究人员和工程师可以进行深度学习模型的训练,特别是基于YOLO算法的车牌检测模型。数据集中的图片是精心挑选的,包含了各种光照条件、不同角度和遮挡情况下的车牌图像,这对于提高模型在现实世界中检测的准确性和鲁棒性至关重要。 在深度学习中,训练模型需要大量的标注数据。一个高质量的数据集对于模型能否成功学习到目标检测中的关键特征是至关重要的。CCPD2019车牌数据集提供的10000张图片以及它们的YOLO格式标签,能够为模型提供充足的训练材料。这些标签通常都是由人工仔细标注,确保了标注的质量和准确性。 深度学习在车牌识别系统中的应用是多方面的,不仅包括检测车牌的位置,还包括车牌字符的分割和识别。在实际应用中,经过训练的YOLO模型首先对输入图像中的车牌区域进行定位,然后可以通过其他专门设计的深度学习模型对车牌上的文字进行识别。 CCPD2019车牌数据集对于研究和开发车牌识别技术具有重要价值,它有助于推动计算机视觉领域特别是车牌检测和识别技术的发展。通过深度学习,特别是使用YOLO这样的先进算法,可以实现车牌的快速准确识别,这对于智能交通管理、车辆安全监控和交通流量分析等应用具有十分重要的意义。