STM32标准库中DMA配置详解 (标准库版)

时间:2024-11-16 07:54:43

  写博客Mark下自己对STM32中DMA功能的一些分析: 

        先看上图中下左侧的偏移地址,偏移地址是相对于DMA1_BASE的相对地址。查表可得DMA1_BASE的实际物理地址是:0x4002 0000 .故我们可以得出这些寄存器的实际地址是什么。实际上我们对寄存器配置的时候也是对这几个寄存器值进行修改。

  1. DMA_ISR: 0x4002 0000
  2. DMA_IFCR 0x4002 0004
  3. DMA_CCR1: 0x4002 0008
  4. DMA_CNDTR1: 0x4002 000C
  5. DMA_CPAR1: 0x4002 0010
  6. DMA_CMAR1: 0x4002 0014
接下来,我们去STM32的程序中来分析下DMA配置的详细过程:
我们主要详细的讲解下两个配置函数: DMA_Configuration()和 DMA_Init()这两个函数,废话少说,先贴两个函数的代码上来。
  1. void DMA_Configuration(void)
  2. {
  3. DMA_InitTypeDef DMA_InitStructure;
  4. /* DMA channel1 configuration */
  5. DMA_DeInit(DMA1_Channel1);//重置DMA的寄存器的值,配置为缺省值
  6. DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)&ADC1->DR; /*设置 DMA 外设基地址,即为转换结果的寄存器*/
  7. DMA_InitStructure.DMA_MemoryBaseAddr =(u32)&AD_Value;/*定义内存基地址*/
  8. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; /*定义AD外设作为数据传输的来源*/
  9. DMA_InitStructure.DMA_BufferSize = N*M;/*指定DMA通道DMA缓存的大小,即需要开辟几个内存空间*/
  10. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /*寄存器地址国定*/
  11. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /*设定内存地址递增,即每次DMA都是将*/
  12. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;/* 定义外设和内存的数据宽度*/
  13. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  14. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;/*设定DMA工作再循环缓存模式*/
  15. DMA_InitStructure.DMA_Priority = DMA_Priority_High;/*设定DMA选定的通道的软件优先级*/
  16. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//关闭内存到内存的传输
  17. DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  18. DMA_Cmd(DMA1_Channel1, ENABLE);/* Enable DMA channel1 */
  19. }
  1. void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)
  2. {
  3. uint32_t tmpreg = 0;
  4. /*--------------------------- DMAy Channelx CCR Configuration -----------------*/
  5. /* Get the DMAy_Channelx CCR value */
  6. tmpreg = DMAy_Channelx->CCR;
  7. /* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
  8. tmpreg &= CCR_CLEAR_Mask;
  9. /* Configure DMAy Channelx: data transfer, data size, priority level and mode */
  10. /* Set DIR bit according to DMA_DIR value */
  11. /* Set CIRC bit according to DMA_Mode value */
  12. /* Set PINC bit according to DMA_PeripheralInc value */
  13. /* Set MINC bit according to DMA_MemoryInc value */
  14. /* Set PSIZE bits according to DMA_PeripheralDataSize value */
  15. /* Set MSIZE bits according to DMA_MemoryDataSize value */
  16. /* Set PL bits according to DMA_Priority value */
  17. /* Set the MEM2MEM bit according to DMA_M2M value */
  18. tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode |
  19. DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc |
  20. DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize |
  21. DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M;
  22. /* Write to DMAy Channelx CCR */
  23. DMAy_Channelx->CCR = tmpreg;
  24. /*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/
  25. /* Write to DMAy Channelx CNDTR */
  26. DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize;
  27. /*--------------------------- DMAy Channelx CPAR Configuration ----------------*/
  28. /* Write to DMAy Channelx CPAR */
  29. DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr;
  30. /*--------------------------- DMAy Channelx CMAR Configuration ----------------*/
  31. /* Write to DMAy Channelx CMAR */
  32. DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr;
  33. }

  将上面两个函数比较一下就可以知道,前者函数对于后者来说就相当于是一个中间量的过程,暂时的将需要的配置参数写入一个结构体DMA_InitTypeDef中,后面调用DMA_Init这个函数之后,重新配置物理地址中DMA的寄存器相应的位。下面附录上两个函数中的结构体参数组成。

  1. typedef struct
  2. {
  3. __IO uint32_t CCR;
  4. __IO uint32_t CNDTR;
  5. __IO uint32_t CPAR;
  6. __IO uint32_t CMAR;
  7. } DMA_Channel_TypeDef;
  1. DMA_InitTypeDef DMA_InitStructure;
  2. typedef struct
  3. {
  4. uint32_t DMA_PeripheralBaseAddr;
  5. uint32_t DMA_MemoryBaseAddr;
  6. uint32_t DMA_DIR;
  7. uint32_t DMA_BufferSize;
  8. uint32_t DMA_PeripheralInc;
  9. uint32_t DMA_MemoryInc;
  10. uint32_t DMA_PeripheralDataSize;
  11. uint32_t DMA_MemoryDataSize;
  12. uint32_t DMA_Mode;
  13. uint32_t DMA_Priority;
  14. uint32_t DMA_M2M;
  15. }DMA_InitTypeDef;