DMA的简单了解与认识
DMA就是为了减轻CPU的负担来设置的存储方式。当从外设取到的数据就不需要经过内核操作,而是通过DMA直接把外设的数据放到内存SRAM中,这样就会减少CPU的负担,让CPU在此同时能做更多的事情。(直接存储器)
对于32的学习已经轻车熟路了,这时我们就会开始想到会有一个关于DMA的结构体即DMA_InitTypeDef
这时就会想到对其结构体的参数进行配置
void USART1_DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_Config(); //中断的配置
/开启DMA时钟/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/设置DMA源:串口数据寄存器地址/
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
/内存地址(要传输的变量的指针)/这里一般的话都是变量
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;
/方向“从内存到外设”/ (当外设作为地址的时候)
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
/传输的大小/
DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;
/外设地址不增/
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_Mode = DMA_Mode_Circular;
/优先级为中/
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
/禁止内存到内存传输*/
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
/根据上面配置DMA的4通道/
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
/使能DMA/
DMA_Cmd (DMA1_Channel4,ENABLE);
/配置DMA传输完毕产生中断/
DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);
}
看到这DMA的配置图就知道,先给配置时钟信号(可以在时钟树图上看到DMA是接着AHB上到的)
首先看到的是DMA_PeripheralBaseAddr = USART1_DR_Base
这是MDA源,也就是外设的基地址,对于USART1_DR_Base,我们能看到这是
#define USART1_DR_Base 0x40013804 // 0x40013800 + 0x04 = 0x40013804
也就是这是DR寄存器的基地址=USART1的地址+偏移量
下图是部分基地址
然后看下DR寄存器
可以看到偏移量为0x04
还有一点注意的就是内存到内存的传输,不能和循环检测一起使用。