1. 串口通信中的进制转换:为什么它如此重要?
如果你刚开始接触QT串口编程,可能会觉得进制转换是个有点绕、有点枯燥的话题。不就是数字换种写法嘛,能有多复杂?但等你真正上手去和设备“对话”时,十有八九会在这里栽跟头。我刚开始做智能硬件开发那会儿,就吃过不少亏。比如,我写了个程序向一个温湿度传感器发送查询指令,指令手册上明明白白写着要发送 0x01 0x03 0x00 0x00 0x00 0x02 这么一串十六进制数据。我当时想当然地直接在代码里写了个字符串 "010300000002" 发过去,结果设备毫无反应,调试了半天才发现,我发送的其实是这些字符的ASCII码,而不是真正的十六进制字节流。这个教训让我深刻理解到,在串口通信这个“字节为王”的世界里,你脑子里想的数字(十进制)、代码里写的数字(各种进制)、以及最终在物理线缆上流动的电流(二进制字节),这三者之间的转换,是必须跨过去的一道坎。
串口通信的本质是字节流的传输。无论是RS-232、RS-485还是USB虚拟串口,底层传递的都是一个个8位的字节(Byte)。而我们在编程时,为了方便理解和处理,会使用十进制整数、十六进制字符串等不同的表现形式。QByteArray 在QT中扮演的角色,就是一个高效的字节数组容器,它是连接我们高级逻辑与底层字节流的关键桥梁。你想想看,设备指令通常是十六进制格式的,比如 0xAA 0x55 表示握手信号;而从传感器读回来的数据,可能是一个表示温度的16位整数,需要从两个字节里解析出来。这个过程里,进制转换无处不在。
所以,今天我们不谈深奥的理论,就聚焦在实战上。我会把我这些年用QT做串口开发时,关于QByteArray和进制转换那些最常用、也最容易出错的技巧,掰开揉碎了讲给你听。目标很简单:让你看完就能用,用了就能对,彻底搞定串口数据打包和解包这个核心环节。
2. 核心武器库:QByteArray与进制转换方法全解析
工欲善其事,必先利其器。在QT的世界里处理进制转换,主要依赖两个核心类:QByteArray 和 QString。它们提供了丰富的方法,但用法上有些细微差别,用错了地方就会导致数据错误。
2.1 从数字到字节:QByteArray::number() 的妙用
这是最直接、最常用的一招。QByteArray::number() 静态方法,它的任务是把一个整数(int, long, uint等)转换成指定进制的字符串表示,并以QByteArray的形式返回。
int temperature = 25; // 摄氏25度
// 将十进制整数25,转换为十六进制字符串(小写),结果QByteArray里存放的是字符'1'和'9'
QByteArray hexBytes = QByteArray::number(temperature, 16);
qDebug() << hexBytes; // 输出: "19"
注意,这里的输出是 "19",它是一个长度为2的字节数组,里面存的是字符 '1' 和 '9' 的ASCII码,并不是数值 0x19。这是新手最容易混淆的点!如果你想得到真正的字节值 0x19,需要再用 QByteArray::fromHex() 进行一次转换。
QByteArray realHexValue = QByteArray::fromHex(hexBytes);
qDebug() << realHexValue.toHex(); // 输出: "19"
// 此时 realHexValue 内部存储的是一个字节,其值为 0x19
那有没有一步到位的方法呢?对于单个字节,其实有更简单的办法。QByteArray的 append() 方法可以直接接受一个 char 或 uchar,而整型赋值给 char 时,存储的就是其低8位的值。
QByteArray cmd;
int dataByte = 0x1A;
cmd.append(static_cast<char>(dataByte)); // 直接追加字节 0x1A
qDebug() << cmd.toHex(); // 输出: "1a"
这种方法在组装固定字节的命令时非常高效。但当你需要转换的数字可能超过255(一个字节的范围)时,或者需要生成十六进制字符串形式时,QByteArray::number() 配合 fromHex() 的组合拳就更可靠。
2.2 字符串的进制转换:QString::number() 与 toInt/toUInt
QString在处理进制转换上同样强大,而且它在处理用户输入或显示数据时更常用。QString::number() 和 QByteArray::number


228

被折叠的 条评论
为什么被折叠?



