原创 STM32学习笔记(12)-DMA初步

2010-7-27 16:22 8041 3 3 分类: MCU/ 嵌入式

  DMA部分我用到的相对简单,当然,可能这是新东西,我暂时还用不到它的复杂功能吧。下面用问答的形式表达我的思路。


DMA有什么用?


       直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。


有多少个DMA资源?


       有两个DMA控制器,DMA1有7个通道,DMA2有5个通道。


数据从什么地方送到什么地方?


       外设到SRAM(I2C/UART等获取数据并送入SRAM);


       SRAM的两个区域之间;


       外设到外设(ADC读取数据后送到TIM1控制其产生不同的PWM占空比);


       SRAM到外设(SRAM中预先保存的数据送入DAC产生各种波形);


       ……还有一些目前还搞不清楚的。


DMA可以传递多少数据?


       传统的DMA的概念是用于大批量数据的传输,但是我理解,在STM32中,它的概念被扩展了,也许更多的时候快速是其应用的重点。数据可以从1~65535个。


通道是如何分配的?


       见下面的这个表:


5a96d8bb-693d-46c5-b98b-6dbb65e79e7f.jpg


7339b6d8-0154-4cc1-913c-9c05c9a9cc51.jpg




如何来用DMA?


       确定数据来源,确定数据目的地,选择使用哪个通道,设定传输多少个数据,设定数据传递模式等等就可以了。且读一下STM32提供给我们的例子。


//////////////////////////////////////////


……


  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_CCR3_Address;


  //设定外围设备的地址


  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SRC_Buffer;


  //设定内存地址,SRC_Buffer是前面定义的一个数组


  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //方向控制


  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_PeripheralDataSize_HalfWord的值为0x100,后一个为0x400,在在stm32f10x_dma.h中定义,用于决定存储器数据宽度*/


  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;


  DMA_InitStructure.DMA_Priority = DMA_Priority_High;


  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;


 


这些设置将会对CCRx寄存器进行操作,如下图所示:


fc41e033-5285-4c92-89a5-387b759d90f0.jpg


c96f8ee5-ca05-4a4d-a56d-ec8bc39148d6.jpg


以下是stm32f10x_dma.c中有关DMA的初始化设置代码


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;


 /////看到了,这里对CCR寄存器进行了写操作,它把上面的那些设置都设定进去了。


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


  /* Write to DMAy Channelx CNDTR */


  DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize;


 13c2e027-a067-4fb4-8a98-72f58f912c69.jpg



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


  /* Write to DMAy Channelx CPAR */


  DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr;


9dbf5b59-a694-4438-82b6-b88c45f2ac3e.jpg



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


/* Write to DMAy Channelx CMAR */


  DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr;


//内存地址送入CMAR寄存器


 fba1b509-d02c-4686-bc6b-b33e54560d25.jpg  



说明:这个图从PDF截下来,图中那个DMA_CPARx写错了,应该是DMA_CMARx


------------------------------------------------------------------------------------------


再来看一个DMA的例子


  /* DMA1 Channel5 configuration ----------------------------------------------*/


  DMA_DeInit(DMA1_Channel5);


  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_CCR1_Address;


  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC1_DR_Address;


  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;


  DMA_InitStructure.DMA_BufferSize = 1;


  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;


  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;


  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_Channel5, &DMA_InitStructure);


  /* Enable DMA1 Channel5 */


  DMA_Cmd(DMA1_Channel5, ENABLE);


还有一些目前暂时还没有去搞清楚的,比如中断处理等,等到需要时再看吧。

文章评论0条评论)

登录后参与讨论
相关推荐阅读
teach51_109853927 2015-10-25 22:37
带“锁定输出”的数控稳压电源(二)
3.控制程序编写        硬件电路设计完成后,就要编写软件了。软件基本上可以分为键盘驱动,PWM生成,功能实现等部分。 3.1 键盘处理程序        STC单片机的引脚可以...
teach51_109853927 2014-03-02 12:17
带“锁定输出”的数控稳压电源(一)
本文是探索“开源培训”思想的作品。 所谓“开源培训”是指在某个社区,各志愿者提供有一定实用价值和教学价值的作品,同时详细说明制作过程,并提供制作所需的各类资源,帮助入门者快速找到适合自己的项目...
teach51_109853927 2014-02-22 21:15
《单片机项目教程》、《单片机项目教程C语言版》电子课件
《单片机项目教程》电子课件 http://pan.baidu.com/s/1kT2Yb6f 《单片机项目教程C语言版》电子课件 http://pan.baidu.com/s/1gd5O...
teach51_109853927 2014-02-22 21:05
《单片机应用与接口技术》相关资源
单片机应用与接口技术    机械工业出版社出版,江苏省教育厅推荐教材 《单片机应用与接口技术》课件 http://pan.baidu.com/s/1c0kpzUg 《单片机应用与接...
teach51_109853927 2014-02-22 15:25
便携式无线抢答器
本产品专门为开展活动时需要用到抢答器的场合设计,已制作成品,读者可以参考作为练手之用。 如图1所示左边为信号接收装置(主持人用),右边两个为发射装置(比赛选手用)。都只需要使用干电池供电即可。...
teach51_109853927 2014-02-22 15:22
Modbus通讯协议
Modbus协议最初由Modicon公司开发出来,在1979年末该公司成为施耐德自动化(Schneider Automation)部门的一部分,现在Modbus已经是工业领域全球最流行的协议。此协...
广告
我要评论
0
3
1
2
3
4
5
6
7
8
9
0
广告
关闭 热点推荐上一条 /5 下一条