STM32学习笔记8(DMA控制器)
DMA简介(1)
DMA,全称为:Direct Memory Access,即直接存储器访问,DMA 用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。当 CPU 初始化这个传输动作,传输动作本身是由DMA 控制器 来实行和完成。DMA 传输对于高效能嵌入式系统算法和网络是很重要的。DMA 传输方式无需 CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备开辟一条直接传送数据的通路,能使 CPU 的效率大为提高。STM32 最多有 2 个 DMA 控制器(DMA2 仅存在大容量产品中),DMA1 有 7 个通道,DMA2 有 5个通道。每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个 DMA 请求的优先权。
从外设(TIMx、ADC、SPIx、I2Cx 和 USARTx)产生的 DMA 请求,通过逻辑或输入到DMA 控制器,这就意味着同时只能有一个请求有效。外设的 DMA 请求,可以通过设置相应的外设寄存器中的控制位,被独立地开启或关闭。
表1是 DMA1 各通道一览表:
表1 DMA各通道一览表
逻辑或,通道 1 的几个 DMA1 请求(ADC1、 TIM2_CH3、 TIM4_CH1),这几个是通过逻辑或到通道 1 的,这样我们在同一时间,就只能使用其中的一个。其他通道也是类似的。
DMA寄存器
注意: 在以下列举的所有寄存器中,所有与通道6和通道7相关的位,对DMA2都不适用,因为DMA2只有5个通道。
DMA 中断状态寄存器(DMA_ISR)
如果开启了 DMA_ISR 中这些中断,在达到条件后就会跳到中断服务函数里面去,如果没开启,我们也可以通过查询这些位来获得当前 DMA 传输的状态。这里常用的是TCIFx,即通道 DMA 传输完成与否的标志。 注意此寄存器为只读寄存器,所以在这些位被置位之后,只能通过其他的操作来清除。
DMA 中断标志清除寄存器(DMA_IFCR)。
- void Init_DMA()
- {
- DMA_InitTypeDef DMA_InitStructure;
- DMA_DeInit(DMA1_Channel1);
- DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
- DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //
- DMA_InitStructure.DMA_BufferSize = 1; //
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
- DMA_InitStructure.DMA_Priority = DMA_Priority_High;
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
- DMA_Init(DMA1_Channel1, &DMA_InitStructure);
- /* Enable DMA1 channel1 */
- DMA_Cmd(DMA1_Channel1, ENABLE);
- }