直接存储器存取(DMA)用于在外围设备和内存以及内存到内存。数据可以通过DMA快速移动没有任何CPU操作。这使CPU资源对其他操作保持空闲。DMA控制器有5个通道,每个通道专门用于管理内存访问请求。来自一个或多个外围设备。它有一个仲裁器来处理DMA之间的优先级请求。
配置过程详解:
首先调用RCC_AHBPeriphClockCmd()函数,进行DMA时钟的初始化。
可以看到DMA在AHB时钟上。所以我们使用以下语句打开DMA1的时钟。
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//使能DMA1时钟
接着在DMA.c中编写如下两个函数。来设置DMA从UART1到内存和内存到UART的传输通道。
/**************************************************************************************
* FunctionName : DMA_MemoryToPeripheral()
* Description : DMA传输(内存-->外设)
* EntryParameter :
* ReturnValue : None
* Function :
**************************************************************************************/
void DMA_MemoryToPeripheral(uint32_t MemoryAddr,uint32_t PeripheralAddr,uint16_t BufferSize)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Channel2);//复位DMA1_Channel2
DMA_InitStructure.DMA_PeripheralBaseAddr=PeripheralAddr;//外设地址
DMA_InitStructure.DMA_MemoryBaseAddr=MemoryAddr;//内存地址
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralDST;//传输方向:内存到外设
DMA_InitStructure.DMA_BufferSize=BufferSize;//传输长度
DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设累增:NO
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//外设累增:YES
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;//循环模式:NO
DMA_InitStructure.DMA_Priority=DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//内存-内存:NO
DMA_Init(DMA1_Channel2,&DMA_InitStructure);
DMA_Cmd(DMA1_Channel2,ENABLE);//使能DMA传输
}
/**************************************************************************************
* FunctionName : DMA_PeripheralToMemory()
* Description : DMA传输(内设-->内存)
* EntryParameter :
* ReturnValue : None
* Function :
**************************************************************************************/
void DMA_PeripheralToMemory(uint32_t PeripheralAddr,uint32_t MemoryAddr,uint16_t BufferSize)
{
DMA_InitTypeDef DMA_InitStructure;//声明结构体
DMA_DeInit(DMA1_Channel3);//复位DMA1_Channel3
DMA_InitStructure.DMA_PeripheralBaseAddr=PeripheralAddr;//外设地址
DMA_InitStructure.DMA_MemoryBaseAddr=MemoryAddr;//内存地址
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//传输方向:内存到外设
DMA_InitStructure.DMA_BufferSize=BufferSize;//传输长度
DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设累增:NO
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//外设累增:YES
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;//循环模式:NO
DMA_InitStructure.DMA_Priority=DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//内存-内存:NO
DMA_Init(DMA1_Channel2,&DMA_InitStructure);
DMA_Cmd(DMA1_Channel3,ENABLE);//使能DMA传输
}
通过以上两个函数可以初始化两个通道,一个从内存到外设,一个从外设到内存。
当然在我们调用这两个通道的时候需要知道一些东西。
1.有关通道的信息: