【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();
}
相关推荐
桥田智能1 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G1 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt
森G1 天前
77、线程池原理和实现------服务器源码解析----云视频服务项目
服务器·c++·qt
森G1 天前
71、打包发布---------打包发布
c++·qt
初圣魔门首席弟子1 天前
Node.js 详细介绍(知识库版)
windows·qt·node.js·知识库
C++ 老炮儿的技术栈1 天前
Qt工控实战:自研机器人TCP长连接客户端(粘包处理+心跳保活+自动重连完整源码解析)
qt·tcp/ip·机器人
郝学胜-神的一滴1 天前
CMake 019:程序生成与清理全解析
开发语言·c++·qt·程序人生·软件构建·cmake
森G1 天前
76、仿ASIO实现的Linux c++服务器------服务器源码解析----云视频服务项目
c++·qt
superkcl20221 天前
【QT Thread】
c++·qt
CodeKwang1 天前
Windows 环境 OCCT 8.0 编译构建及与 Qt6 项目集成
windows·qt·opencascade