QT QML QSerialPort需先开Putty/终端才能接收数据求助
串口通信异常排查求助
我开发了一款通过串口与外部设备通信的应用,使用TeraTerm可正常接收数据,在QT中能正常发送并解析数据,但如果不先打开Putty/TeraTerm,QT虽能找到并打开串口,却无法触发readyRead()信号槽,仅能发送数据无法接收。我怀疑是串口初始化问题,附上相关代码及调试日志,尝试简化代码、调整串口参数后问题仍存在,请求帮助排查原因及解决办法。
相关代码
类定义
class C_SerialPortManager : public QObject { Q_OBJECT public: explicit C_SerialPortManager(QObject *parent = nullptr); ... signals: private slots: void readSerial(); private: QSerialPort *comPort; ... };
初始化函数
C_SerialPortManager::C_SerialPortManager(QObject *parent) : QObject{parent} { comPort = new QSerialPort(parent); qDebug() << (serialPortInit(comPort) == true ? "init Success" : " init Failure"); } bool C_SerialPortManager::serialPortInit(QSerialPort * comPort) { bool BMS_IS_AVAILIABLE = false; // 遍历所有可用串口 foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) { BMS_IS_AVAILIABLE = true; // 标记端口可用 BMS_PORT_NAME = serialPortInfo.portName(); } if(BMS_IS_AVAILIABLE) { qDebug() << "Found the port : " << BMS_PORT_NAME; comPort->setPortName(BMS_PORT_NAME); comPort->setBaudRate(QSerialPort::Baud115200); comPort->setDataBits(QSerialPort::Data8); comPort->setFlowControl(QSerialPort::NoFlowControl); comPort->setParity(QSerialPort::NoParity); comPort->setStopBits(QSerialPort::OneStop); if (!(comPort->open(QIODevice::ReadWrite))) { qDebug() << "Error String : "<< comPort->errorString(); return(false); } qDebug() << "Connect Signal Slot :" << QObject::connect(comPort, SIGNAL(readyRead()), this, SLOT(readSerial())); } else { qDebug() << "Couldn't find the correct port."; timedOutSerial(); return(false); } connect(&timerTimeoutSerial, &QTimer::timeout, [&](){timedOutSerial();}); timerTimeoutSerial.start(500); return(true); }
调试日志
未先打开Putty/TeraTerm时
Found the port : "COM6" Connect Signal Slot : true init Success
先打开Putty/TeraTerm时
Found the port : "COM6" Connect Signal Slot : true init Success
排查建议及解决办法
- 检查硬件流控/握手信号:部分串口设备需要DTR/RTS信号触发数据输出,Putty/TeraTerm打开串口时会自动激活这些信号,而Qt默认可能未设置。可以在打开串口后添加:
comPort->setDataTerminalReady(true); comPort->setRequestToSend(true); - 修正串口选择逻辑:当前遍历所有串口时,最后一个端口会覆盖之前的结果,可能误选非目标设备端口。建议通过设备PID/VID或描述符精准筛选:
foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) { // 替换为你的设备实际PID和VID if(serialPortInfo.vendorIdentifier() == 0xXXXX && serialPortInfo.productIdentifier() == 0xXXXX) { BMS_IS_AVAILIABLE = true; BMS_PORT_NAME = serialPortInfo.portName(); break; // 找到目标端口后终止遍历 } } - 调整信号连接时机:建议在打开串口前就连接
readyRead信号,避免串口打开后数据已到达但信号未绑定的情况:// 先绑定信号槽 QObject::connect(comPort, SIGNAL(readyRead()), this, SLOT(readSerial())); // 再打开串口 if (!(comPort->open(QIODevice::ReadWrite))) { // 错误处理 } - 清空串口缓存:打开串口后手动清空接收缓存,避免残留数据影响:
comPort->open(QIODevice::ReadWrite); comPort->clear(); // 清空接收和发送缓存 - 使用Qt新信号槽语法:替换旧的SIGNAL/SLOT宏,避免语法匹配问题:
connect(comPort, &QSerialPort::readyRead, this, &C_SerialPortManager::readSerial);
内容的提问来源于stack exchange,提问作者Clem
相关产品推荐
相关产品推荐

