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

Qt中通过SerialPort串口发送十六进制数据及代码异常排查

问题原因

你代码里的逻辑错误直接导致数据无法正确发送,核心问题有三个:

  • 发送逻辑顺序写反:你第一次调用serialPort->write()时,send_data是空数组,要发送的0xAA是在write执行完之后才追加到数组里,第一次发送根本没有带上目标字节。后续第二次调用write虽然追加了0xAA,但没有做发送状态校验和等待,数据大概率滞留在缓冲区没有实际发出。
  • 长度计算完全错误:sizeof(send_data)计算的是QByteArray类对象本身占用的栈内存大小(固定值,和数组里存了多少有效数据无关),不是待发送数据的实际长度,QByteArray存储的有效数据长度必须调用.size()方法获取。
  • 异步发送丢数据:Qt串口的write()方法是异步接口,调用后数据只是被放到了发送缓冲区,不会立刻从串口发出,如果write之后马上执行关闭串口、清空缓冲区等操作,缓冲区里的数据会直接丢失,对端自然收不到。
正确的十六进制数据发送实现

实现步骤

  1. 先把所有待发送的十六进制字节按顺序填充到QByteArray中,所有数据填充完成后再调用write接口
  2. 传入write接口的数据长度参数,使用QByteArray的.size()方法获取,禁止用sizeof计算容器类的有效数据长度
  3. write调用后,调用waitForBytesWritten()等待数据实际从串口发出,或者绑定bytesWritten信号确认发送状态,避免缓冲区数据丢失
  4. 提前确认串口配置(波特率、数据位、停止位、校验位、流控)和对端完全匹配,参数不匹配会导致对端收不到有效数据或解析乱码

参考代码

QByteArray send_data;
// 所有待发送十六进制数据必须在write调用前填充完成
send_data += static_cast<char>(0xAA);
// 多字节数据按顺序追加即可,示例:
// send_data += static_cast<char>(0x55);
// send_data += static_cast<char>(0x01);

if(serialPort->isWritable())
{
    qDebug() << "串口可写,开始发送数据";
    qint64 writeRet = serialPort->write(send_data);
    if(writeRet == -1)
    {
        qDebug() << "发送出错:" << serialPort->errorString();
        return;
    }
    // 等待数据实际写入串口,超时时间设置1000ms即可覆盖绝大多数场景
    if(!serialPort->waitForBytesWritten(1000))
    {
        qDebug() << "发送超时:" << serialPort->errorString();
    }
    else
    {
        qDebug() << "发送完成,实际发送字节数:" << writeRet;
    }
}

额外注意事项

  • 连续发送多帧数据时,不要无间隔连续调用write,等上一帧发送完成(waitForBytesWritten返回成功或者收到bytesWritten信号)再发送下一帧,避免缓冲区溢出导致粘包、丢包
  • 如果要发送的十六进制数据是字符串格式(比如"AA 55 01"),可以直接调用QByteArray::fromHex()方法把十六进制字符串转成字节数组,不需要自己逐字节强转

内容的提问来源于stack exchange,提问作者sam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:48:28