STM32 DMA
简介
DMA,全称为:Direct Memory Access,即直接存储器访问。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
个
事件标志逻辑或成为一个单独的中断请求。
●存储器和存储器间的传输
●外设和存储器,存储器和外设的传输
●闪存、
SRAM
、外设的
SRAM
、
APB1 APB2
和
AHB
外设均可作为访问的源和目标。
●可编程的数据传输数目:最大为
65536
STM32F103RCT6
有两个
DMA
控制器,
DMA1
和
DMA2
从外设(
TIMx
、
ADC
、
SPIx
、
I2Cx
和
USARTx
)产生的
DMA
请求,通过逻辑或输入到
DMA
控制器,这就意味着同时只能有一个请求有效。外设的
DMA
请求,可以通过设置相应的
外设寄存器中的控制位,被独立地开启或关闭。
我们要用到串口 1 的发送,属于 DMA1 的通道 4,
接下来我们就介绍库函数下 DMA1 通道 4 的配置步骤:
1)使能 DMA 时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能 DMA 时钟
2)初始化 DMA 通道 4 参数
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx,
DMA_InitTypeDef* DMA_InitStruct)
3)使能串口 DMA 发送
进行 DMA 配置之后,我们就要开启串口的 DMA 发送功能,使用的函数是:
USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
如果是要使能串口 DMA 接受,那么第二个参数修改为 USART_DMAReq_Rx 即可。
4)使能 DMA1 通道 4,启动传输。
使能串口 DMA 发送之后,我们接着就要使能 DMA 传输通道:
DMA_Cmd(DMA_CHx, ENABLE);
通过以上 3 步设置,我们就可以启动一次 USART1 的 DMA 传输了。
5)查询 DMA 传输状态
在 DMA 传输过程中,我们要查询 DMA 传输通道的状态,使用的函数是:
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG)
比如我们要查询
DMA
通道
4
传输是否完成,方法是:
DMA_GetFlagStatus(DMA2_FLAG_TC4);
这里还有一个比较重要的函数就是获取当前剩余数据量大小的函数:
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx)
比如我们要获取
DMA
通道
4
还有多少个数据没有传输,方法是:
DMA_GetCurrDataCounter(DMA1_Channel4);