[TOC]

DMA笔记

最近做项目使用到了DMA,于是学习了DMA,DMA是一个DMA控制器来把一个地址空间的数据复制到另外一个地址空间,在没有使用到DMA时,这个过程是由CPU来完成的,这占据了CPU的资源,降低了效率,尤其在频繁收发数据时,CPU消耗极大,所以使用到DMA控制器来脱机传输数据提高了CPU的效率,在各种涉及到数据传输的地方都能用到DMA,比如串口和一些外设如陀螺仪中,用到DMA来减小CPU开销。

配置

一般分4步:以从串口通过DMA通道发送数据到指定内存地址为例!

1、使能时钟

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

2、初始化对应DMA通道参数

DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA2_Stream2); //配置DMA2的通道2为缺省状态(即是默认状态)

            DMA_InitStructure.DMA_Channel = DMA_Channel_4; //选择DMA通道
            DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (USART1->DR); //配置外设基地址:即USART1的接收数据地址DR
            DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)rx1_buf; //存放数值内存的基地址
            DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//DMA传输方向
            DMA_InitStructure.DMA_BufferSize = dma_buf_num;//总接收发数据长度
            DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//地址加1关闭
            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_Circular;//DMA循环模式
            DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//优先级非常高                
            DMA_Init(DMA2_Stream2, &DMA_InitStructure);//
            DMA_DoubleBufferModeConfig(DMA2_Stream2, (uint32_t)rx2_buf, DMA_Memory_0);//    DMA缓存大小            
            DMA_DoubleBufferModeCmd(DMA2_Stream2, ENABLE);//                

3、使能外设的DMA

USART_Cmd(USART1, DISABLE);

4、使能DMA通道

​ DMA_Cmd(DMA2_Stream2, DISABLE); //关闭
​ DMA_Cmd(DMA2_Stream2, ENABLE);//开启

有时也需要查询DMA的状态,比如有没有传输完成,还有多少没有传输等等,对应的库函数可以了解一下。DMA配置就到这里

wechat