你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【实战经验】串口工作在DMA模式下有时接收异常

[复制链接]
zero99 发布时间:2016-7-12 14:44
串口工作在DMA模式下有时接收异常

前言
客户反馈在使用STM32F205的串口工作在DMA模式时,有时能够接收数据,有时完全没有数据,但如果换成中断模式来接收又能100%正常收到数据。

一 复现现象
问题背景
与客户沟通,客户使用的是STM32F2标准库V1.1.0,串口波特率为1.408Mbps,不经过串口RS232,直接连接主CPU和从MCU(STM32F205)的串口发送和接收引脚,如下图所示:

1.png

尝试重现问题
由于客户使用的是主从架构,实验采用两块STM3220G-EVAL评估板来重现现象。一块用来不间断发送串口数据,另一块采用串口DMA进行接收,直接通过杜邦线连接串口PIN脚并共地,不使用评估板上的RS232收发器。接收端使用STM32F2xx_StdPeriph_Examples\ USART\USART_TwoBoards的示例代码。代码片段如下:

2.png

3.png

USART_Config()函数如下:

4.png

5.png

6.png

按如上代码,有如下现象:
1 代码不做修改,若先启动接收端MCU再启动发送端MCU,接收端MCU的串口能正常接收。
2代码不做修改,若先启动发送端MCU再启动接收端MCU,接收端MCU的串口100%接收异常。
3 修改发送端代码,改为发送端MCU串口每1秒间隔发送一次,则无论启动顺序如何,接收端MCU的串口都能正常。

二 程序分析
由上述代码可知,程序是先在USART_Config()函数函数内初始化串口并使能,然后再在接下来的main函数的while循环内初始化DMA并使能。这个是标准库内附带的示例代码,咋一看没什么问题,但仔细一想,针对用户的使用场景,这里就会产生一个问题:由于用户的主CPU有可能在从MCU启动之前就已经有可能启动,那么在这种情况下,在初始化完串口并使能后,到DMA使能之前这段时间内,若主CPU向从MCU发送串口数据,从MCU是否能正确接收?

从上述测试代码的结果2可以得出,若在串口初始化并使能后到DMA使能之前有数据来,MCU是不能接收的,经进一步调试,发现此时数据寄存器USART_DR存在一个数据,且在状态寄存器USART_SR中ORE值1,由此可知,串口的接收寄存器中已经接收到一个数据,但是后面的数据又来了,由于数据寄存器中的数据没有及时转移走(此时DMA还没有开启),从而导致后面的数据无法存入,所以产生了上溢错误(ORE),而一旦产生上溢错误后,就无法再触发DAM请求,及时之后再启动DMA也不行,无法触发DMA请求就无法将数据寄存器内的数据及时转移走,如此陷入死锁,这就是串口无**常接收的原因。这时反观一下代码的结果3,这又将做如何解释?

仔细查看测试结果3,发现这个发送端每1秒间隔发送一次,那么就会存在这个一个概率,这个发送的时间点是否刚好在接收端MCU的串口初始化并使能和DMA使能之间还是之后,这个时间窗口非常关键,如果刚好在时间窗,那么串口接收就不正常,如果在这个时间窗之后,串口接收就能正常。由于测试代码采用的是1秒间隔,对于MCU来说这个是非常大的时间长度,还是很小概率能碰中这个时间窗的,因此,测试结果看起来是都能正常,实际严格来说,还是存在刚好碰中的可能。如果间隔时间缩短,那个碰中的几率就增大。由此看来,这也就能解释测试结果3了,也能解释客户提到的有时正常有时不正常的现象了。

三 问题处理
处理有两种方法,第一种方法是在使能DMA后,及时将数据寄存器DR中的数据清除掉,如下代码所示:

7.png

这里是使用读DR的方法来清除的,从参考手册中也提到使用这种方法来清除ORE标志:

8.png

第一种方法类似于一种纠错措施,下面介绍另一种推荐的方法,如下代码所示:

9.png

如上所示,可以先使能DMA再使能串口,这样就彻底不存在那个时间窗了,不管数据何时过来能能被DAM及时转走。这个是推荐的解决方法。

四 结论
标准库中的示例代码一般来说只供参考,对于大部分情况来说都是能正常工作的,但偶尔也会出现不适用的情况,此时更需要我们针对问题进行思考分析,进一步找到原因才能解决问题。对于串口使用DMA来接收的情况,这里建议一定要先使能DMA,最后使能串口,这样就能避免类似问题出现了。


文档下载地址:
https://www.stmcu.org.cn/document/detail/index/id-217182


实战经验汇总:
https://www.stmcu.org.cn/module/forum/thread-576401-1-1.html

收藏 4 评论7 发布时间:2016-7-12 14:44

举报

7个回答
leiyijing2003 回答时间:2017-3-24 17:47:42
我们也发现了同样的问题,既然ST知道了有问题,怎么不更新库文件呢?
faye1 回答时间:2017-7-17 13:30:20
厉害,基本也是类似的问题,搞了很久
Abners 回答时间:2017-9-27 18:31:02
我用的是103的片子,也遇到一个问题,不过是发送的,特定长度,最后一个字节不对!苦逼呀!!!
任风吹吹 回答时间:2018-5-9 10:09:34
leiyijing2003 发表于 2017-3-24 17:47
我们也发现了同样的问题,既然ST知道了有问题,怎么不更新库文件呢?

这个属于应用层代码调用顺序问题,为什么要更新库?看懂了再说话
秦秦秦 回答时间:2018-11-22 09:53:39
不错,支持下
甜心男爵 回答时间:2018-12-28 09:47:17
Abners 发表于 2017-9-27 18:31
我用的是103的片子,也遇到一个问题,不过是发送的,特定长度,最后一个字节不对!苦逼呀!!! ...

你可以在DMA发送完成后检查一下串口是否空闲,因为DMA发送完了之后串口还要1到2个字节的时间,判断下串口发送完成标志位就好了
liudawei123 回答时间:2019-9-12 11:34:44
非常不错哦,支持下

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版