0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一文知道串口通信的帧同步问题

电子工程师 作者:工程师a 2018-06-03 04:26 次阅读

封装STM32串口的底层时,遇到了串口帧同步的问题。虽然以前也遇到类似场合,写出来的代码基本能够解决问题,但是在逻辑上总是不能彻底的解释一些细节。

当前的工作环境:

由于代码想用在一个简单的PID闭环上,做在线的参数整定。假设当前PID解算周期是1ms,即每1ms,做一次串口的收包,解包,Pid解算,数据采集,然后打包,发包。也就是说是固定步长的解包。

串口的方案是开启收发的DMA以及DMA的中断。(坚决不考虑直接使用串口中断。一个字节中断一次太费资源)。DMA数组作为串口的FIFO队列(并不是真正意义上的队列)。

当前的需求:

1、时间节拍到来时,检查是否有收到数据。没有则跳出,有则进入下一步

2、检查数据中的包格式,比如包头是否正确,帧长度是否对齐,CRC(目前还没有做进去)等

3、包格式检查出错误,回包时添加标志位,声明包格式错误请求重发。包格式没有错误则进行解包并设置对应的寄存器和赋值。

4、具有合理的接收缓冲区,大于缓冲区的数据进行放弃。

5、能够及时检测出丢字节,多字节等帧长度出错的问题。

几套尝试过的方案:

1、DMA数组的长度和帧长度相等。

触发条件:DMA计数值减到0(即已经收满一个帧的长度的数据)产生DMA中断,将触发标志位写1。PC机上可以通过开启一个线程监视缓冲区数量实现。

解包操作:设置共用体,其中结构体为帧协议,同时公用一个u8 数组作为DMA数组。判断触发条件,若满足,读取共用体中的包头包尾,若正确,继续读取成员,解包赋值。

缓冲机制:无。DMA设置为normal模式,计数减到0后即停止。有新的数据到来也不会被传入数组。PC机上可以手动关闭串口。

报错机制:

帧错位:在包头检查中会发现,舍弃当前帧,设置重发标志位请求重发。

字节缺失:字节缺失的帧发送完成后不会满足触发条件,等到第2帧的数据的前几个字节填满缺失的帧后,触发解包操作。在检查包围的时候,报错响应。舍弃字节缺失帧,但是难以保证字节缺失帧的后几帧能顺利接收。而且出错和报错响应不同步。即报错响应出现在错误的下一帧。

字节超出:字节超出的帧会及时响应,并且由于包尾错误,会立即响应报错并请求重发。

解包过快:不会出现解包速度大于收包速度。因为数据满一个帧长度才会解包。

2、DMA数组指向元素类型为帧结构体的链表

触发条件:DMA计数值减到0(即已经收满一个帧的长度的数据)产生DMA中断,DMA中断中对List进行Push_back操作,增加一个element,然后将DMA的内存地址指向新的element的首地址。触发条件是List的size大于1(在没有收到任何报文之前,得有一个空element用于放置马上要到来的报文);

解包操作:检查List第1个元素的包头包尾,如果正确,读取成员解包赋值,然后对List进行pop_front,直到list的size等于1.

缓冲机制:链表天然的缓冲机制,唯一担心的是堆溢出,可以设置一个上限,在中断里判断。

报错机制:

帧错位:在包头检查中会发现,但是需要丢弃缓冲区内错位帧之后所有的帧。因为后边的必然都错位了。

字节缺失:第2帧到来时,检查包尾时发现。同样存在报错响应不同步的问题。

字节超出:报错同步响应。丢弃缓冲区中所有帧

解包过快:不存在这个问题。理由同 方式1.

3、DMA数组指向多倍于帧长度的数组首地址

触发条件:缓冲队列非空。触发响应后,立即将缓冲队列memcpy到临时数组进行解包。同时清空队列。

解包操作:在临时数组中搜索包头的第1个字节,一单满足,立即检查:包头第2字节,包尾是否在缓冲区长度内,包尾是否正确。如果4个条件均满足,立即开始解包赋值。完成后重复上一步,在数组中搜索第2个包头。直到最后在缓冲区末端,残留帧的前一部分,舍弃该无尾帧。

