自己现在一直在学习STM32,对他的各个模块已经有了一个基本的了解,现在我把STM32DMA这块的东西跟大家分享一下。首先,咱们先来看看STM32中对DMA的介绍 DMA(Direct Memory Access,直接内存存取)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输,数据可以通过DMA快速的移动,这样就能够节省CPU的资源,然CPU来专心干一些其他更有意思的事情。
下面我们再来具体看一看STM32中它的特性有那些呢
1、一共有12个独立的可配置通道,DMA1有7个通道,DMA2有5个通道。
2、每一个通道都有与至直接连接的硬件DMA请求,当然每个通道同样也支持软件触发
3、在同一个DMA通道上,多个通道上的优先权可以通过软件来配置,优先权一共有四组(很高,高,中等和低),当优先权相等的时候,这个时候就由硬件来决定了。
4、数据源和目标数据区的传输宽度可以设为3种,字节(8),半字(16),全字(32).源地址和目标地址必须和数据数据传输宽度所对齐。
5、能够支持循环的缓冲器管理
6、每个通道都有三个事件标志,DMA半传输、DMA传输完成、DMA传输出错,这三个事件可以成为一个单独的中断请求。
7、可以在存储器和存储器之间,外设和存储器,存储器和外设之间进行传输
8、flash、SRAM、外设的SRAM、APB1、APB2、和AHB外设都可以作为访问的源和目标地址。
9、可以编程的数据传输数目:最大为65535。
DMA框图如下,其实大家一看他的框图对他的结构就基本了解了。
从图中我们可以看出,DMA控制器和Cortex-M3共享系统数据总线,直接进行数据的传输。当CPU和DMA同时访问相同的目标时,DMA请求会暂停CPU访问系统总线若干个周期,这个时候总线总裁器将起到作用,它将执行循环调度,以保证CPU至少可以得到一半的系统总线的带宽。
DMA控制器和外设通过握手以后将启动DMA传输,DMA的传输过程大体可以分为3个步骤。
1、从某一个位置取出数据,这个位置可以为外设数据寄存器或者其他存储地址。
2、把数据放到某一个位置,这个位置同上描述一样
3、在寄存器里执行一次递减操作,此寄存器里包含着未传输完成的数据个数。
对DMA通道的具体使用是有一定的步骤和模块的,下面我已UART的DMA为例,介绍一下DMA的配置过程,这个相信大家一个就会明白。
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA1时钟
DMA_DeInit(DMA1_Channel4); //默认初始化DMA1通道4
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(USART1->DR);; //定义通道的外设基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)TxBuffer1; //定义通道的存储器基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //指定外设为目的地址
DMA_InitStructure.DMA_BufferSize = num; //通道缓冲区数据单元大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设寄存器地址不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //当前存储寄存器地址增加
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据宽度为8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据宽度为8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //使用正常缓冲模式
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //DMA通道优先级非常高
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止存储器到存储器传输
DMA_Init(DMA1_Channel4, &DMA_InitStructure); //初始化DMA1
通过以上配置就可以对DMA进行应用了!
文章评论(0条评论)
登录后参与讨论