STM32 DMA

STM32的DMA(Direct Memory Access,直接存储器访问)是一种硬件模块,用于在外设与存储器之间或存储器与存储器之间直接传输数据,无需CPU干预,从而显著提升系统效率和实时性。

一、DMA 核心概念与工作原理

DMA的核心思想是将数据搬运任务从CPU中剥离。传统方式下,CPU需要亲自读取外设数据再写入内存,这会占用大量计算资源。而DMA控制器作为独立的硬件模块,在配置好后,能在外设产生请求时,直接通过系统总线完成数据的读取和写入,整个过程CPU可以处理其他任务。

一次完整的DMA传输包含三个基本操作:1)从源地址(外设寄存器或存储器)取数据;2)将数据存放到目标地址(存储器或外设寄存器);3)递减传输数量计数器。只要传输计数器不为零且DMA通道已使能,传输就会持续进行。

二、STM32 DMA 的主要特性

  1. 多通道与控制器:STM32(如F1系列)通常有1到2个DMA控制器(DMA1和DMA2)。DMA1有7个通道,DMA2有5个通道,每个通道可连接到特定外设(如ADC、USART、SPI等)。
  2. 传输方向:支持外设到存储器、存储器到外设以及存储器到存储器(部分模式限制)三种方向。
  3. 可编程数据宽度:传输的数据单元可以是字节(8位)、半字(16位)或字(32位),源和目标的数据宽度可以独立设置。
  4. 地址递增模式:可以设置外设地址和存储器地址在每次传输后是否自动递增。通常,外设(如数据寄存器)地址固定,而存储器(如数组)地址需要递增以存放连续数据。
  5. 传输模式
    • 单次模式 (Normal):传输指定数量的数据后停止,需要重新配置才能再次启动。
    • 循环模式 (Circular):传输完成后自动重装计数器,从初始地址开始新一轮传输,适用于ADC连续采样等场景。
  6. 优先级管理:每个通道的优先级可通过软件设置(非常高、高、中、低)。当多个通道同时请求时,先比较软件优先级;若相同,则通道编号小的拥有更高的硬件优先级。
  7. 中断与事件:每个通道可以产生三种事件标志:半传输完成、传输完成和传输错误。这些标志可以触发中断,方便CPU在传输关键节点进行处理。

三、DMA 配置关键结构体成员(以标准库为例)

配置DMA时,需要初始化一个结构体(DMA_InitTypeDef),其核心成员与功能如下:

结构体成员 功能描述 对应寄存器/常见设置
DMA_PeripheralBaseAddr 外设数据寄存器地址。例如,串口传输设为 &USART1->DR;ADC传输设为 &ADC1->DR DMA_CPARx
DMA_Memory0BaseAddr 存储器基地址,通常是自定义数组的首地址。 DMA_CMARx
DMA_DIR 传输方向:外设到存储器、存储器到外设等。 DMA_CCRx 的 DIR 位
DMA_BufferSize 要传输的数据数量。 DMA_CNDTRx
DMA_PeripheralInc 外设地址是否递增。通常设为 Disable(外设寄存器固定)。 DMA_CCRx 的 PINC 位
DMA_MemoryInc 存储器地址是否递增。通常设为 Enable(用于存储数据数组)。 DMA_CCRx 的 MINC 位
DMA_PeripheralDataSize 外设数据宽度:字节、半字或字。 DMA_CCRx 的 PSIZE 位
DMA_MemoryDataSize 存储器数据宽度:字节、半字或字。 DMA_CCRx 的 MSIZE 位
DMA_Mode 传输模式:单次模式 (Normal) 或循环模式 (Circular)。 DMA_CCRx 的 CIRC 位
DMA_Priority 通道优先级:低、中、高、非常高。 DMA_CCRx 的 PL 位
DMA_M2M 是否使能存储器到存储器模式。 DMA_CCRx 的 MEM2MEM 位

