【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();
}
相关推荐
薛定谔的猫喵喵6 小时前
基于C++ Qt的唐代诗歌查询系统设计与实现
c++·qt·sqlite
枫叶丹46 小时前
【Qt开发】Qt界面优化(一)-> Qt样式表(QSS) 背景介绍
开发语言·前端·qt·系统架构
明月醉窗台18 小时前
qt使用笔记六之 Qt Creator、Qt Widgets、Qt Quick 详细解析
开发语言·笔记·qt
R_.L21 小时前
【QT】常用控件(按钮类控件、显示类控件、输入类控件、多元素控件、容器类控件、布局管理器)
开发语言·qt
无小道1 天前
Qt——常用控件
开发语言·qt
初次见面我叫泰隆1 天前
Qt——5、Qt系统相关
开发语言·qt·客户端开发
牵牛老人1 天前
【Qt 开发后台服务避坑指南:从库存管理系统开发出现的问题来看后台开发常见问题与解决方案】
开发语言·qt·系统架构
xmRao1 天前
Qt+FFmpeg 实现 PCM 音频转 AAC 编码
qt·ffmpeg·pcm
xmRao1 天前
Qt+FFmpeg 实现录音程序(pcm转wav)
qt·ffmpeg
喜欢喝果茶.1 天前
QOverload<参数列表>::of(&函数名)信号槽
开发语言·qt