工作中经常会遇到串口通信,并对交互的数据进行处理。经常用到的是通过不停的产生串口接收中断,然后对数据做处理。,这样做的弊端就是,不停的会产生串口接受中断。中断请求不但使CPU停下来,而且要CPU执行中断服务程序为中断请求服务,这个请求包括了对断点和现场的处理以及CPU与外设的传送,所以CPU付出了很多的代价。后面就可以采用DMA接收数据,这样串口就可以不需要每次接收到一个字节的数据就进入中断,影响主程序运行。当DMA接收到的数据达到定长时就会产生DMA中断,因此也就带来了一个弊端,就是如果需要接受不定长的数据怎么处理,这时候就需要DMA+串口空闲中断。  “这两个资源配合,简直就是天衣无缝啊,无论接收什么不定长的数据,管你数据有多少,来一个我就收一个,就像广东人吃“山竹”,来一个吃一个~(最近风好大,我好怕)” 综上DMA配合串口有以下几种运用和注意事项:

DMA不通过串口中断接受数据,而是采用普通的串口接受数据的方式接受串口数据,当产生DMA中断时代表传输完成开始对数据进行处理。

DMA接受不定长数据,采用DMA+串口空闲中断的方式,达到无论接收什么不定长的数据,管你数据有多少,来一个我就收一个的效果。

串口DMA数据发送

串口DMA数据发送和接收

主要理解前两种运用即可。

注意事项:

STM32的IDLE的中断在串口无数据接收的情况下,是不会一直产生的,产生的条件是这样的,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一断接收的数据断流,没有接收到数据,即产生IDLE中断。如果中断发送数据帧的速率很快,MCU来不及处理此次接收到的数据,中断又发来数据的话,这里不能开启,否则数据会被覆盖。有两种方式解决:

1.在重新开启接收DMA通道之前,将Rx_Buf缓冲区里面的数据复制到另外一个数组中,然后马上处理复制出来的数据,然后再开启DMA,(实现比较简单)

2.建立双缓冲,重新配置DMA_MemoryBaseAddr的缓冲区地址,那么下次接收到的数据就会保存到新的缓冲区中,不至于被覆盖(暂时没有细究这个是如何实现的)
 

相关例程参考:链接:https://pan.baidu.com/s/1jrSYB5IsHQOCjTYDolaAag 
提取码:obpi 
复制这段内容后打开百度网盘手机App,操作更方便哦

https://wenku.baidu.com/view/b6ad1e8258fb770bf68a558c.html


http://www.openedv.com/forum.php?mod=viewthread&tid=284146&extra=

http://www.openedv.com/forum.php?mod=viewthread&tid=63849&highlight

https://mp.weixin.qq.com/s/FPLdThjKX2sOlMZb_OyQdQ