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();
}