当前位置:   article > 正文

STM32HAL库DMA串口_stm32dma串口接收数据

stm32dma串口接收数据

在使用串口中断时,当我们的串口接收到信息时,就会开始出发一次中断,然后开始一个字节字节地去接收,在这个·过程中,虽然效率变高了,但是串口仍然会占用到一些CPU,那么有什么效率高,但又没那么占CPU的方法呢。

答案是有的,那就是用DMA来接收。

DMA,全称为:Direct Memory Access,即直接存储器访问。直接存储器存取( DMA )用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须 CPU 干预,数据可以通过 DMA 快速地移动,这就节省了 CPU 的资源来做其他操作。典型的例子就是移动一个外部内存的区块到芯片内部更快的内存区。像是这样的操作并没有让处理器工作拖延,反而可以被重新排程去处理其他的工作。DMA 传输对于高效能嵌入式系统算法和网络是很重要的。DMA 传输方式无需 CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备开辟一条直接传送数据的通路, 能使 CPU 的效率大为提高。

  STM32最多有 2 DMA 控制器( DMA2 仅存在大容量产品中), DMA1 7 个通道。 DMA2 有5
个通道。每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁起
来协调各个DMA请求的优先权。
STM32 DMA有以下一些特性:
●每个通道都直接连接专用的硬件 DMA 请求,每个通道都同样支持软件触发。这些功能
通过软件来配置。
●在七个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),假如
在相等优先权时由硬件决定(请求0 优先于请求 1 ,依此类推)
●独立的源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和
目标地址必须按数据传输宽度对齐。

●支持循环的缓冲器管理
●每个通道都有3 个事件标志(DMA 半传输, DMA 传输完成和 DMA 传输出错),这3
事件标志逻辑或成为一个单独的中断请求。

存储器和存储器间的传输
●外设和存储器,存储器和外设的传输
●闪存、S RAM、外设的SRAM APB1 APB2 AHB 外设均可作为访问的源和目标。
●可编程的数据传输数目:最大为65536 

具体的函数和功能可以参考大佬的这篇文章STM32 | DMA配置和使用如此简单(超详细)_dma_it_tc-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_44524484/article/details/105671273

在本次项目中,我们用到的是STM32F103C8T6最小系统板,先在Cubemx里面开启串口中断,记得要使能中断,在这里我们使用的是串口空闲中断,再开启DMA,如下面两张图一样,我们就开启了串口和DMA了。

在这里我们可以编写回调函数,这里的回调函数和串口中断的是有区别的,串口空闲中断的回调函数用的是HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)

这里的size可以使用sizeof()来计算接收到的数据

在main.c函数的while循环里面开启DMA空闲接收中断

__HAL_DMA_DISABLE_IT(&hdma_usart1_rx,DMA_IT_HT);这个是不使能DMA的半传输中断,这样子在接收不定长数据的时候就不会发生只接收一半就发生中断的现象,导致数据接收不完整。

通过DMA来接受的还有串口DMA接收中断,但这个本质上是和串口中断一样的,调用的还是出串口接收中断void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart),因此在这里便不做示例了。

在本次实验中,我们接收的是不定长度的数据,大家如果接收的是定长度,就可以直接使用DMA中断。

以上是我自己做的实验的一些步骤,若有不足请各位大佬多多指教,如果还有其他的更好的接收方法,也希望大家多多指出来,一起进步。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号