news 2026/5/26 11:31:50

二、在freertos中对应esp01s模块的ap模式下的通信测试。

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
二、在freertos中对应esp01s模块的ap模式下的通信测试。

一、前期配置

参考:
https://blog.csdn.net/weixin_44386927/article/details/155891583
的配置。

二、代码部分

1、定义部分
1、串口的初始化参考之前的配置。#defineAP_SSID"ESP01S_AP"// AP模式的WiFi名称#defineAP_PWD"12345678"// AP模式的WiFi密码(至少8位)#defineAP_CHANNEL6// AP信道(1-13)#defineAP_ENCRYPT3// 加密方式:3=WPA2_PSK(推荐)#defineTCP_SERVER_PORT8080typedefstruct{uint8_tconn_id;// 数据发送方的conn_iduint16_tdata_len;// 原始数据长度chardata_content[UART_RX_BUF_SIZE];// 原始数据内容uint8_tparse_ok;// 解析成功标记}IPD_Data_Proc_t;externuint8_tESP01_Send_To_Client(uint8_tconn_id,constchar*proc_data);externvoidESP01_Parse_IPD_Data(constchar*ipd_str,IPD_Data_Proc_t*ipd_proc);
2、函数部分
/** * @brief 去除字符串首尾空白符(\r\n/空格/制表符) */voidtrim_whitespace(char*str){if(str==NULL||*str=='\0')return;// 去除开头空白符char*start=str;while(*start!='\0'&&isspace((unsignedchar)*start))start++;// 去除结尾空白符char*end=str+strlen(str)-1;while(end>start&&isspace((unsignedchar)*end))end--;*(end+1)='\0';// 移动到原字符串开头memmove(str,start,strlen(start)+1);}/** * @brief 解析ESP01S的+IPD数据(兼容首尾\r\n,提取conn_id和内容) */voidESP01_Parse_IPD_Data(constchar*ipd_str,IPD_Data_Proc_t*ipd_proc){memset(ipd_proc,0,sizeof(IPD_Data_Proc_t));ipd_proc->parse_ok=0;// 空数据校验if(ipd_str==NULL||strlen(ipd_str)==0)return;// 去除首尾空白符(处理\r\n+IPD...\r\n)chartemp_buf[128]={0};strncpy(temp_buf,ipd_str,sizeof(temp_buf)-1);trim_whitespace(temp_buf);// 校验是否为IPD格式if(strncmp(temp_buf,"+IPD,",5)!=0)return;// 解析conn_id(IPD后的第一个数字)constchar*p=temp_buf+5;charid_str[4]={0};inti=0;while(*p!=','&&*p!='\0')id_str[i++]=*p++;ipd_proc->conn_id=atoi(id_str);p++;// 跳过逗号// 解析数据长度charlen_str[8]={0};i=0;while(*p!=':'&&*p!='\0')len_str[i++]=*p++;ipd_proc->data_len=atoi(len_str);p++;// 跳过冒号// 解析原始数据内容if(ipd_proc->data_len>0&&ipd_proc->data_len<64){strncpy(ipd_proc->data_content,p,ipd_proc->data_len);ipd_proc->data_content[ipd_proc->data_len]='\0';ipd_proc->parse_ok=1;}}/** * @brief 向指定conn_id的客户端回传处理后的数据 */uint8_tESP01_Send_To_Client(uint8_tconn_id,constchar*proc_data){if(proc_data==NULL||strlen(proc_data)==0){printf("❌ 回传数据为空\r\n");return0;}uint16_tproc_len=strlen(proc_data);// 步骤1:发送AT+CIPSEND指令(指定ID和长度)charsend_cmd[64]={0};snprintf(send_cmd,sizeof(send_cmd),"AT+CIPSEND=%d,%d\r\n",conn_id,proc_len);if(!ESP01_SendATCmd(send_cmd,">","ERROR",1000)){printf("❌ ID%d:AT+CIPSEND指令失败\r\n",conn_id);return0;}// 步骤2:发送处理后的数据(纯数据,无\r\n)HAL_UART_Transmit(&huart2,(uint8_t*)proc_data,proc_len,100);osDelay(20);// 确保数据发送完成return1;}
3、任务部分
voidStartTask02(void*argument){ESP01_UART_Data_t rx_data={0};charcmd_buf[USART1_DMA_BUF_SIZE]={0};charat_cmd[128]={0};printf("串口1调试指令接收任务已启动,支持指令:\r\n");printf("1. LED_ON - 点亮LED\r\n");printf("2. LED_OFF - 关闭LED\r\n");printf("3. ESP_AT+AT - 配置ESP01并开启\r\n");while(1){.....前面省略,参考之前的。elseif(strncmp(cmd_buf,"ESP_AT+",7)==0){// 提取AT指令(去掉前�?ESP_AT+,得到真正的AT指令�?strncpy(at_cmd,cmd_buf+7,sizeof(at_cmd)-1);printf("手动发AT指令给ESP01:%s\r\n",at_cmd);if(strcmp(at_cmd,"AP")==0){HAL_UART_Transmit(&huart2,(uint8_t*)"+++",3,100);osDelay(1000);if(!ESP01_SendATCmd("AT","OK","ERROR",AT_CMD_TIMEOUT)){printf("AT失败\r\n");}// 2. 切换到AP模式(CWMODE=2:仅AP;3:AP+STA)if(!ESP01_SendATCmd("AT+CWMODE=2","OK","ERROR",AT_CMD_TIMEOUT)){printf("AT+CWMODE=2失败\r\n");}ESP01_SendATCmd("AT+RST","READY","ERROR",2000);osDelay(1500);// 等待重启完成(至少1秒)if(!ESP01_SendATCmd("AT","OK","ERROR",AT_CMD_TIMEOUT)){printf("重启后AT测试失败\r\n");}if(!ESP01_SendATCmd("AT+CIPMUX=1","OK","ERROR",AT_CMD_TIMEOUT)){printf("开启多路连接失败\r\n");}else{printf("多路连接模式已开启\r\n");}//配置AP参数(SSID、密码、信道、加密方式)//AT+CWSAP="ESP01S_AP","12345678",11,3snprintf(at_cmd,sizeof(at_cmd),"AT+CWSAP=\"%s\",\"%s\",%d,%d",AP_SSID,AP_PWD,AP_CHANNEL,AP_ENCRYPT);if(!ESP01_SendATCmd(at_cmd,"OK","ERROR",AT_CMD_TIMEOUT)){printf("AT+CWSAP(配置AP参数)失败\r\n");}//AT+CIPMUX=1 # 1=多连接模式,0=单连接(默认)//AT+CIPSERVER=1,8080 # 1=开启服务器,8080=监听端口//AT+CIPSERVER? # 验证服务器状态,返回+CIPSERVER:1,8080即生效snprintf(at_cmd,sizeof(at_cmd),"AT+CIPSERVER=1,%d",TCP_SERVER_PORT);if(!ESP01_SendATCmd(at_cmd,"OK","ERROR",AT_CMD_TIMEOUT)){printf("AT+CIPSERVER(启动TCP服务器)失败\r\n");}else{printf("AP模式TCP服务器已启动:%d\r\n",TCP_SERVER_PORT);// 可选:定时查询客户端连接状态flag_ap_on=1;osThreadFlagsSet(myTask03Handle,0x01);// 通知myTask04开始检测连接状态}}}memset(&rx_data,0,sizeof(rx_data));}}voidStartTask03(void*argument){ESP01_UART_Data_t rx_data={0};IPD_Data_Proc_t ipd_proc;while(1){if(osMessageQueueGet(myQueue02Handle,(void*)&rx_data,NULL,5000)==osOK){if(flag_ap_on==1){// 1. 解析IPD数据(提取conn_id和原始内容)memset(&ipd_proc,0,sizeof(ipd_proc));ESP01_Parse_IPD_Data((char*)rx_data.data,&ipd_proc);if(ipd_proc.parse_ok==0){memset(&rx_data,0,sizeof(rx_data));continue;}if(strcmp(ipd_proc.data_content,"+++")==0){printf("look\n");HAL_UART_Transmit(&huart2,(uint8_t*)ipd_proc.data_content,ipd_proc.data_len,100);osDelay(20);// 确保数据发送完成}ESP01_Send_To_Client(ipd_proc.conn_id,ipd_proc.data_content);}memset(&rx_data,0,sizeof(rx_data));osDelay(100);}osDelay(100);}}

注意:1、初始化配置完后,pc端即客户端,要重新连接。

效果如下:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/26 6:53:17

盛水最多的容器(滑动窗口 双指针)

这道题当然可以暴力求解&#xff0c;O(N^2),但是有时候并不会通过&#xff0c;因此要想一个时间复杂度为O&#xff08;N&#xff09;的方法。如果说用滑动窗口肯定会有人会有疑问&#xff0c;这怎么用&#xff1f;下面直接说解法&#xff1a;首先left与right分别指向数组的两边…

作者头像 李华
网站建设 2026/5/26 6:53:50

深度探究Span:.NET内存布局与零拷贝原理及实践

深度探究Span&#xff1a;.NET内存布局与零拷贝原理及实践 在.NET开发中&#xff0c;高效的内存管理至关重要&#xff0c;尤其在处理高性能、低延迟的应用场景时。Span<T> 类型应运而生&#xff0c;它为开发者提供了一种灵活且高效的内存操作方式&#xff0c;能够显著提升…

作者头像 李华
网站建设 2026/5/25 16:43:49

helm 部署 elasticsearch 栈

说明:本文使用的 chart 仓库名字为 elastic/cloud-on-k8s 地址为 elastic/cloud-on-k8s。 1、添加 repo 源 helm repo add elastic https://helm.elastic.co helm repo update2、安装 eck-operator ⚠️说明:ECK Operator(Elastic Cloud on Kubernetes)本身安装的东西其…

作者头像 李华
网站建设 2026/5/25 15:34:05

Qt定时器线程使用全解析

1.Qt定时器线程使用全解析在Qt框架中&#xff0c;定时器&#xff08;如QTimer&#xff09;的“使用线程”特指其所属线程&#xff08;即创建该定时器的线程&#xff09;必须是由QThread启动并管理、且运行了事件循环&#xff08;exec()&#xff09;的线程。这一规则涉及线程的创…

作者头像 李华
网站建设 2026/5/26 4:54:43

低代码开发的“真香”定律:从排斥到离不开

在数字化工具迭代的历史中&#xff0c;几乎所有颠覆性技术都曾经历过“从排斥到追捧”的转折——智能手机初现时&#xff0c;有人质疑“不如功能机耐用”&#xff1b;云计算普及前&#xff0c;企业担忧“数据放在云端不安全”&#xff1b;低代码开发如今的处境&#xff0c;亦复…

作者头像 李华
网站建设 2026/5/26 4:51:05

32、Django Web应用开发实战指南

Django Web应用开发实战指南 1. 网络应用概述 网络的规模极其庞大,上面充斥着人们日常依赖的各种应用程序。网络应用如此之多,主要有以下几个原因: - 普遍可访问性 :网络应用部署后,任何有权限访问的人只需在浏览器中输入URL即可使用。用户通常只需安装浏览器(他们可…

作者头像 李华