IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> QT连载1:readyRead()函数,数据分包不完整解决办法 -> 正文阅读

[嵌入式]QT连载1:readyRead()函数,数据分包不完整解决办法

一,问题

? ? 网上的小伙伴遇到串口接收的函数一般是下列函数,QT中串口接收函数:

//=============串口定义==============//
    connect(&mSerial,SIGNAL(readyRead()),this,SLOT(SerialPort_Readyread()));

? ? 此函数存在问题:接收数据后,不定时抛出,也就是说串口中有数据就会执行后面的槽函数,然后用下面函数接收:

void MainWindow::SerialPort_Readyread()
{
    QByteArray recvData = mSerial.readAll();
}

? ? 这样接收到的recvData数据就会分包。网上遇到很多说解决这个问题的,但是最后总是会有问题。前面文章中,我也采用的一种方法就是加报头和报尾。但是这个方法也会出现丢数据的情况,所以之后做了很多实验,怎么规避这种丢包的问题。

二,思路

? ? 程序嘛,就是让修改的,不能按照别人给的来。所以换了一种做法,采用下面的方法。

? ? 1.槽函数不采用串口数据触发

? ? 采用下列函数:

connect(&m_timer_test, &QTimer::timeout, this, &MainWindow::handleTimeout_test);

void MainWindow::handleTimeout_test()
{
    nRxAllLength = mSerial.bytesAvailable();

    recvDataAD = mSerial.readAll();

    m_timer_test.stop();
}

注:其中的定时器为发送指令时启动,延时一定时间后接收。标准的MODBUS协议。

? ? 串口数据采用定时器槽函数接收,先判断接收到数据个数,再将数据放进recvDataAD数组里。对于需要定时接收的场合可能不太适用,但是可以作为一个思路。当然如果底层单片机定时发送一定的数据,需要单片机先给一个指令,之后延时一定时间后接收主要主要数据。

2.测试方法

? ? 采用波特率19200和38400,指令下发取单片机一定的数据,修改定时器时间,测试定时器时间最短多少能接收到全部一帧数据。

? ? ?举例:波特率19200,设定取单片机字节数45个,改变时间设定:60ms后执行槽函数。此时采集数量一直稳定在45个。证明给单片机下发取数45个指令后,返回45个,串口完全接收,并可以一次弹出。即:QT串口接收45个byte(uint_8),60ms可以接收到完整的数据包。按照这种思路,减小定时器时间。当定时器时间达到47ms时,接收到的数据不再是稳定的45个,会出现其他个数,说明串口已经不能完整的接收到数据包。所以时间定在48ms。由此此处结论:QT接收45个字节时,至少需要间隔48ms,才能得到完整数据包,当然时间越长约好。

?三,测试结果

? ? (1)?测试结果如下:

波特率:19200
采集数量(单位u8)最小时间(单位ms)
4548
8564
12581
165107
205127
285173

? ? 波特率为19200时,QT接收完整数据需要的时间。

? ? ?其中:蓝色曲线为采集数量对应最小间隔时间,红色曲线为最小间隔时间在19200波特率下能传输的最大数据量。

? ? 可得出:(1)数据量越大,需要间隔时间越长,并且数据量和间隔时间成线性正比。(2)一定时间间隔内,传输数据与最大传输数据个数比例大概是2:1。

?(2)?测试结果如下:

波特率:38400
采集数量(单位u8)最小时间(单位ms)
4520
8534
12548
16564
20578
28599

? ? 波特率为38400时,QT接收完整数据需要的时间。

?? ? ?其中:蓝色曲线为采集数量对应最小间隔时间,红色曲线为最小间隔时间在38400波特率下能传输的最大数据量。

? ? 同样可得出:(1)数据量越大,需要间隔时间越长,并且数据量和间隔时间成线性正比。(2)一定时间间隔内,传输数据与最大传输数据个数比例大概是4:1。

? ? ?波特率19200和波特率38400不同的地方在于接收最大传输数据比例,相同的时间内,波特率增加一倍,传输数据和最大传输数据量比例减小一倍。

? ? 所以初步得出结论:当波特率增加时,传输一定数据需要的间隔时间是线性减小。

四,结论

? ? (1)QT串口数据不丢包的方法是:延长一定时间,执行槽函数,取数据。如果是QT下发指令取数据,则需延长一定时间最小时间T后,方可取得发送包的完整数据。如果是单片机固定时间上传数据,则需延长时间2*T,方可取得发送包的完整数据(无法判断什么时候发送报文,没有办法准确开始定时器,所以只能间隔时间t后,可得到完整数据包)。

? ? (2)QT串口接收数据量一定情况下,波特率越高越好,需要间隔的时间越短。但是相对于波特率能传输的最大数量来说,利用率是下降的。

? ? (3)不能一直使用网上说的QT函数,没事就自己改改,或许还能找到解决办法。

五,存在问题

? ? (1)仅仅使用了两种波特率得出结论,可能对于进一步高的波特率不太实用,但是时间有限,工作之余只能草率得出结论,感兴趣的小伙伴可以试试更高波特率的是不是符合上述结论,如果不一致还请相信告诉下,我再进一步验证。

? ? (2)底层单片机执行程序需要一定时间,下发指令和回复指令需要时间,已经尽量避免,但是肯定还会有执行时间,延长了QT串口的接收时间。

? ? (3)电脑执行时间没有考虑,电脑越好,应该QT执行的越快,这个没办法,公司只有一台电脑,没有办法做出结论。电脑速率应该也会影响最终结果。如果小伙伴重复试验,结果相差有点,可以参考这个问题。

六,展望

? ? 以后有时间了,可以做下全波特率的执行时间,给出一张完整的接收时间表,其中包含波特率,数据数量,需要时间参数。如果有小伙伴做出来也给个链接哈,表示衷心感谢!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-07-30 12:54:10  更:2021-07-30 12:54:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/1 14:51:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码