一直都没有整理STM32 DMA应用,这篇文章算是抛砖引玉吧,欢迎拍砖。
本人QQ 330952038,欢迎交流学习
什么是DMA —- Directional Memory Access, 直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作
我们通过以下几方面学习串口DMA:
一、如何理解DMA
对于DMA,打个比方就很好理解:
角色预设: 淘宝店主 —- STM32 MCU
快递员 —- 外设(如UART,SPI)
发货室 —- DMA
1、首先你是一个淘宝店主,如果每次发货收货都要跟快递沟通交涉会很浪费时间和精力。
2、然后你就自己建了一个发货室,发货室里有好多个货柜箱子,每个箱子上都写着快递名字(如果申通快递,顺丰快递等)。
3、每次发什么快递,你就找到对应的货柜箱子,把货物放进去即可,然后跟快递通知一声。
4、快递取走快件。
5、如果是收货,快递直接把快件放到对应的柜子,然后通知你一下。
6、你过来提取货物。
通过上面的方式,你可以不需要直接跟快递打交道,就可以轻松发货成功,DMA处理方式跟上面例子是一样的。
如果下图:
二、STM32 DMA 配置
那么DMA在STM32上是具体怎么实现的呢? 我们先了解一下STM32关于DMA的相关配置。
1、两个DMA控制器有12个通道(DMA1有7个通道,DMA2有5个通道)
ps:对应我们例子,就是有两个大的发货室,一个有7个货柜,另个有5个货柜。
2、在同一个DMA模块上,多个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),优先权设置相等时由硬件决定(请求0优先于请求1,依此类推)
ps: 店主可以跟每个快递公司签订协议,可以在货柜前贴上加急(很高),很急(高),急(中),一般(低), 如果同时有几个快递员过来取货,优先根据上面的优先级先取件。
3、独立数据源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐。
ps: 指的是货件大小
4、支持循环的缓冲器管理(会把原来的数据覆盖)
5、每个通道都有3个事件标志(DMA半传输、DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求。
ps: 送快递出现的异常情况(送到了一半,送完,快递出错)
解释到这里,不知道大家能不能理解呢。后面是具体的配置。
1、DMA 对应通道如下图
DMA1:
DMA2:
2、DMA配置
1)数据传输的目的地和来源
对应我的例子,就是送快递还是取快递。
2)定义DMA通道的DMA缓存的大小
ps: 即货柜大小,能存多少个快件
3)外设地址寄存器递增与否
4)内存地址寄存器递增与否
5)设定了外设数据宽度
6)设定了内存数据宽度
7)设置了DMA的工作模式
8)DMA通道的软件优先级
9)使能或关闭DMA通道的内存到内存传输
三、 编程
串口用DMA方式发送和接收,分以下几步:
1)串口初始化
2)DMA初始化
3)发送数据
4)接收数据
我们按部就班:
1) 串口初始化 — 使用串口一
#define DMASIZE 1024
// 配置串口一的发送和接收的GPIO口功能,以及中断
static void _uart1_gpio_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
RCC_APB2Periph_USART1 |
RCC_APB2Periph_AFIO, ENABLE) ;
GPIOA->CRH&=