缓冲机制:由缓冲队列作为缓冲。

报错机制:

帧错位:在临时数组中不存在帧错位的概念,帧错位完全可以被正确解包。

字节缺失:在解包步骤中被检测到包尾有误,则请求重发。而且能同步响应。

字节超出:同字节缺失

解包过快:由于触发方式为缓冲队列非空。如果查询触发条件时,恰好接收了部分帧,则仍然能满足触发条件。那么此时这个接收了一部分的帧会作为字节缺失的帧被舍弃并进行报错

小结:

三种方式对比下来,第3种方式有着较优越的性能,而且能够很好地移植到PC机上实现。但是对于解包过快的问题,仍然需要讨论。

字节缺失同步响应和解包过快的矛盾:

问题可以被化简为:一个10字节的帧,解包时,如果包里只有9个字节,那这一帧到底是没发完还是字节缺失。

如果使用“已收到大于10个字节的数据”作为解包触发条件,那么解包时永远有10个字节,判断最后一个字节是否是包尾,即可。但是字节缺失永远只能在下一帧响应。

如果使用“缓冲区数据多于0”作为解包触发条件,虽然字节缺失能立即被响应,但是也有可能将未发完的帧误判。

因此需要针对当前的应用进行分析。目前对于单片机的帧率和帧长度为:

波特率:115200

发送帧率:5f/s

发送帧长:20 Bytes

接收帧检测周期:1ms

接收帧长度:10 Bytes

传送1Byte数据,由于没有校验位,1个停止位,因此需要10bits。

那么传输速率为11520B/s(约11KB/S),即传输1Byte需要86.8us(约0.1ms)。

发送帧每一帧20Bytes,需要1.736ms(约2ms)

接收帧每一帧10Bytes,需要0.858ms(约1ms)

因此对于当前的情况下单片机的接收条件,1ms解包一次,完全不需要缓冲区,但是却有很大可能发生在帧截断。

因此应该采用“已收到等于帧长度个字节的数据”作为触发条件。放弃字节缺失帧的同步响应。

但是对于PC机端,如果同样为1ms间隔检测触发条件,接收帧的时常变为1.736毫秒,那么一个间隔内是必然收不满1帧的。

因此同样可以采用“已收到等于帧长度个字节的数据”作为触发条件。放弃字节缺失帧的同步响应。

但是对于Qt上的串口类,现在还没有摸清他的工作原理,尚无法讨论何种方法比较合适。

/**********************************11月1日更新分割线****************************************/

一个能够提高缺字节帧报错响应速度的方案:

判断帧是丢字节还是未发完的区分方式其实是在时间上。

比如之前提到的115200波特率,20Bytes的帧,其传送时间应该小于2ms。

因此,当:接收缓冲区有数据,单数据未到达20Bytes时,若这种状态维持超过2ms,则说明传输已经完成,缺字节。

而程序本身的step timer已经有了计时的功能。因此,实现方式如下。

声明一个标志位1:FIFO队列有数据但不满帧长度。

声明一个计数器1:标志位1的计数。

当FIFO队列数据从0跳变到1时,set标志位1。

CheckMailBox时,标志位1已置位,则将计数器1的值加1。

由于20Bytes的帧在2ms内应该发送完。而解算周期为1ms。

故,当计数器1的值大于2时,如果FIFO队列数据长度仍然没有达到帧长度,说明该包有数据丢失。set报错标志位。

即可检测出丢字节的帧。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 帧同步
    +关注

    关注

    0

    文章

    13

    浏览量

    9381
  • 串口通信
    +关注

    关注

    34

    文章

    1609

    浏览量

    55409
