一、概述
串口使用时,有时候会有接收不定长数据的需求,这时候用DMA+空闲中断的方式是最好的方法。
二、cubeide的配置
串口按照需求配置后,添加一个串口接收的DMA,如下图
三、代码编写部分
1、在 串口init函数 MX_UART4_Init(void)的末尾用户代码区域添加使能空闲中断和dma接收的代码,如下图,注意DMA接收缓存数组需要自定义
2、自定义一个串口中断函数,并在stm32h7xx_it.c文件中串口中断位置处添加该函数。
3、在自定义的中断函数中实现空闲中断时的处理。(为什么要添加一个自定义中断函数,而不在HAL_UART_RxCpltCallback中断接收回调函数中处理空闲中断?因为在HAL库当中,空闲中断并不会触发HAL_UART_RxCpltCallback回调函数,只有当DMA的receive buff满了之后才会触发)
注意:
1、首先要判断是否为空闲中断,是的话要及时清除空闲标志位
2、这里非常重要,也容易搞忘。需要关闭串口的DMA,因为不关闭的话,后面会在缓存数组中自增接着存储,将多次不定长存储数据混着存在一起,而不能到达每一次空闲中断接收到的数据都刷新缓存数组,从缓存数组的第一个字节开始。
3、这个也非常重要,在下一次开启dma接收前将dma缓存中的数据取出来存到其他数组中,因为如果在下一次dma缓存开启后同时又要读取dma缓存数据进行处理的话,会造成DMA不接收数据的错误。所以要提前取出数据以供后续数据处理,或者下一次dma接收换接收缓存地址也可以。
4、清空dma缓存数组
5、开启下一次DMA接收,不开启的话下一次则不能接收。
标签:DMA,缓存,UART,中断,串口,接收,空闲 From: https://www.cnblogs.com/tgc-3/p/17593893.html