1. DMA简介DMADirect Memory Access直接存储器存取DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输无需CPU介入节省了CPU的资源存储器到存储器的数据转运我们一般使用软件触发。外设到存储器的数据转运我们一般使用硬件触发。2. STM32的存储器下表列出了STM32具有的存储器以及存储器的地址及用途ROM掉电不丢失RAM掉电丢失类型起始地址存储器用途ROM0x0800 0000程序存储器Flash存储C语言编译后的程序代码ROM0x1FFF F000系统存储器存储BootLoader用于串口下载ROM0x1FFF F800选项字节存储一些独立于程序代码的配置参数RAM0x2000 0000运行内存SRAM存储运行过程中的临时变量RAM0x4000 0000外设寄存器存储各个外设的配置参数RAM0xE000 0000内核外设寄存器存储内核各个外设的配置参数3. DMA框图方向部分就是DMA运行区域存储器和存储器以及外设到存储器既然需要转运数据就需要如下的三个参数1 起始地址2数据宽度3地址是否自增对于地址是否自增比如通过串口接收数据进行数据转运此时地址选择不自增数据会不断的填入这个地址我们只需要进行转运即可。3.1 传输计数器用来确定转运多少次数据当传输计数器降低至0后会通过自动重装器来重置计数器。3.2 触发方式触发方式提供图中的M2M来决定当M2M置1此时软件触发DMA转运当M2M置0此时为硬件触发提供外设的标志位来进行触发。3.3 DMA传输的三个条件传输计数器大于0触发源有触发信号DMA使能4. DMA请求来源上述介绍了两种触发方式此部分就是具体的DMA通道对应的触发源由图中可得DMA可以转运SPI,IIC,UART的数据以及定时器TIM信号触发DMA转运。右侧的硬件优先级通过仲裁器来判断其运行的先后顺序。5. DMA数据宽度转运原则按照下图所示当读小宽度写大宽度此时高位补0当读大宽度写小宽度此时只保留低位6. DMA实例6.1 固定数组数据转运若有两组数据如下表所示那么地址需要自增将对应位置的数据转运到对应的位置6.2 AD扫描模式 DMA数据转运因为是扫描模式且每次的AD采样结果都会将其存储在DR寄存器所以外设地址不自增目标地址自增此时可以将数据传输到对应的数组中7. 代码7.1 DMA初始化按照框图进行初始化第一步RCC开启时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);第二步初始化DMADMA_InitTypeDef DMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddrAddrA;DMA_InitStructure.DMA_PeripheralDataSizeDMA_PeripheralDataSize_Byte;DMA_InitStructure.DMA_PeripheralIncDMA_PeripheralInc_Enable;DMA_InitStructure.DMA_MemoryBaseAddrAddrB;DMA_InitStructure.DMA_MemoryDataSizeDMA_MemoryDataSize_Byte;DMA_InitStructure.DMA_MemoryIncDMA_MemoryInc_Enable;DMA_InitStructure.DMA_DIRDMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSizeSize;DMA_InitStructure.DMA_ModeDMA_Mode_Normal;DMA_InitStructure.DMA_M2MDMA_M2M_Enable;DMA_InitStructure.DMA_PriorityDMA_Priority_Medium;DMA_Init(DMA1_Channel1,DMA_InitStructure);第三步DMA使能DMA_Cmd(DMA1_Channel1,ENABLE);7.2 DMA硬件触发使用DMA转运ADC采样数据主要这里与上述的DMA初始化有两个差别M2M关闭也就是关闭软件触发打开对应外设的DMA硬件触发模式开关这里列出有差别的代码部分DMA_InitStructure.DMA_M2MDMA_M2M_Disable;ADC_DMACmd(ADC1,ENABLE);