收藏 人收藏

    评论

    相关推荐

    嵌入式系统中串口通信同步方法

    个同类型或其他类型的中断,从而造成主程序得不到执行或后续中断数据丢失所以,嵌入式系统中的串口通信虽然看似简单,但其中仍有许多问题值得研究,例如串口
    发表于 10-09 19:17

    求大佬分享种嵌入式系统中串口通信同步方法

    本文针对该问题给出了逐次比较、基于FIFO队列和基于状态机的3种同步方法。通过测试、分析和比较得出,基于有限状态机的方法是嵌入式系统串口通信中很有效的
    发表于 05-27 06:52

    种并行同步设计方案的提出、设计与应用

    针对设计某高速卫星数据通信同步系统中所遇到的问题,提出了种新的并行同步设计方案,解决了
    发表于 07-05 16:11 12次下载

    基于FPGA的光纤通信系统中同步头检测设计

     为实现设备中存在的低速数据光纤通信同步复接/ 分接,提出种基于FPGA 的同步头信号提取检测方案,其中
    发表于 10-26 16:56 46次下载

    同步通信,同步通信原理是什么

    同步通信,同步通信原理是什么  同步通信种连续
    发表于 03-17 16:34 6132次阅读
    <b class='flag-5'>同步</b><b class='flag-5'>通信</b>,<b class='flag-5'>同步</b><b class='flag-5'>通信</b>原理是什么

    同步,同步是什么意思

    同步,同步是什么意思 在数字通信时,般总是以
    发表于 03-17 17:30 2.4w次阅读

    VHDL语言实现的同步算法

    数字通信网中,同步同步复接设备中最重要的部分,他包括同步码的产生和
    发表于 07-02 18:33 1675次阅读
    VHDL语言实现的<b class='flag-5'>帧</b><b class='flag-5'>同步</b>算法

    采用FPGA实现同步同步系统的设计

    为了能在GPS接收端获取正确导航电文,研究了CJPS接收机位同步同步的基本原理和实现方式。提出种采用FPGA来实现位同步
    发表于 11-07 17:13 12次下载
    采用FPGA实现<b class='flag-5'>同步</b>、<b class='flag-5'>帧</b><b class='flag-5'>同步</b>系统的设计

    基于DSP Builder的同步检出模型

    基于信号在进行远距离传输的时候,不可避免地存在信号干扰、延迟、非线性失真等,为了确保数字通信系统传输的有效性,必须采用同步。按照同步的作用可以将其分为载波同步、位
    发表于 11-13 16:16 3次下载
    基于DSP Builder的<b class='flag-5'>帧</b><b class='flag-5'>同步</b>检出模型

    串口数据转CAN格式详解

    MCU没有CAN或CAN接口数量不够怎么办?目前市面上有串口转CAN的相关模块或设备,但大家知道串口转CAN是如何实现的吗?转换后的格式是如何的?本文将为大家详细介绍
    的头像 发表于 02-02 16:30 1.5w次阅读

    基于有限状态机的嵌入式系统串口通信同步方法设计

    同类型或其他类型的中断,从而造成主程序得不到执行或后续中断数据丢失。所以,嵌入式系统中的串口通信虽然看似简单,但其中仍有许多问题值得研究,例如串口通信过程中的
    发表于 04-10 08:48 2614次阅读
    基于有限状态机的嵌入式系统<b class='flag-5'>串口</b><b class='flag-5'>通信</b><b class='flag-5'>帧</b><b class='flag-5'>同步</b>方法设计

    STM32之汇编语言的串口通信

    、USART简介通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter)是个串行通信设备,可以灵活地与外部设备进行全双工数据交换。串行
    发表于 12-06 21:06 9次下载
    STM32之汇编语言的<b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    浅谈串口通信

    线和根发送线就可以完成系统间交换信息 尽管串行通讯的比按字节传输的并行通信慢,但是串口具有通信线路少,布线简便易行,施工方便,结构灵活,系统间协商协议,自由度及灵活度较高的特点。
    的头像 发表于 01-09 12:56 1593次阅读

    简析插值法同步

    同步方式:具有搜索、校验、同步三种状态:长、同步字、搜索容错位数、校核容错位数、同步容错位数
    的头像 发表于 02-10 14:00 789次阅读

    了解串口通讯与MODBUS协议

    串行通信的两种基本形式:同步通信和异步通信。 异步通信所传输的数据格式是由1个起始位、1
    的头像 发表于 03-23 09:59 4087次阅读
    <b class='flag-5'>一</b><b class='flag-5'>文</b>了解<b class='flag-5'>串口</b>通讯与MODBUS协议