DMA比较好用,也比较简单,今天在做多通道ADC“连续”“扫描”采样时,对DMA有了更深一点的认识,今天给大家分享下:
#define ADC1_DR_Address ((uint32_t)0x4001244C)
unsigned short Buff[3];
......
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buff;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 3;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
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_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1, ENABLE);
初始化时,要先用DMA_DeInit将DMA的通道初始化成缺省值。
外设地址设置,内存基地址设置,设置外设的传输属性(输入/输出),这些都容易理解;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
#define DMA_DIR_PeripheralDST ((uint32_t)0x00000010)
#define DMA_DIR_PeripheralSRC ((uint32_t)0x00000000)
这里是设置谁为数据传输源;
DMA_InitStructure.DMA_BufferSize = 3;
如果是获取一组数值,像ADC,USART,我们可以用一个缓冲区,如果不用,像ADC数据更新快的,马上就被刷新了。我这里的DMA_Buffersize 是 Buff的大小;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
#define DMA_PeripheralInc_Enable ((uint32_t)0x00000040)
#define DMA_PeripheralInc_Disable ((uint32_t)0x00000000)
#define DMA_MemoryInc_Enable ((uint32_t)0x00000080)
#define DMA_MemoryInc_Disable ((uint32_t)0x00000000)
这个根据需要进行设置;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
#define DMA_PeripheralDataSize_Byte ((uint32_t)0x00000000)
#define DMA_PeripheralDataSize_HalfWord ((uint32_t)0x00000100)
#define DMA_PeripheralDataSize_Word ((uint32_t)0x00000200)
#define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000)
#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00000400)
#define DMA_MemoryDataSize_Word ((uint32_t)0x00000800)
这个设置获取数据的大小;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
#define DMA_Mode_Circular ((uint32_t)0x00000020)
#define DMA_Mode_Normal ((uint32_t)0x00000000)
这个要强调下,像我这里,要不断更新Buff[0],Buff[1],Buff[2],我上面设置的缓冲区正好也是3,我们可以用Circular属性来设置!他就不停的刷新这段地址!
他还有一种属性是Normal,这种属性一般用在Point 2 Point时使用;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
#define DMA_Priority_VeryHigh ((uint32_t)0x00003000)
#define DMA_Priority_High ((uint32_t)0x00002000)
#define DMA_Priority_Medium ((uint32_t)0x00001000)
#define DMA_Priority_Low ((uint32_t)0x00000000)
因为DMA有多路,所以我们要规定先传哪路数据,所以我们就要规定一个优先级;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
#define DMA_M2M_Enable ((uint32_t)0x00004000)
#define DMA_M2M_Disable ((uint32_t)0x00000000)
这个是设置是不是Memary to Memary的!