STM32之DMA
一、DMA简介
1、DMA简介
DMA(Direct Memory Access:直接内存存取)是一种可以大大减轻CPU工作量的数据转移方式。
CPU有转移数据、计算、控制程序转移等很多功能,但其实转移数据(尤其是转移大量数据)是可以不需要CPU参与。比如希望外设A的数据拷贝到外设B,只要给两种外设提供一条数据通路,再加上一些控制转移的部件就可以完成数据的拷贝。
DMA就是基于以上设想设计的,它的作用就是解决大量数据转移过度消耗CPU资源的问题。有了DMA使CPU更专注于更加实用的操作--计算、控制等。
2、DMA的工作原理
DMA的作用就是实现数据的直接传输,而去掉了传统数据传输需要CPU寄存器参与的环节,主要涉及四种情况的数据传输,但本质上是一样的,都是从内存的某一区域传输到内存的另一区域(外设的数据寄存器本质上就是内存的一个存储单元)。四种情况的数据传输如下:
- 外设到内存
- 内存到外设
- 内存到内存
- 外设到外设
当用户将参数设置好,主要涉及源地址、目标地址、传输数据量这三个,DMA控制器就会启动数据传输,传输的终点就是剩余传输数据量为0(循环传输不是这样的)。换句话说只要剩余传输数据量不是0,而且DMA是启动状态,那么就会发生数据传输。
3、DMA是否影响CPU的运行
在X86架构系统中,当DMA运作时(假设我们从磁盘拷贝一个文件到U盘),DMA实际上会占用系统总线周期中的一部分时间。也就是说,在DMA未开启前,系统总线可能完全被CPU使用;当DMA开启后,系统总线要为DMA分配一定的时间,以保证DMA和CPU同时运作。那么显然,DMA会降低CPU的运行速度。
在STM32控制器中,芯片采用Cortex-M3架构,总线结构有了很大的优化,DMA占用另外的总线,并不会与CPU的系统总线发生冲突。也就是说,DMA的使用不会影响CPU的运行速度。
二、STM32的DMA结构
1、DMA的主要特性
● 12个 独立的可配置的通道(请求)DMA1有7个通道,DMA2 有5个通道
● 每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过
软件来配置。
● 在七个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),假如在相
等优先权时由硬件决定(请求0优先于请求1,依此类推) 。
● 独立的源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标
地址必须按数据传输宽度对齐。
● 支持循环的缓冲器管理
● 每个通道都有3个事件标志(DMA 半传输,DMA传输完成和DMA传输出错),这3个事件标志
逻辑或成为一个单独的中断请求。
● 存储器和存储器间的传输
● 外设和存储器,存储器和外设的传输
● 闪存、SRAM 、外设的SRAM 、APB1 APB2和AHB外设均可作为访问的源和目标。
● 可编程的数据传输数目:最大为65536
下面为功能框图:
2、两个DMA控制器结构
① DMA1 controller

② DMA2 controller

3、DMA寄存器列表

① 中断类
DMA_ISR: DMA中断状态寄存器
DMA_IFCR: DMA中断标志位清除寄存器
说明: DMA1、DMA2分别有一组寄存器。
② 控制传输类
DMA_CCRx: DMA通道x配置寄存器
DMA_CNDTRx: DMA通道x数据数量寄存器
DMA_CPARx: DMA通道x外设地址寄存器
DMA_CMARx: DMA通道x内存地址寄存器
说明:
1> 每一个通道都有一组寄存器。
2> DMA_CPARx、DMA_CMARx是没有差别的,它们都可以存放外设的地址、内存的地址。DMA_CPARx、DMA_CMARx只不过起得名字有差别而已。
4、STM32的DMA工作特点
① DMA进行数据传输的必要条件
- 剩余传输数据量大于0
- DMA通道传输使能
- 通道上DMA数据传输有事件请求
前两者都好理解,对于第三点确实需要详细的解释,请看下边的三条。
② 外设到XX方向的传输
假设是ADC到存储器的数据传输,显然ADC的DMA传输的源地址是ADC的数据寄存器。并不是说只要DMA通道传输使能后,就立即进行数据传输。只有当一次ADC转化完成,ADC的DMA通道的传输事件有效,DMA才会从ADC的数据寄存器读出数据,写入目的地址。当DMA在读取ADC的数据寄存器时,同时使ADC的DMA通道传输事件无效。显然,要等到下一次ADC转换完成后,才能启动再一次的数据传输。
③存储器对XX的DMA传输
因为数据是准备好的,不像ADC还需要等待数据到位。所以,不需要对应通道的事件。只要使能DMA数据传输就一直传输,直到达到设定的传输量。
example:
1.内存到内存
DMA传输请求一直有效
2.内存到串口
DMA传输请求一直有效
一种解释:
存储器对存储器的置位,就相当于相应通道的事件有效。 对应通道的事件有效和存储器对存储器的置位,就是传输的触发位。每次传输的事件置位一次,完成一次传输。如果是由外设引发的DMA传输,则传输完成后,相应传输事件会置为无效,而存储器对存储器的传输,则一次传输完成后,相应事件一直有效,直至完成设定的传输量。 摘自:http://bbs.21ic.com/icview-400841-1-1.html
④外设以DMA方式工作时,能否再以软件方式进行操作?
有一点是肯定的,当外设以DMA方式正在数据传输时,不可能再相应CPU的软件控制命令,否则这不符合逻辑。
但是,倘若外设仅仅配置成DMA工作方式,但是DMA请求并未产生,数据传输并没有进行。此时,软件控制命令仍然能够对外设进行控制。这是笔者在串口以DMA方式发送数据情形下,所得到的测试结论。
三、STM32的DMA软件编程
1、“内存到内存”模式传输
① 初始化配置
uint8_t SendBuff[SENDBUFF_SIZE];
uint8_t ReceiveBuff[RXBUFF_SIZE];
/**
* @brief USART1 TX DMA 配置,内存到内存
* @param 无
* @retval 无
*/
void DMA_Mem2Mem_Config(void)
{
DMA_InitTypeDef DMA_InitStructure; /*开启DMA时钟*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /*设置DMA源地址*/
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SendBuff; /*设置DMA目的地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ReceiveBuff; /*方向:从内存SendBuff到内存ReceiveBuff*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; /*传输大小DMA_BufferSize=SENDBUFF_SIZE*/
DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE; /*ReceiveBuff地址自增*/
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; /*SENDBUFF_SIZE地址自增*/
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /*ReceiveBuff数据单位*/
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; /*SENDBUFF_SIZE数据单位*/
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /*DMA模式:正常模式*/
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ; /*优先级:中*/
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; /*使能内存到内存的传输 */
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable; /*配置DMA1的4通道*/
DMA_Init(DMA1_Channel4, &DMA_InitStructure); /*失能DMA1的4通道,一旦使能就开始传输*/
DMA_Cmd (DMA1_Channel4,DISABLE);
}
② DMA中断配置
/**
* @brief DMA 中断配置
* @param 无
* @retval 无
*/
void DMA_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure; /* 配置中断源 */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); /* 配置DMA发送完成后产生中断 */
DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);
}
③启动传输
DMA_Cmd (DMA1_Channel4,ENABLE);
2、利用DMA实现循环传输
方法1:单次传输模式
当传输结束时,触发DMA中断,在中断程序中首先失能DMA通道,然后修改该通道的传输数据量。最后重新使能DMA通道,注意只有失能的DMA通道才能成功修改传输数据量。
方法2:循环传输模式
当传输结束时,硬件自动会将传输数据量寄存器进行重装,进行下一轮的数据传输。
四、再谈STM32的DMA传输是否影响CPU的运行速度
声明:经过笔者测试,当DMA工作在内存到外设的传输和内存到内存的传输时,都不会影响CPU的运行速度。为了给这种现象一个合理的解释,笔者做以下猜测:
1、S3C2440的DMA传输
S3C2440的SDRAM是外置的,并且SDRAM的数据线、地址线、控制线总共只有一组。假设DMA传输的方向是内存到外设,当DMA运作时,需要占用SDRAM的三类线才才能实现传输;而与此同时CPU也需要通过这三类线来访问SDRAM来读取程序、读写数据。
显然,DMA的运行与CPU的运行有交叉点,DMA就会影响到CPU的运行。
2、STM32的DMA传输
STM32与S3C2440的区别是很大的,S3C2440是微处理器,RAM外置且空间很大;STM32是微控制器,RAM片内集成且空间较小。此时,ST公司就有可能提升DMA的运作效率,使DMA的工作不影响到CPU的运行。
外设与外设之间的DMA传输,因为与CPU的运行没有交叉点(CPU的数据流注意是在Flash、内存、寄存器中传输),所以不会影响CPU的运行速度。唯一有可能影响的是外设与内存或者内存与内存之间的DMA传输。
倘若ST公司的SRAM是一个双口RAM,也就是同时可以由两组接口对RAM进行访问,就可以很好的解决速度影响问题。倘若CPU恒定占有一组接口,而另一组接口留给DMA控制器。那么当外设与内存或者内存与内存之间的DMA传输时,由于不与CPU的访问SRAM接口冲突,所以可以解决速度影响问题。
但其实偶尔还是会影响的,当CPU访问SRAM的空间和DMA访问SRAM的空间相同时,SRAM势必会对这种情况进行仲裁,这可能会影响到CPU的访问SRAM的速度。其实,这种情况的概率也是很小的,所以即使影响CPU的运行速度,也不会很大。
参考资料:《STM32参考手册》
STM32之DMA的更多相关文章
- STM32之DMA+ADC
借用小甲鱼的经典:各位互联网的广大网友们.大家早上中午晚上好..(打下小广告,因为小甲鱼的视频真的很不错).每次看小甲鱼的视频自学都是比较轻松愉快的..我在想,如果小甲鱼出STM32的视频,我会一集不 ...
- STM32使用DMA发送串口数据
1.概述 上一篇文章<STM32使用DMA接收串口数据>讲解了如何使用DMA接收数据,使用DMA外设和串口外设,使用的中断是串口空闲中断.本篇文章主要讲解使用DMA发送数据,不会讲解基础的 ...
- STM32的DMA
什么是DMA?其全称是:Direct Memory Access:根据ST公司提供的相关信息,DMA是STM32中一个独立与Cortex-M3内核的模块,有点类似与ADC.PWM.TIMER等模块:主 ...
- STM32 串口DMA方式接收(转)
STM32 是一款基于ARM Cortex-M3内核的32位MCU,主频最高可达72M.最近因为要在车机上集成TPMS功能, 便开始着手STM32的开发工作,STM32F10x系列共有5个串口(USA ...
- STM32 基DMA的DAC波形发生器
DAC是STM32系列的一个基本外设,可以将数字信号转化成模拟信号,这次我将使用DAC来输出一个特定波形. 首先确定工作方法,由于我目前在做的简易示波器在输出波形的同时还需要显示输入信号,所以不能占用 ...
- STM32 UART DMA实现未知数据长度接收
串口通信是经常使用到的功能,在STM32中UART具有DMA功能,并且收发都可以使用DMA,使用DMA发送基本上大家不会遇到什么问题,因为发送的时候会告知DMA发送的数据长度,DMA按照发送的长度直接 ...
- stm32的DMA传输一半中断
这里本想做一个录音程序 硬件很简单: MIC(麦克风)放大滤波电路---->stm32的ADC----->DMA通道----->一个数组缓存------->通过FATFS的 ...
- STM32之DMA实例
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/zouleideboke/article/details/75092558 DMA简介: DMA(Di ...
- STM32串口DMA接收数据错位——暴力解决方法
背景:两片STM32通过串口通信,为了减小CPU负担,采用DMA进行通信,发送端为STM32F103C8T6,接收端为STM32F407VET6.在调试的过程中发现,一直出现数据错位的问题,接收端尝试 ...
随机推荐
- Delphi 调用批处理
uses ShellApi; procedure TForm1.Button1Click(Sender: TObject); var filename, Path: string; begin fil ...
- MAC OS X 终端命令入门 (简单常用整理)
在这里记下..防止丢失 pwd 当前工作目录 cd(不加参数) 进root cd(folder) 进入文件夹 cd .. 上级目录 cd ~ 返回root cd - 返回上一个访问的目录 rm 文件名 ...
- mysql init_connect 参数的其他用处
http://blog.itpub.net/133735/viewspace-691196/ init_connect 是可以动态在线调整的,这样就有了一些其他的用处 经过测试init_conne ...
- 如何运用管理员身份运行cmd窗口?
所有程序 → 附件 → 命令行提示符 → 鼠标右键“以管理员身份运行”.
- Java immutable class
可变类:类的实例创立之后,还可以修改这个实例的内容. 比如创建一个3*3的矩阵,如果设立了set function,在main中可以用set更改对应位置元素的大小. 不可变类:就是类的实例一旦被建立, ...
- [整理]Oracle LOCK 机制
数据库是一个多用户使用的共享资源.当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性.锁机制用于管理对 ...
- C++ notes for beginners
作者:马 岩(Furzoom) (http://www.cnblogs.com/furzoom/)版权声明:本文的版权归作者与博客园共同所有.转载时请在明显地方注明本文的详细链接,未经作者同意请不要删 ...
- 使用的 SQL Server 版本不支持数据类型“datetime2”解决办法
不论下方提示什么数据格式有错误,一般都是entity生成的时候的问题.比如服务器上用的sql2005,自己用的2008. 解决方法: model层生成的model.edmx文件,用记事本打开, 将&l ...
- How to fix “The program can’t start because MSVCR110.dll is missing from your computer.” error on Windows
原文出处 How to fix “The program can’t start because MSVCR110.dll is missing from your computer.” error ...
- webrtc学习——RTCPeerConnection
The RTCPeerConnection interface represents a WebRTC connection and handles efficient streaming of da ...