4. 设备通信基础
在 Qt Quick 设备通信工程中,应用层面对的不是抽象的“数据”,而是一条条真实存在的物理链路与协议栈。串口、网络、蓝牙、USB 是四类最常见的设备通信方式,它们分别对应不同的物理介质、拓扑结构、传输特性和编程接口。理解它们的底层原理与协议差异,是选择通信方案、设计数据模型、排查通信故障的前提。
一、四类通信方式的本质差异
从工程视角看,通信方式的选择取决于三个核心问题:设备之间是点对点还是多对多?数据是流式还是报文式?连接是固定还是可热插拔?串口是典型的点对点、字节流、有线连接;网络通信支持多对多、报文或流、可跨主机;蓝牙是短距离无线、支持点对点与星型拓扑;USB 则是主从结构、支持热插拔与供电。
二、串口通信:最基础的字节流通道
串口(UART)是嵌入式设备最常用的调试与通信接口。它没有时钟线,收发双方依靠预先约定的波特率同步。一帧数据由起始位、5~9 位数据位、可选校验位和停止位组成。Qt 中通过 QSerialPort 类操作串口,核心流程是:枚举端口 → 打开配置 → 读写数据 → 关闭释放。
QSerialPort serial;
serial.setPortName("COM3");
serial.setBaudRate(QSerialPort::Baud115200);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
if (serial.open(QIODevice::ReadWrite)) {
serial.write("AT+RST\r\n");
connect(&serial, &QSerialPort::readyRead, [&](){
QByteArray data = serial.readAll();
qDebug() << "收到:" << data;
});
}
串口编程最常见的误区是“粘包”与“半包”:readyRead 触发时并不保证一次收到完整帧。工程上必须结合帧头、帧尾、长度字段或超时机制做拆包,不能假设一次读取就是一条完整指令。
三、网络通信:TCP 与 UDP 的取舍
网络通信把设备接入 IP 网络,适合远程监控与多设备汇聚。TCP 提供面向连接的可靠字节流,适合配置下发、固件升级等不能丢数据的场景;UDP 无连接、开销小、延迟低,适合高频遥测与实时控制。Qt 中分别对应 QTcpSocket 与 QUdpSocket。
| 对比项 | TCP | UDP |
|---|---|---|
| 连接方式 | 面向连接,三次握手 | 无连接,直接发送 |
| 可靠性 | 确认重传,有序到达 | 不保证到达与顺序 |
| 数据边界 | 字节流,需自行拆包 | 保留报文边界 |
| 延迟 | 较高 | 低 |
| 适用场景 | 配置、升级、文件 | 遥测、心跳、广播 |
四、蓝牙与 USB:短距无线与主从有线
蓝牙低功耗(BLE)采用 GAP 广播/扫描/连接与 GATT 服务/特征模型。设备先广播,中心设备扫描后发起连接,再通过服务 UUID 和特征 UUID 读写数据。Qt 提供 QLowEnergyController、QLowEnergyService 等类完成这一流程。BLE 的典型特征是“小数据、低功耗、间歇传输”,不适合大流量持续通信。
USB 是严格的主从结构:主机负责枚举、分配地址、发起所有传输,设备只能被动响应。USB 定义了四种传输类型——控制传输用于枚举与配置,中断传输用于 HID 键鼠,批量传输用于大容量数据,等时传输用于音视频。Qt 官方模块对 USB 支持有限,工程中常借助 libusb 或平台原生接口封装。
五、场景案例与排障复盘
假设要开发一个 Qt Quick 环境监测终端,同时接入温湿度传感器(串口)、网关(TCP)、手环(BLE)和摄像头(USB)。合理的架构是:为每类通信封装独立的 C++ 后端类,通过 Q_PROPERTY 和信号槽暴露给 QML,QML 只负责展示与交互,不直接触碰底层句柄。
掌握这四类通信的原理与协议差异,才能在 Qt Quick 项目中做出正确的技术选型,并为后续的异步数据模型、线程处理与错误恢复打下基础。