You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 05:30:12