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

1. 现象

//正常数据
Read:  "12345678901234567890123456789012345678901234567890"		

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

2. 问题代码

#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. 修改后代码

#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. TCP协议是安全的吗?

    2024-03-18 00:16:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-18 00:16:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-18 00:16:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-18 00:16:03       20 阅读

热门阅读

  1. ThreadLocal-案例编码实战

    2024-03-18 00:16:03       19 阅读
  2. 17个工作必备的Python自动化代码分享(上篇)

    2024-03-18 00:16:03       19 阅读
  3. clickhouse sql语句

    2024-03-18 00:16:03       17 阅读
  4. Leetcode64. 最小路径和

    2024-03-18 00:16:03       18 阅读
  5. 【MATLAB函数】三点法定位+权重

    2024-03-18 00:16:03       19 阅读
  6. 【Linux】在 Linux 上安装 Zig 编译环境

    2024-03-18 00:16:03       21 阅读
  7. 2024.2.26校招 实习 内推 面经

    2024-03-18 00:16:03       19 阅读
  8. R语言【ClusterR】——KMeans_rcpp()

    2024-03-18 00:16:03       18 阅读
  9. 在 emacs 中如何将窗口的垂直分割改为水平分割

    2024-03-18 00:16:03       22 阅读
  10. ActiveMQ

    ActiveMQ

    2024-03-18 00:16:03      17 阅读
  11. 2024.03.17 校招 实习 内推 面经

    2024-03-18 00:16:03       18 阅读
  12. CSS中那些你不知道的选择器

    2024-03-18 00:16:03       22 阅读