直接存储器存取DMA(Direct Memory Access):
允许CPU内部的硬体子系统(外设)可以独立地直接读写系统存储器,它允许不同速度的硬件装置来传递数据而不依赖于CPU。单片机采用DMA提供外设和存储器之间或者存储器之间的高速数据传输。当CPU初始化这个传输动作后,数据的传输动作由DMA控制器来实行和完成。STM32有有两个DMA控制器,DMA1有7个通道,DMA2有5个通道,每个通道专门用来管理一个或多个外设对存储器访问的请求,一个仲裁器来协调各个DMA请求的优先权。起到通信“桥梁”的作用,快速是其应用的主要价值。
I2C/UART等外设寄存器数据送到SRAM;
SRAM的两个区域之间传输;
外设寄存器到外设寄存器;
SRAM到外设寄存器。
DMA控制器和Cortex-M3核共享系统数据总线执行直接存储器数据传输。当CPU和DMA同时访问相同的目标(RAM或外设)时,DMA请求可能会停止 CPU访问系统总线达若干个周期,总线仲裁器执行循环调度。外设发送一个请求信号到DMA控制器后,DMA控制器根据通道的优先权处理请求。
使用ADC1-DMA的初始化过程:
DMA_InitTypeDef DMA_InitStructure;
/* DMA channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //数据来源,对应的寄存器地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue; //数据保存位置,通过读该变量获得AD值
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA的传输方向,此处单向传输
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的优先级,以便分级管理调度
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //两个变量间是否互相访问
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
HAL库中设置:
hdma_adc1.Instance = DMA1_Channel1;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
通过直接取用定义的在RAM中用于保存ADC值得数据进行调用,在一些场合比使能然后等待读取寄存器数据更方便点。DMA初始化后就没有多少需要管理的处理了,十分方便。