QT 5.7中QSerialPort.write()仅调用QThread::sleep()时在macOS生效
QT 5.7 QSerialPort跨平台异常:Windows 7 vs macOS Sierra 调试记录
最近在做自定义串口设备通信开发时,踩了QT 5.7里QSerialPort的跨平台坑——代码在Windows 7上跑起来完全正常,但到了macOS Sierra上就各种异常,前后折腾了差不多20小时才找到可行的解决办法,不过翻遍官方文档还是没搞懂为什么这个修改能生效,在这里分享出来,希望能帮到同路人,也盼着有人能解惑。
Windows 7下正常运行的代码
这是最初在Windows上调试通过的串口初始化代码,打开设备和后续读写都很稳定:
#include <QSerialPort> #include <QSerialPortInfo> void initSerialPort() { QSerialPort serial; serial.setPortName("COM3"); serial.setBaudRate(QSerialPort::Baud9600); serial.setDataBits(QSerialPort::Data8); serial.setParity(QSerialPort::NoParity); serial.setStopBits(QSerialPort::OneStop); serial.setFlowControl(QSerialPort::NoFlowControl); if (serial.open(QIODevice::ReadWrite)) { qDebug() << "串口打开成功"; // 后续读写逻辑 } else { qDebug() << "串口打开失败:" << serial.errorString(); } }
macOS Sierra上的异常表现
把代码直接移植到macOS后,遇到了一堆问题:
- 调用
serial.open(QIODevice::ReadWrite)大概率失败,错误提示无法打开指定的串口设备 - 偶尔侥幸打开成功,后续的读写操作要么丢失数据,要么直接超时无响应
- 尝试调整波特率、流控、奇偶校验等参数,问题依然存在
调试后可行的修改方案
经过无数次试错,最后发现加上两个设置和一个延迟就能解决问题:
#include <QSerialPort> #include <QSerialPortInfo> #include <QThread> void initSerialPort() { QSerialPort serial; serial.setPortName("/dev/tty.usbmodem14101"); // macOS下的串口路径 serial.setBaudRate(QSerialPort::Baud9600); serial.setDataBits(QSerialPort::Data8); serial.setParity(QSerialPort::NoParity); serial.setStopBits(QSerialPort::OneStop); serial.setFlowControl(QSerialPort::NoFlowControl); // 关键修改1:打开串口前手动设置DTR和RTS信号 serial.setDataTerminalReady(true); serial.setRequestToSend(true); if (serial.open(QIODevice::ReadWrite)) { qDebug() << "串口打开成功"; // 关键修改2:打开后延迟100ms再执行读写操作 QThread::msleep(100); // 后续读写逻辑 } else { qDebug() << "串口打开失败:" << serial.errorString(); } }
至今没搞懂的疑问
虽然问题解决了,但还是有几个困惑:
- QT官方文档里完全没提到macOS下需要手动设置DTR/RTS才能正常打开串口,Windows下却不需要这一步
- 打开后的100ms延迟纯粹是调试时偶然试出来的,找不到任何文档说明为什么这一步是必须的
- 为什么同样的串口设备,在两个系统上的驱动层面会有这么大的差异?
内容的提问来源于stack exchange,提问作者Michael Smith
相关产品推荐
相关产品推荐

