嵌入式踩坑:STM32+ESP8266 AT 指令发送返回 ERROR,串口助手正常
·
STM32 通过 USART2 驱动 ESP8266 AT 指令,代码发送 AT 指令模块返回ERROR;但是电脑串口助手直接发完全正常。硬件层面排查:供电加 AMS1117,电流充足,接线引脚无误。
根因
printf重定向函数fputc写了自动补\r的逻辑:
int fputc(int ch, FILE *f)
{
if (ch == '\n')
{
HAL_UART_Transmit(&huart2, (uint8_t *)&"\r", 1, 1000);
}
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 1000);
}
代码里调用printf("%s\r\n", cmd)发送 AT 指令,输出字符序列:cmd内容 + \r + \n。 当\n触发 if 判断,额外插入一个\r,最终发给 ESP8266 的结束符变成 \r\r\n。 ESP8266 AT 固件只识别\r\n作为指令结束标志,多余回车导致指令解析失败,返回 ERROR。
重点区分两种写法:
- fputc 自动补
\r:printf 只需要写%s\n,不要手动加\r- fputc 不做任何字符替换:printf 才用
%s\r\n
修复方案
修改 fputc,原样转发字符,去掉自动添加\r的逻辑,并且补齐标准返回值:
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 1000);
return ch;
}
代码架构说明
- 使用 USART2 与 ESP8266 通信,串口中断接收,全局缓冲区存储模块应答,
strstr匹配应答字符串 ESP8266_SendAT自带 3 次重试,每次发送前清空接收缓存,函数内部通过 printf 追加\r\n作为 AT 指令结尾- OneNET 物模型上传使用
AT+MQTTPUBRAW,下发 AT 命令收到 OK 之后,直接发送 JSON 载荷,载荷不能带任何换行符 - MQTTUSERCFG 参数保持原有配置不变,MQTT 连接应答要匹配
+MQTTCONNECTED,不是CONNECT
其他潜在隐患(后续优化)
- 全局 buffer 在中断写、主循环同时读取,存在并发竞争,会造成应答识别不稳定、超时
- 初始化函数不要重复调用,MQTT 会话建立后重复执行 AT 初始化指令会报错
- sprintf 拼接字符串注意数组长度,防止缓冲区溢出产生乱码
调试顺序建议
- 修改 fputc 代码下载
- 单独测试最简单
AT指令,确认返回 OK - 依次测试 AT+CWMODE、AT+CWJAP、MQTTUSERCFG、MQTTCONN
- 最后调用 OneNET_PubRaw_Multi 上传物模型数据

更多推荐


所有评论(0)