C语言UART通信如何通过read/write收发非字符串类十六进制值
串口十六进制值收发解决方案
写入原始十六进制字节的实现逻辑
你要发送的单字节十六进制值(比如0x90)是原始二进制值,不是"0x90"这类字符串形式的ASCII字符,你后续调整为用unsigned char数组存储十六进制字面量的思路是正确的,只需要修正2个错误:
- 不要用
strlen计算数组长度:strlen会遇到0x00就停止计数,你的指令数组里包含0x00元素,会导致实际发送的长度远小于预期,直接填数组的实际长度即可,同作用域下可以用sizeof(str)获取数组总字节数。 - write的正确写法示例:
unsigned char str[13] = {0xA5,0x80,0x90,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBD}; // 第三个参数直接传数组长度,不要用strlen write(fd, str, sizeof(str));
编译告警修复
你遇到的%x格式不匹配告警,原因是str是数组名,本质是指向数组首地址的指针,而%x要求传入整型值,你直接传数组名相当于传了内存地址,自然不符合要求。
如果需要打印发送的十六进制字节,遍历数组逐个输出元素即可,示例:
// 打印所有发送的字节,%02X表示按两位十六进制大写输出,不足位补0 for(int i=0; i<sizeof(str); i++){ printf("%02X ", str[i]); } printf("\n");
read函数读取十六进制值的处理
读取到的串口数据同样是原始二进制字节,不要当作字符串处理,不要主动加'\0'截断,按实际读到的字节数遍历输出即可,示例:
// 建议将buffer也定义为unsigned char类型,避免高字节为1时输出符号位 unsigned char buffer[2000]; int bytes_read = read(fd, buffer, sizeof(buffer)); if (bytes_read > 0) { printf("收到%d字节:", bytes_read); for(int i=0; i<bytes_read; i++){ printf("%02X ", buffer[i]); } printf("\n"); }
修正后的while循环完整示例
// 建议将buffer定义为unsigned char类型 unsigned char buffer[2000]; while(1){ unsigned char str[13] = {0xA5,0x80,0x90,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBD}; // 发送原始字节 write(fd, str, sizeof(str)); // 打印发送的字节 printf("发送13字节:"); for(int i=0; i<sizeof(str); i++){ printf("%02X ", str[i]); } printf("\n"); // 读取返回数据 int bytes_read = read(fd,buffer,sizeof(buffer)); if (bytes_read > 0){ printf("收到%d字节:", bytes_read); for(int i=0; i<bytes_read; i++){ printf("%02X ", buffer[i]); } printf("\n"); } usleep(100000); }
内容的提问来源于stack exchange,提问作者youna
相关产品推荐
相关产品推荐

