版权归如下公司,禁止非授权转载:
- 北京西普阳光教育科技股份有限公司(https://www.simpleware.com.cn)
- 维周机器人科技有限公司(http://www.vejoe.com)
文章目录
【实验目的】
- 掌握单片机DMA的工作原理,以及在STM32单片机上实现DMA传输的配置和流程;
- 了解DMA传输方式相对与传统利用CPU传输方式的优势;
- 完成以 DMA 的方式给数据赋值并显示在OLED显示屏上的实验。
【实验原理】
DMA (Direct Memory Access),直接存储器存取,是一种可以大大减轻CPU 工作量的数据存取方式,因而被广泛地使用。外设工作的时候,除了转移数据,实质上是不需要内核进行干预的,而如果数据转移的工作现在也交给了另一个外设,那么在该外设进行工作的时候,内核同时还可以进行其它操作。而STM32 的 DMA 模块正是以类似外设的形式,添加到 Cortex 内核之外,进行数据转移工作的。
一、DMA功能简介:
单片机的硬件系统,通常主要由 CPU(内核)、外设、内存(SRAM)、总线等结构组成,在系统工作中,数据经常要在各项设备之间进行转移。通常情况下,在转移数据的过程中会占用 CPU 十分宝贵的资源,所以我们希望 CPU 更多地被用在数据运算或响应中断之中,而数据转移的工作交由其它部件完成。DMA 恰恰为 CPU 分担了这部分数据转移的工作。因为 DMA 的存在, CPU 被解放出来,它可以在 DMA 转移数据的过程中同时进行数据运算,响应中断,大大提高了系统的运行效率。
在 STM32 中,DMA 的传输模式分为3种:
- 外设到存储器的传输。
- 存储器到存储器的传输。
- 存储器到外设的传输。
二、DMA工作过程分析
由 DMA 控制器挂载在AHB(高级高性能总线)上,与内核共享数据总线。DMA控制器在收到一个传输命令后,开始访问源地址寄存器中储存的地址,并加载该地址对应的数据,然后将数据存储到目标地址寄存器中指定的地址上去。在完成一次数据转移后,DMA内记录数据总数的寄存器执行一次减一操作,然后根据预先设定的传输模式决定是否对源/目标地址进行位移操作。例如,若是从外设(GPIO或其他有固定接口的设备)到存储器的传输,则在执行一次操作后,只需目标地址进行位移,源地址不变;而若是从存储器到存储器的传输,则需要同时将源地址和目标地址进行位移。
三、DMA库函数分析
DMA_InitTypeDef结构体参数的配置如下:
typedef struct
{
uint32_t DMA_PeripheralBaseAddr; // DMA 外设基地址
uint32_t DMA_MemoryBaseAddr; //DMA 内存基地址
uint32_t DMA_DIR; //规定了外设是作为数据传输的目的地还是来源
uint32_t DMA_BufferSize; // DMA 缓存的大小
uint32_t DMA_PeripheralInc; // 外设地址寄存器递增与否
uint32_t DMA_MemoryInc; // 内存地址寄存器递增与否 uint32_t DMA_PeripheralDataSize; // 外设数据宽度
uint32_t DMA_MemoryDataSize; // 内存数据宽度
uint32_t DMA_Mode; // 工作模式
uint32_t DMA_Priority; // DMA 软件优先级
uint32_t DMA_M2M; //非否内存到内存传输
}DMA_InitTypeDef;
- DMA_PeripheralBaseAddr:外设地址,设定 DMA_CPAR 寄存器的值;一般设置为外设的数据寄存器地址,如果是存储器到存储器模式则设置为其中一个存储器地址。
- DMA_Memory0BaseAddr:存储器地址,设定 DMA_CMAR 寄存器值;一般设置为我们自定义存储区的首地址。
- DMA_DIR:传输方向选择,可选外设到存储器、存储器到外设。它设定DMA_CCR 寄存器的 DIR[1:0]位的值。 这里并没有存储器到存储器的方向选择,当使用存储器到存储器时,只需要把其中一个存储器当作外设使用即可。
- DMA_BufferSize:设定待传输数据数目,初始化设定 DMA_CNDTR 寄存器的值。
- DMA_PeripheralInc:如果配置为 DMA_PeripheralInc_Enable,使能外设地址自动递增功能,它设定 DMA_CCR 寄存器的 PINC 位的值;一般外设都是只有一个数据寄存器,所以一般不会使能该位。
- DMA_MemoryInc:如果配置为 DMA_MemoryInc_Enable,使能存储器地址自动递增功能,它设定 DMA_CCR 寄存器的 MINC 位的值;我们自定义的存储区一般都是存放多个数据的,所以要使能存储器地址自动递增功能。
- DMA_PeripheralDataSize: 外设数据宽度,可选字节(8 位)、半字(16位)和字(32位),它设定 DMA_CCR 寄存器的 PSIZE[1:0]位的值。
- DMA_MemoryDataSize:存储器数据宽度,可选字节(8 位)、半字(16 位)和字(32位),它设定 DMA_CCR 寄存器的 MSIZE[1:0]位的值。 当外设和存储器之间传数据时,两边的数据宽度应该设置为一致大小。
- DMA_Mode: DMA 传输模式选择,可选一次传输或者循环传输,它设定DMA_CCR 寄存器的 CIRC 位的值。 例程我们的 ADC 采集是持续循环进行的,所以使用循环传输模式。
- DMA_Priority:软件设置通道的优先级,有 4 个可选优先级分别为非常高、高、中和低,它设定 DMA_CCR 寄存器的 PL[1:0]位的值。 DMA 通道优先级只有在多个 DMA 通道同时使用时才有意义,如果是单个通道,优先级可以随便