QT5 QSerialPort接收数据不完整以及乱码解决方案

QSerialPort接收数据不完整

现象:

在设计串口助手时,串口接收到包含中文的字符串时,有时会显示不完整或者乱码。

分析:

接收数据的流程是这样的,
QT5 QSerialPort接收数据不完整以及乱码解决方案
由于串口接收到数据就会触发readyRead信号,从而立即调用槽函数ReadData(),若此时刚好截断在中文字符的前一个字节位,就会导致这个中文显示遗漏并且导致后面接收到的字符串乱码。
比如接收“我是谁”,这段字符串的数据包是[0xce 0xd2 0xca 0xc7 0xcb 0xad],在接收的时候可能会出现在接收到0xca即“是”的前一个字节触发readyRead,从而导致上述现象,多次发送“我是谁”的显示情况
QT5 QSerialPort接收数据不完整以及乱码解决方案

解决方案:

增加一个接收超时确认(做过Stm32项目的应该都知道串口有个idle中断,是一个道理),实际应用时接收到的字符串往往都是一帧一帧的,即两段字符串之间必然是有时间间隔的,而且这个间隔远大于单段字符串里的2个bit之间的间隔(波特率),那么我们可以在接收到readyRead的信号后开启一个定时器来开始计时,等到计时结束再调用readAll()来读取所有数据。若在计时过程中又有readyRead的信号(也就是说还有数据需要接收)就关闭定时器再重新开启。
QT5 QSerialPort接收数据不完整以及乱码解决方案
修改为这样的流程后,同样多次发送“我是谁”的显示情况
QT5 QSerialPort接收数据不完整以及乱码解决方案
相关代码

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 连接信号与槽
    connect(recvDelayTimer,SIGNAL(timeout()),this,SLOT(recvData()));
}
// 接收数据
void MainWindow::recvData()
{
    recvDelayTimer->stop(); //先关闭接收延时计时
    QByteArray data = port->readAll();
    if(!data.isEmpty())
    {
        QString str = ui->textRecvData->toPlainText();
        str += str.fromLocal8Bit(data);
        ui->textRecvData->clear();
        ui->textRecvData->append(str);
        data.clear();
    }
}
// 串口接收数据延时, 延时时间可根据串口波特率计算,大于2个bit间隔
void MainWindow::portRecvDataDelay()
{
    recvDelayTimer->stop();
    recvDelayTimer->start(30);
}
//打开串口后
connect(port,&QSerialPort::readyRead,this,&MainWindow::portRecvDataDelay);
//.h文件
private:
    Ui::MainWindow *ui;
    QSerialPort *port;
    QTimer *recvDelayTimer;

测试的不严谨,参考的朋友请自行测试。

QT5 QSerialPort接收数据不完整以及乱码解决方案QT5 QSerialPort接收数据不完整以及乱码解决方案 风玲一诺 发布了1 篇原创文章 · 获赞 0 · 访问量 16 私信 关注
上一篇:Qt 资料大全


下一篇:QT5.x应用在Mac OS X和Windows平台的发布过程