datasheet

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

2019-01-04来源: eefocus关键字:STM32  标准库  DMA配置

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



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



DMA_ISR:  0x4002 0000

DMA_IFCR  0x4002 0004

 

DMA_CCR1:      0x4002 0008

DMA_CNDTR1: 0x4002 000C

DMA_CPAR1:    0x4002 0010

DMA_CMAR1:   0x4002 0014


接下来,我们去STM32的程序中来分析下DMA配置的详细过程:


我们主要详细的讲解下两个配置函数:DMA_Configuration()和DMA_Init()这两个函数,废话少说,先贴两个函数的代码上来。


void DMA_Configuration(void)

{

DMA_InitTypeDef DMA_InitStructure;

/* DMA channel1 configuration */ 

DMA_DeInit(DMA1_Channel1);//重置DMA的寄存器的值,配置为缺省值

DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)&ADC1->DR; /*设置 DMA 外设基地址,即为转换结果的寄存器*/

DMA_InitStructure.DMA_MemoryBaseAddr =(u32)&AD_Value;/*定义内存基地址*/

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; /*定义AD外设作为数据传输的来源*/

DMA_InitStructure.DMA_BufferSize = N*M;/*指定DMA通道DMA缓存的大小,即需要开辟几个内存空间*/

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /*寄存器地址国定*/

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /*设定内存地址递增,即每次DMA都是将*/

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;/* 定义外设和内存的数据宽度*/

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;/*设定DMA工作再循环缓存模式*/

DMA_InitStructure.DMA_Priority = DMA_Priority_High;/*设定DMA选定的通道的软件优先级*/

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//关闭内存到内存的传输   

DMA_Init(DMA1_Channel1, &DMA_InitStructure);

DMA_Cmd(DMA1_Channel1, ENABLE);/* Enable DMA channel1 */

}

void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)

{

  uint32_t tmpreg = 0;

/*--------------------------- DMAy Channelx CCR Configuration -----------------*/

  /* Get the DMAy_Channelx CCR value */

  tmpreg = DMAy_Channelx->CCR;

  /* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */

  tmpreg &= CCR_CLEAR_Mask;

  /* Configure DMAy Channelx: data transfer, data size, priority level and mode */

  /* Set DIR bit according to DMA_DIR value */

  /* Set CIRC bit according to DMA_Mode value */

  /* Set PINC bit according to DMA_PeripheralInc value */

  /* Set MINC bit according to DMA_MemoryInc value */

  /* Set PSIZE bits according to DMA_PeripheralDataSize value */

  /* Set MSIZE bits according to DMA_MemoryDataSize value */

  /* Set PL bits according to DMA_Priority value */

  /* Set the MEM2MEM bit according to DMA_M2M value */

  tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode |

            DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc |

            DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize |

            DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M;

 

  /* Write to DMAy Channelx CCR */

  DMAy_Channelx->CCR = tmpreg;

 

/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/

  /* Write to DMAy Channelx CNDTR */

  DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize;

 

/*--------------------------- DMAy Channelx CPAR Configuration ----------------*/

  /* Write to DMAy Channelx CPAR */

  DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr;

 

/*--------------------------- DMAy Channelx CMAR Configuration ----------------*/

  /* Write to DMAy Channelx CMAR */

  DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr;

}

  

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



typedef struct

{

  __IO uint32_t CCR;

  __IO uint32_t CNDTR;

  __IO uint32_t CPAR;

  __IO uint32_t CMAR;

} DMA_Channel_TypeDef;

DMA_InitTypeDef  DMA_InitStructure;

typedef struct

{

  uint32_t DMA_PeripheralBaseAddr;

  uint32_t DMA_MemoryBaseAddr;   

  uint32_t DMA_DIR;  

  uint32_t DMA_BufferSize;   

  uint32_t DMA_PeripheralInc;   

  uint32_t DMA_MemoryInc;   

  uint32_t DMA_PeripheralDataSize; 

  uint32_t DMA_MemoryDataSize;    

  uint32_t DMA_Mode;    

  uint32_t DMA_Priority;      

  uint32_t DMA_M2M;                                                  

}DMA_InitTypeDef;



关键字:STM32  标准库  DMA配置

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/2019/ic-news010442772.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:stm32学习笔记---计数器定时中断(1s)
下一篇:stm32 DMA初始化选项研究

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32堆栈设置

1.堆和栈大小 定义大小在startup_stm32f2xx.sStack_Size      EQU     0x00000400                AREA    STACK, NOINIT, READWRITE, ALIGN=3Stack_Mem      
发表于 2019-04-16
STM32堆栈设置

STM32堆和栈(Heap & Stack)的资料理解

源起:在移植cjson的过程中,解析json包的时候发现动态内存分配不足而导致解析失败,为解决这一问题,而深入了解stm32的堆和栈。stm32的存储器结构。Flash,SRAM寄存器和输入输出端口被组织在同一个4GB的线性地址空间内。可访问的存储器空间被分成8个主要块,每个块为512MB。FLASH存储下载的程序。SRAM是存储运行程序中的数据。而SRAM一般分这几个部分:静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率
发表于 2019-04-16
STM32堆和栈(Heap & Stack)的资料理解

STM32定义堆栈地址到ram区顶部

本设置针对stm32f103rbt6的设置,该芯片RAM大小为20kB,故RAM区地址范围为0x20000000—0x20005000,芯片信息如下图所示;第一步:设置.sct文件;;*************************************************************; *** Scatter-Loading Description Filegenerated by uVision ***; *************************************************************LR_IROM1 0x08000000 0x00020000  
发表于 2019-04-16
STM32定义堆栈地址到ram区顶部

STM32之程序如何防止堆栈溢出

近日为某个项目写了个草稿程序,即非正式程序,后来发现老是进入hardfaulthandler,原来是堆栈溢出,后仔细查看发现函数调用纵深太深,最多的时候可保持7个函数在堆栈中调用。因此有心得如下:一、函数调用不要纵深太深,即以下模式:main(){   fun1();}fun1(){  fun2();}fun2(){   fun3();}fun3(){  fun4();}fun4(){  fun5();}fun5(){  fun6();}fun6(){   fun7();}这样子main函数要调用fun1函数完成某个功能,则要一直调到
发表于 2019-04-16

stm32之堆栈

stm32中的堆栈设置keil编译完成时存储情况当编译成功时,会出现: BUILD://Program Size: Code=340 RO-data=252 RW-data=0 ZI-data=1632Code:程序代码部分RO-data: 程序定义的常量const tempRW-data:已初始化的全局变量ZI-data:未初始化的全局变量片中的:flash=Code+RO-data+RW-dataRAM=RW-data+ZI-data通过上面的BUILD可以看出,这个程序已经用了1600多的RAM,为什么会出用到这么多的RAM呢?在startup_stm32f10x_md.s文件中存在:St
发表于 2019-04-16

说说STM32的堆栈与内存

1.概念这里所说的堆栈,是针对单片机所说的“堆”与“栈”,指的是内存中一片特殊用途的区域。而不是数据结构中的堆栈(虽然其实规则一样)。这里所说的内存,是指RAM,RAM包括SRAM,DRAM等。而不是什么手机内存卡之类。这里所说的flash,指的是用作为ROM的存储器,保存代码与常量数据。而不是动画制作。。。栈的生长方向:指的是入栈方向,从高地址向低地址生长叫做向下生长,或逆向生长;反过来就叫向上生长,或正向生长。STM32的栈是向下生长。2.内存中的堆栈安排确切地说,是keil mdk根据STM32的特性,对stm32的RAM甚至flash进行部署。编译工程后,在生成的.map文件里可以看到具体的安排。双击工程界面的工程根目录
发表于 2019-04-16
说说STM32的堆栈与内存

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved