DMA,全称为:Direct Memory Access,即直接存储器访问。DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备开辟一条直接传送数据的通路,能使CPU的效率大为提高。
DMA设置的一般步骤可以总结为如下几个步骤:
1.DMA时钟使能
2.DMA设置复位
3.设置DMA基地址,内存地址,输出方向参数
4.设置DMA数据大小,优先级,使用通道参数
5.DMA工作方式初始化
6.使能DMA
7.编写中断处理函数

前端采集模块的DMA使用主要用于ADC采集结果的传输和USART串口的数据发送传输。根据《stm32中文参考手册》的DMA请求一览表,选用了DMA1的通道1作为ADC1的数据传输通道,以及DMA1通道4作为和USART串口的数据发送传输通道。此处采用了单个DMA复用多通道的设计,是因为DMA速度足以完成这些任务,而且留下其他DMA资源以便项目以后可以扩展,达到节省资源的目的。

USART使用DMA发送数据配置和使能代码
- void DMA_USART_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
- {
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
-
- DMA_DeInit(DMA_CHx);
- DMA1_MEM_LEN=cndtr;
- DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;
- DMA_InitStructure.DMA_MemoryBaseAddr = cmar;
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
- DMA_InitStructure.DMA_BufferSize = cndtr;
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
- DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
- DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
- DMA_Init(DMA_CHx, &DMA_InitStructure);
-
- }
- void DMA_USART_Enable(DMA_Channel_TypeDef*DMA_CHx)
- {
- DMA_Cmd(DMA_CHx, DISABLE );
- DMA_SetCurrDataCounter(DMA_CHx, DMA1_MEM_LEN);
- DMA_Cmd(DMA_CHx, ENABLE);
- }
ADC使用DMA传送多通道数据配置和使能代码
- void DMA_ADC_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
- {
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
-
- DMA_DeInit(DMA_CHx);
- DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;
- DMA_InitStructure.DMA_MemoryBaseAddr = cmar;
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
- DMA_InitStructure.DMA_BufferSize = cndtr;
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
- 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(DMA_CHx, &DMA_InitStructure);
-
- }
-
- void DMA_ADC_Enable(DMA_Channel_TypeDef*DMA_CHx)
- {
- DMA_Cmd(DMA_CHx, DISABLE );
- DMA_Cmd(DMA_CHx, ENABLE);
- }
这里需要注意的是USART使用DMA发送数据需要每一次都重新使能,即每发送一次数据使能一下。
而ADC使用DMA传送多通道数据则只需要使能一次就可以自动循环工作,只需从数组空间读取ADC数据。
STM32f103的数电采集电路的DMA设计和使用优化程序
原文:http://www.cnblogs.com/zym0805/p/7049168.html