【Qt】QT串口接收一帧数据有时候不完整,需要接收两次

1. 现象

c 复制代码
//正常数据
Read:  "12345678901234567890123456789012345678901234567890"		

//异常数据
Read:  "12345678901234567890123456789012"						
Read:  "345678901234567890"

2. 问题代码

c 复制代码
#include "serialbase.h"

QString serialNameLinux = "/dev/ttyS4";

SerialBase::SerialBase(QObject *parent)
    : QObject{parent}
{
    // 设置串口号
    SerialPort.setPortName(serialNameLinux);
    // 打开串口
    SerialPort.open(QIODevice::ReadWrite);
    // 设置波特率
    SerialPort.setBaudRate(115200);
    //设置数据位数
    SerialPort.setDataBits(QSerialPort::Data8);
    //设置奇偶校验
    SerialPort.setParity(QSerialPort::NoParity);
    // 设置流控制
    SerialPort.setFlowControl(QSerialPort::NoFlowControl);
    //设置停止位
    SerialPort.setStopBits(QSerialPort::OneStop);
}

SerialBase::~SerialBase()
{
    SerialPort.close();
}


void SerialBase::serialRx(void)
{
    SerialPort.waitForReadyRead(10);
    QByteArray rxBuff = SerialPort.readAll();

    if(rxBuff.length() > 0)
        qDebug() << "Read: " << rxBuff;
}

//周期性调用这个函数
void SerialBase::serialReadTest()
{
    serialRx();
}

3. 问题分析

  • 问题出在SerialPort.waitForReadyRead(10);这行代码,手册中的说明如下:
  • 超时时间到达之前接收到数据,则发送信号readyRead(),超时时间到达的时候,返回true
  • 注意,如果超时时间到达时,数据帧没有接收完,就出现了如上问题。
  • 超时时间到达时还没有数据返回,则直接返回false

4. 解决思路

接收到readyRead()信号后,再调用waitForReadyRead()等待一段时间。

4. 修改后代码

c 复制代码
#include "serialbase.h"

QString serialNameLinux = "/dev/ttyS4";

SerialBase::SerialBase(QObject *parent)
    : QObject{parent}
{
    // 设置串口号
    SerialPort.setPortName(serialNameLinux);
    // 打开串口
    SerialPort.open(QIODevice::ReadWrite);
    // 设置波特率
    SerialPort.setBaudRate(115200);
    //设置数据位数
    SerialPort.setDataBits(QSerialPort::Data8);
    //设置奇偶校验
    SerialPort.setParity(QSerialPort::NoParity);
    // 设置流控制
    SerialPort.setFlowControl(QSerialPort::NoFlowControl);
    //设置停止位
    SerialPort.setStopBits(QSerialPort::OneStop);

    //接收到数据后,再等待一段时间
    connect(&SerialPort, SIGNAL(readyRead()), this, SLOT(waitNextMs()));
}

SerialBase::~SerialBase()
{
    SerialPort.close();
}

void SerialBase::serialRx(void)
{
    SerialPort.waitForReadyRead(10);
    QByteArray rxBuff = SerialPort.readAll();

    if(rxBuff.length() > 0)
        qDebug() << "Read: " << rxBuff;
}

void SerialBase::waitNextMs()
{
    SerialPort.waitForReadyRead(20);
    qDebug() << "wait";
}

void SerialBase::serialReadTest()
{
    serialRx();
}
相关推荐
秋月的私语2 分钟前
遥感影像拼接线优化工具:基于Qt+GDAL+OpenCV的从零到一实践
开发语言·qt·opencv
姓刘的哦21 分钟前
Qt自定义控件
开发语言·qt
AlanW1 小时前
Qt Model/View 框架完全指南:从入门到性能优化
qt
艾莉丝努力练剑4 小时前
【QT】Qt常用控件与布局管理深度解析:从原理到实践的架构思考
linux·运维·服务器·开发语言·网络·qt·架构
Z文的博客4 小时前
嵌入式 ARM 设备交叉编译 mosquitto 2.0.20 (完整 TLS 支持) 详细教程 TRAE全程辅助,没敲一行代码
qt·mqtt·嵌入式·ai编程·mosquitto·嵌入式linux·trae
特立独行的猫a4 小时前
HarmonyOS 鸿蒙PC端 Qt 应用开发:第三方 Qt 开源软件移植指南
qt·harmonyos·鸿蒙·鸿蒙pc
C++ 老炮儿的技术栈14 小时前
GCC编译时无法向/tmp 目录写入临时汇编文件,因为设备空间不足,解决
linux·运维·开发语言·汇编·c++·git·qt
米优18 小时前
qt+vlc实现国标客户端测试工具
qt·gb28181·vlc
米优19 小时前
qt+vlc实现解码h264/h265裸码流播放
开发语言·qt·vlc
小小码农Come on19 小时前
QT面试题总结
开发语言·qt