概述
前言:
最近项目有使用串口接收大段不定长GPS数据的需求,调试了很久,终于找到一个比较好的解决办法。我觉得这个项目需求(高波特率、大段数据、不定长)十分典型,所以在这里记录一下,与大家分享。
这次项目用的是STM32H7的主控+cubemx+MDK做的开发,项目中使用到了FreeRTOS+lwip以及多个串口,且每个串口的波特率都是一个比较高的波特率(均在460800以上),与传统大家常用的9600及115200在调试过程中会有一些不同(感觉是更容易受到干扰)。
在接手项目时,第一时间想的是使用IDLE中断+DMA这种主流的接收不定长数据的方式进行操作,但在调试过程中遇到了串口一帧数据(400-600字节)被打断成两帧数据的情况,在这种情况下需要额外花费CPU的算力去解析、拼包,否则就会导致丢帧,由于项目的特殊性和gps数据只有1HZ的性质,丢弃掉被打散的包和花费额外算力去拼包都是不优先考虑的方法,于是我开始进行对于这个bug的分析与尝试性解决。
问题分析:
针对包被打散的情况,我分析是在数据传输的过程中,单片机跳到了空闲中断,读取了一次DMA中的数据,原因可能有几种:
1、GPS模块在发送数据时并不是均匀连续的,中间存在一定长度的中断,导致IDLE中断触发。
2、误触发,由于波特率较高容易受到其他干扰,以及单片机运行的任务较多,单片机内部中断、任务调度产生了干扰,导致IDLE中断触发。
针对以上两种可能性,展开调试,首先先使用电脑用460800波特率接收GPS同样的数据,发现没有任何问题;
然后通过示波器查看GPS数据,未发现明显异常,示波器的Decode功能也能正常解析GPS数据(这里本来想贴几张图,由于目前工作环境不太允许,所以就省略了);
最后将GPS的波特率拉低,设置在115200,单片机通过115200波特率接收同样的数据,发现数据接收正常了,但是领导无法接受115200波特率下,整帧数据接收时间将会达到40ms左右的延时。所以无奈再去寻找其他解决办法。
那么就得从原理上来分析这个问题了,我们首先来看一下ST官方对于空闲中断条件的说明:
当在参考手册RM0433中文文档(文档号029587 Rev 1)1912页我们可以看到,当检测到空闲线路时IDLE会置1并产生中断,我们继续查看,产生空闲线路的条件
同文的1859、1860页讲述了起始位检测,当起始位检测中止时,即停止位结束后,下降沿检测成功,随后连续检测一位时间没有起始位的话,接收器就会返回空闲状态,继而触发空闲中断,结合之前改为115200波特率bug消除的现象来看的话,我们可以认为,460800波特率下,一位时间太短了,很容易误检测,导致单片机IDLE中断触发,那么,我接下来就需要考虑,如何去将触发中断的时间延长,使中断没有这么容易被触发,让我们可以更好的接收一整帧的数据。
解决问题:
当然解决这个问题有很多种方式,降低波特率也好,改变接收中断也罢,都能解决这个问题,针对我的需求,我查看了STM32H7串口接收的几种中断:
在中断介绍中,我发现接收器超时中断也许可以解决我目前的问题,我查找了接收器超时中断触发的条件:
当我们在RTOR寄存器中设置超时值之后,没有任何通信时就可以触发这个中断,不过手册上又说并非每一个串口都支持这个超时中断,所以我们还要去48.4节USART实现中查找我们要用的串口是否支持超时中断:
可以看到除了LPUART,所有串口都是支持的。
阶段总结:
经过分析与查找手册,我们找到了一个可以自由调整“空闲”时间的“空闲中断”——RTOF接收器超时中断,这样的中断方式从原理上是可以解决我们大段不定长高波特率数据在使用空闲中断时会被打断的问题的,在下一节,我将编写代码来实现使用接收器超时中断的不定长数据串口接收。
非常感谢大家的阅读,如果喜欢请给我点个赞吧,如文章中有错漏欢迎大家在评论区或私信斧正,一些其他的技术问题也可以在评论区或私信交流。
最后
以上就是无情书本为你收集整理的STM32 串口超时中断+DMA接收不定长数据 比 空闲中断(IDLE)更加灵活、稳定(一)前言:问题分析:解决问题:阶段总结: 的全部内容,希望文章能够帮你解决STM32 串口超时中断+DMA接收不定长数据 比 空闲中断(IDLE)更加灵活、稳定(一)前言:问题分析:解决问题:阶段总结: 所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复