STM32F103F使用HAL_UART_Transmit发送含NULL(0x00)数据时ESP无法完成MQTT发布的问题求助
问题分析与解决方案
核心原因
你遇到的问题本质是字符串解析依赖0x00作为结束符,不管是C语言的字符串函数,还是ESP的AT指令解析逻辑,都会把0x00当成字符串的终止标志:
- 虽然你的代码里用for循环完整拷贝了包含0x00的CMD2数据,但ESP在解析
AT+MQTTPUB指令中被双引号包裹的消息内容时,会在第一个0x00处停止解析,直接忽略后面的所有内容(包括你补的结尾双引号和换行),导致AT指令不完整,ESP无法执行发布操作。 - 哪怕你最后指定了正确的串口发送长度,ESP的AT指令解析器仍然会按字符串规则处理消息字段,不会识别后面的字节。
解决方法
改用ESP AT指令的二进制数据发布模式,直接指定要发布的数据长度,让ESP按字节数读取数据,而不是按字符串解析。这种模式下,0x00会被当作普通二进制字节处理,不会触发截断。
修改后的代码示例
// 1. 构造AT指令前缀:明确指定要发布的数据长度 char PubPrefix[64]; // 根据你的SerialNumber长度调整缓冲区大小 // 使用snprintf获取实际写入的前缀长度(避免strlen可能的问题) int prefixLen = snprintf(PubPrefix, sizeof(PubPrefix), "AT+MQTTPUB=0,\"Data/%s\",%d,", SerialNumber, DataLength); // 2. 发送AT指令前缀 HAL_UART_Transmit(huart, (uint8_t *)PubPrefix, prefixLen, 10); // 3. 发送CMD2中的原始二进制数据(包含0x00也没问题) HAL_UART_Transmit(huart, (uint8_t *)CMD2, DataLength, 10); // 4. 发送指令结束的换行符 char cmdEnd[] = "\r\n"; HAL_UART_Transmit(huart, (uint8_t *)cmdEnd, sizeof(cmdEnd)-1, 10);
关键说明
- 这个方案不再把二进制数据放到双引号里,而是通过
%d告诉ESP要发布的数据字节数,ESP会严格按照这个长度读取后面的二进制内容,完全不受0x00影响。 - 确保
PubPrefix的缓冲区足够容纳你的SerialNumber和DataLength的字符串形式,避免缓冲区溢出。 - 原代码中的
Appendix是用来补全字符串形式的消息结尾,现在用二进制模式不需要这部分,可以直接删除。
内容的提问来源于stack exchange,提问作者M.Navidi
相关产品推荐
相关产品推荐

