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

发布者:Tianran2021最新更新时间:2024-06-20 来源: elecfans关键字:串口通信  帧同步  STM32 手机看文章 扫描二维码
随时随地手机看文章

封装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报错标志位。

即可检测出丢字节的帧。


关键字:串口通信  帧同步  STM32 引用地址:一文知道串口通信的帧同步问题

上一篇:制作一个0-20mA的信号发生器,可以给很多仪器仪表做校准或测试
下一篇:HID+CDC复合设备在WIN10的识别问题

推荐阅读最新更新时间:2024-11-17 08:59

stm32独立看门狗和窗口看门狗的区别
1)独立看门狗没有中断,窗口看门狗有中断 2)独立看门狗有硬件软件之分,窗口看门狗只能软件控制 3)独立看门狗只有下限,窗口看门狗又下限和上限 4)独立看门狗是12位递减的。窗口看门狗是7位递减的 5)独立看门狗是用的内部的大约40KHZ RC振荡器,窗口看门狗是用的系统时钟APB1ENR 以上是我总结的 接下来我们介绍一下独立看门狗和窗口看门狗,这里我们就不讲解程序了,很简单的,配置一下寄存器就可以使用了。 独立看门狗没有中断功能,只要在计数器减到0(下限)之前,重新装载计数器的值,就不会产生复位,独立看门够有硬件和软件之分,硬件是通过烧写器的“设定选项几节等”配置,一旦开启了硬件看门狗,那么就停不下来了,只能在重新
[单片机]
STM32 systick做为系统时间使用(非简单延时)
基本能搜到的systick 都是作为延时使用的,因为设计需求我更多实用的是系统时间判断。 假如我有个LED 需要每10s 闪一下,并且单片机还需要做其他的工作,用延时工作效率太低了,开个定时器又太浪费了。因此系统时钟就体现出了由为重要的应用场合。只需要检测到系统时间为10s 的倍数就可以做动作了,当然前提保证程序的大体循环能在1s 内完成,这个基本没问题如果一个大体循环1s 内完成不了 那这个程序要么就是大到无法形容,要么就是无止境的运行。 首先进入while(1) 大循环前初始化systick,进入主体程序就在计数了,计数分毫秒,秒,这样能在特点的时间进入指定的程序中运行。 初始化systick void Tim
[单片机]
STM32低功耗设置
前两个月在公司做了一个低功耗项目,现在功耗最低10uA不到,平均功耗40uA左右,算是达标了。因为是公司产品,就不方便贴代码、原理图了,该产品是一个小模块,可以方便的嵌入到各种系统里面。跟原子哥他们卖的NRF2401类似,是一个读卡器。 做这个项目中间也请了技术支持,因为外围电路芯片的功耗一直降不下来,经过与对方的反复交流,对方提供了低功耗的测试结果、硬件方案、软件方案,经过修改测试,最终成为我们的产品,功耗比较满意。 硬件方案选择的是STM32,外加某公司的读卡芯片。前期完成了读卡等功能的开发,最后一项开发内容是最艰巨也是最困难的---低功耗。在开发过程中,从硬件设计上不断裁剪元器件,软件上不断精简代码,功耗最低
[单片机]
STM32里的串口通信
在STM32里,串口通信是USART,STM32可以通过串口和其他设备进行传输并行数据,是全双工,异步时钟控制,设备之间是点对点的传输。 对应的STM32引脚分别是RX和TX端。STM32的串口资源有USART1、USART2、USART3. 串口的几个重要的参数: 波特率,串口通信的速率 空闲,一般为高电平 起始位,标志一个数据帧的开始,固定为低电平。当数据开始发送时,产生一个下降沿。(空闲–》起始位) 数据位,发送数据帧,1为高电平,0为低电平。低位先行。 比如 发送数据帧0x0F 在数据帧里就是低位线性 即 1111 0000 校验位,用于数据验证,根据数据位的计算得来。有奇校验,偶校验和无校验。 停止位,用于数据的间隔
[单片机]
<font color='red'>STM32</font>里的<font color='red'>串口通信</font>
STM32学习笔记一一内存管理
1.简介 内存管理:指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。 内存管理的实现方法有很多种,最终都是要实现两个函数: malloc 和 free。 malloc :函数用于内存申请; free: 函数用于内存释放。 1.1 分块式内存管理原理 由上图可知,分块式内存管理由内存池和内存管理表两部分组成。内存池被等分为 n块,对应的内存管理表,大小也为 n,内存管理表的每一个项对应内存池的一块内存。 内存管理表的项值代表的意义:当该项值为 0 的时候,代表对应的内存块未被占用;当该项值非零的时候,代表该项对应的内存块已经被占用,其数
[单片机]
<font color='red'>STM32</font>学习笔记一一内存管理
STM32使用外部16MHZ晶振修改程序点
做小封装产品设计的朋友或许知道3225-4PIN的晶振,为何8MHZ晶振批量价格要到2元一片,而16MHZ晶振只需要0.4元甚至更少。究其原因是因为3225封装的晶振目前全球最低频率一般为8MHZ,而国内8MHZ达不到精度指标,所以市场上的8MHZ晶振一般为进口晶振,因此成本被垄断。 图1 3225封装晶振 STM32单片机学习者一开始用的晶振一般是2PIN的8MHZ晶振,一旦正真做产品研发的时候,使用到3225的8MHZ晶振的话,成本是个不小的挑战。笔者现针对这个问题,提出使用16MHZ晶振代替的方法。 图2 STM32时钟树状图 由上图可以看出,如果想兼容8MHZ晶振,必须在时钟倍频前2分频。程序设计如
[单片机]
<font color='red'>STM32</font>使用外部16MHZ晶振修改程序点
stm32.cube(四)——HAL.ADC
一、Adc特性 1.1 Adc概述 Stm32的Adc具有12位的精度,共有16个外部通道和2个内部通道。不同通道的 A/D 转换可以在单一、连续、扫描或者间断模式下进行。它的其他特性还包括支持模拟看门狗和DMA。 1.2 Adc初始化 和大多数外设一样,Adc在使用前必须初始化时钟源,并从掉电模式唤醒该设备。建议在初始化Adc后立即运行一次校准,以减少准确性错误。 1.3 通道的选择 对于16个可复用的通道,可以将通道分成两种类型的组。常规组和注入组,组序列保存在寄存器ADC_SQRx和ADC_JSQR中。常规组可以包含最多16个通道,注入组最多包含4个通道。 注入组可以理解为常规组的一种中断,当注入组的采集被触发时,常规
[单片机]
gd32和stm32哪个好?
GD32和STM32是两种常见的微控制器系列,是开发者们常用的开发板核心。尽管它们相似之处很多,但它们也存在着差异,本文将深入探讨GD32和STM32,分享它们的优缺点。 首先,我们从GD32说起。GD32是由国内的同时表示中心研发的一种基于ARM Cortex-M3 CPU的微控制器,该平台具有很高的兼容性、低功耗以及出色的性能。许多GD32产品也广泛用在电子产品、智能家居、工业控制系统和无人机开发等领域。 与此相反,STM32系列是ST公司基于Cortex-M3架构开发的高性能微控制器。STM32系列以其高速运算能力、出色的数据处理性能、广泛的官方支持和易用的硬件软件接口而著名。STM32可轻松完成各种任务,比如音频、显示以及
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved