C++串口发送0x00失败求助:无法写入十六进制0x00
串口发送0x00失败的问题排查与解决
先还原下你的问题场景:
我需要向串口发送作为设备地址的0x00,但尝试后并未成功写入。我的发送缓冲区定义如下:
const char bufferTX[11] = "\xA5\x00\x05\x10\x00\x00\xD0\x01\x00\x00";
以下是我的串口发送函数:for(int k = 0; k<sizeof(bufferTX); k++) { RS232_cputs(cport_nr, &bufferTX[k]); printf("sent: %c\n", bufferTX[k]); }
问题根源分析
你遇到的核心问题有两个:
RS232_cputs函数的字符串特性RS232_cputs这类带cputs后缀的函数,本质是发送字符串的接口——它会从传入的指针位置开始发送字符,直到遇到'\0'(也就是0x00)就立即停止。而你的缓冲区里第2个字节就是0x00,这就导致:- 第一次调用
RS232_cputs时,只发送了\xA5就碰到0x00,直接停止; - 后续调用时,指针指向的就是0x00,函数直接返回,什么都发不出去。
这就是0x00没发送成功、整个数据包都不对的关键原因。
- 第一次调用
缓冲区初始化的额外字节
你用字符串字面量"\xA5\x00..."初始化char数组时,编译器会自动在末尾添加一个'\0'作为字符串结束符。所以sizeof(bufferTX)得到的是11,但你实际要发送的是前面10个字节,最后那个自动添加的0x00属于冗余数据。
解决方案
针对这两个问题,给你两种可行的修复方式:
方式一:改用单字节发送函数
如果你的串口库提供了单字节发送接口(比如RS232_sendbyte这类),直接用它发送每个字节,完全避开字符串结束符的问题:
// 用unsigned char定义缓冲区更合理,避免字符符号扩展问题 const unsigned char bufferTX[] = {0xA5, 0x00, 0x05, 0x10, 0x00, 0x00, 0xD0, 0x01, 0x00, 0x00}; for(int k = 0; k < sizeof(bufferTX); k++) { RS232_sendbyte(cport_nr, bufferTX[k]); // 用十六进制打印更直观,避免0x00显示为空白 printf("sent: 0x%02X\n", bufferTX[k]); }
方式二:适配RS232_cputs发送单字节
如果只能用RS232_cputs,可以把每个字节包装成一个长度为1的临时字符串(手动添加结束符),强制让函数发送单个字节:
const unsigned char bufferTX[] = {0xA5, 0x00, 0x05, 0x10, 0x00, 0x00, 0xD0, 0x01, 0x00, 0x00}; for(int k = 0; k < sizeof(bufferTX); k++) { char temp[2] = {bufferTX[k], '\0'}; // 手动添加字符串结束符 RS232_cputs(cport_nr, temp); printf("sent: 0x%02X\n", bufferTX[k]); }
另外注意:原来的printf("sent: %c\n", bufferTX[k])打印0x00时会显示为空白,改成十六进制打印能清晰看到每个发送的字节值,方便调试。
内容的提问来源于stack exchange,提问作者Sukru
相关产品推荐
相关产品推荐