四、DMA 配置与使用的一般步骤

  1. 使能时钟:首先开启DMA控制器的时钟(通常在AHB总线上)。
  2. 初始化DMA通道:使用上述结构体参数配置DMA通道,包括地址、方向、数据量等。
  3. 使能外设的DMA功能:在对应外设(如ADC、USART)的配置中,开启其DMA请求输出。
  4. 配置中断(可选):如果需要,使能DMA传输完成等中断,并配置NVIC。
  5. 使能DMA通道:最后启动DMA通道,使其等待外设请求或软件触发。
  6. 触发传输:对于外设触发模式(如ADC),启动外设即可;对于存储器到存储器模式,使能通道即开始传输。
  7. 查询状态或处理中断:通过查询标志位或在中段服务函数中,判断传输是否完成并进行后续处理。

五、典型应用示例:ADC 使用 DMA 搬运数据

这是一个非常常见的应用,用于高效地连续采集模拟信号。关键步骤如下:

  1. 初始化ADC :配置ADC为定时器触发等连续转换模式,并关键一步 :调用 ADC_DMACmd(ADC1, ENABLE); 使能ADC的DMA输出。
  2. 初始化DMA :以ADC1(对应DMA1通道1)为例进行配置。
    • 源地址 (PeripheralBaseAddr):(u32)(&ADC1->DR) (ADC数据寄存器地址)。
    • 目标地址 (MemoryBaseAddr):自定义数组(如 u16 adcValue[128])的首地址。
    • 方向:外设到存储器 (DMA_DIR_PeripheralSRC)。
    • 存储器地址递增使能。
    • 数据宽度:半字(16位,匹配ADC的12位结果)。
    • 模式:循环模式 (Circular),实现连续采集。
    • 使能传输完成中断,以便在数组填满时进行处理。
  3. 启动:启动ADC转换,随后ADC每完成一次转换就会触发DMA请求,DMA自动将数据搬运到指定数组中。CPU只需在DMA传输完成中断中处理这批数据即可,期间完全自由。

六、DMA 与 CPU 的关系

在STM32的Cortex-M架构中,DMA和CPU通过总线矩阵共享系统总线。当DMA和CPU同时访问同一目标(如SRAM)时,总线仲裁器会协调访问,通常采用轮转调度以保证双方都能获得带宽,因此DMA的使用不会完全阻塞CPU,但可能会在总线争用时轻微影响CPU的访问速度。这与一些其他架构(如x86)不同,在STM32上合理使用DMA能显著降低CPU负载,提高系统整体性能。

总之,STM32的DMA是提升数据吞吐量和系统实时性的强大工具,熟练掌握其原理和配置方法对于开发高性能嵌入式应用至关重要。

相关推荐
bubiyoushang8882 小时前
STM32F103C8T6+DM9051以太网功能实现方案
stm32·单片机·嵌入式硬件
IT_阿水2 小时前
基于STM32河流水质检测
stm32·单片机·嵌入式硬件
黑白园3 小时前
STM32定时器中断
stm32·单片机·嵌入式硬件
weixin_456808384 小时前
【沁恒蓝牙开发】ADC DMA定时采样、转化
单片机·嵌入式硬件
华普微HOPERF5 小时前
MCU+BLE射频+丰富外设,BLE SoC如何高效传输数据?
单片机·嵌入式硬件
振南的单片机世界5 小时前
时钟开关:不用的外设,把它的时钟关掉,省电!
stm32·单片机·嵌入式硬件
金色光环5 小时前
SCPI添加错误码
stm32·scpi
iCxhust6 小时前
将8088 BootLoader分拆烧写到8086 ROM中
stm32·单片机·嵌入式硬件·51单片机·微机原理
国科安芯6 小时前
商业航天电机控制领域抗辐射 MCU 芯片应用研究
网络·单片机·嵌入式硬件·安全性测试
charlie1145141917 小时前
嵌入式C++工程实践第20篇:GPIO 输入模式内部电路 —— 芯片是如何“听“到外部信号的
开发语言·c++·stm32·单片机