STM32F103 学习笔记-22-DMA(第1节)-DMA功能框图讲解和DMA初始化结构体讲解

一、DMA 简介

DMA (Direct Memory Access,直接存储器访问) ​ 是 STM32F103 系列微控制器内置的一个独立外设,其核心功能是在不占用 CPU 资源的情况下,实现数据在存储器与外设之间、存储器与存储器之间的高速传输

1.1 核心优势

传统的数据传输方式需要 CPU 主动参与,将数据从源地址读取到内核寄存器,再写入目标地址,整个过程 CPU 被完全占用。而 DMA 传输时,CPU 只需配置传输参数并启动 DMA,之后 DMA 控制器会自动完成数据搬运,CPU 可以并行执行其他任务,极大提高了系统效率。

1.2 支持的传输方向

DMA 支持三种数据传输模式:

  • 存储器到存储器 (Memory-to-Memory, M2M):数据在内部 Flash、SRAM 之间传输

  • 外设到存储器 (Peripheral-to-Memory, P2M):典型应用如 ADC 采集数据到 SRAM

  • 存储器到外设 (Memory-to-Peripheral, M2P):典型应用如 SRAM 中的数据通过串口发送

1.3 DMA 控制器与通道

STM32F103 系列包含两个 DMA 控制器:

  • DMA1:拥有 7 个独立通道,支持所有三种传输模式

  • DMA2:拥有 5 个独立通道,支持所有三种传输模式

重要说明 :DMA2 仅存在于大容量产品 (Flash 容量 256KB~512KB)和互联型产品(STM32F105/F107 系列)中。指南者和霸道开发板使用的 STM32F103ZET6 属于大容量产品,因此同时具备 DMA1 和 DMA2。

二、DMA 功能框图详解

DMA 功能框图主要由三部分组成:DMA 请求通道仲裁器

2.1 DMA 请求

DMA 传输必须由请求源触发。对于 P2M 和 M2P 模式,请求源只能是外设;对于 M2M 模式,由软件触发。

当外设需要进行 DMA 传输时,会向对应的 DMA 通道发送请求信号。DMA 控制器接收到请求后,若通道空闲,则启动数据传输。

2.2 DMA 通道

DMA 通道可以理解为独立的数据传输管道,每个通道都有自己的配置寄存器,可以独立配置传输方向、数据宽度、地址增量等参数。

2.2.1 DMA1 通道映射
DMA1 通道 外设请求源
通道 1 ADC1、TIM2_CH3、TIM4_CH1
通道 2 SPI1_RX、TIM1_CH1、TIM2_UP、TIM3_CH1
通道 3 SPI1_TX、TIM1_CH2、TIM2_CH2、TIM3_CH2
通道 4 SPI2_RX、USART1_TX、TIM1_CH4、TIM1_TRIG、TIM3_CH3
通道 5 SPI2_TX、USART1_RX、TIM1_UP、TIM3_CH4、TIM3_TRIG
通道 6 USART2_RX、TIM1_CH1、TIM2_CH4
通道 7 USART2_TX、TIM1_CH2、TIM2_CH1、TIM4_CH2
2.2.2 DMA2 通道映射
DMA2 通道 外设请求源
通道 1 ADC3、TIM5_CH4、TIM8_CH3
通道 2 SPI3_RX、TIM5_CH3、TIM8_CH4、TIM8_TRIG
通道 3 SPI3_TX、TIM5_CH2、TIM8_CH1
通道 4 UART4_RX、SDIO、TIM5_CH1、TIM8_CH2
通道 5 UART4_TX、TIM5_UP、TIM6_UP/DAC_CH1、TIM7_UP/DAC_CH2、TIM8_UP

特殊说明存储器到存储器(M2M)模式不受上述通道映射限制,可以使用 DMA1 和 DMA2 的任意通道。

2.3 DMA 仲裁器

当多个 DMA 通道同时产生传输请求时,仲裁器负责决定哪个通道优先获得总线使用权。仲裁规则分为两个阶段:

  1. 软件优先级阶段:通过 DMA_CCRx 寄存器的 PL[1:0] 位配置,分为四个等级:

    • 00:低优先级

    • 01:中优先级

    • 10:高优先级

    • 11:最高优先级

  2. 硬件优先级阶段:当两个通道的软件优先级相同时,通道编号小的优先级更高。例如,DMA1 通道 4 的优先级高于 DMA1 通道 7。

跨控制器优先级:DMA1 的所有通道优先级均高于 DMA2 的通道。

三、DMA 初始化结构体详解

STM32 标准外设库使用 DMA_InitTypeDef结构体来配置 DMA 参数,该结构体定义在 stm32f10x_dma.h文件中。

3.1 数据从哪里来,要到哪里去

这部分由结构体的前三个成员决定:

复制代码
typedef struct {
    uint32_t DMA_PeripheralBaseAddr;  // 外设基地址
    uint32_t DMA_MemoryBaseAddr;      // 存储器基地址
    uint32_t DMA_DIR;                 // 数据传输方向
    // ... 其他成员
} DMA_InitTypeDef;
  1. DMA_PeripheralBaseAddr :配置 DMA_CPAR 寄存器,指定外设数据寄存器的地址。例如,串口发送时应设置为 (uint32_t)&USART1->DR

  2. DMA_MemoryBaseAddr:配置 DMA_CMAR 寄存器,指定存储器的起始地址。例如,发送数组时应设置为数组名(数组首地址)。

  3. DMA_DIR:配置 DMA_CCR 寄存器的 DIR 位(位 4),指定数据传输方向:

    • DMA_DIR_PeripheralDST:外设作为目标地址(M2P 模式)

    • DMA_DIR_PeripheralSRC:外设作为源地址(P2M 模式)

M2M 模式说明 :除了配置上述三个成员外,还需要单独配置 DMA_CCR 寄存器的 MEM2MEM 位(位 14)为 1,即设置结构体成员 DMA_M2M = DMA_M2M_Enable

3.2 数据要传多少,传的单位是什么

这部分由以下五个成员决定:

复制代码
uint32_t DMA_BufferSize;          // 传输数据数目
uint32_t DMA_PeripheralInc;       // 外设地址增量模式
uint32_t DMA_MemoryInc;           // 存储器地址增量模式
uint32_t DMA_PeripheralDataSize;  // 外设数据宽度
uint32_t DMA_MemoryDataSize;      // 存储器数据宽度
  1. DMA_BufferSize :配置 DMA_CNDTR 寄存器,指定一次传输的数据单元数目。该寄存器为 16 位,因此最大传输数目为65535

  2. DMA_PeripheralInc:配置 DMA_CCR 寄存器的 PINC 位(位 6),指定外设地址是否自动递增:

    • DMA_PeripheralInc_Enable:每次传输后外设地址自动加 1

    • DMA_PeripheralInc_Disable:外设地址保持不变(适用于单个数据寄存器的情况)

  3. DMA_MemoryInc:配置 DMA_CCR 寄存器的 MINC 位(位 7),指定存储器地址是否自动递增:

    • DMA_MemoryInc_Enable:每次传输后存储器地址自动加 1(适用于数组传输)

    • DMA_MemoryInc_Disable:存储器地址保持不变

  4. DMA_PeripheralDataSize ​ 和 DMA_MemoryDataSize:分别配置 DMA_CCR 寄存器的 PSIZE[1:0] 位(位 8-9)和 MSIZE[1:0] 位(位 10-11),指定数据宽度:

    • DMA_PeripheralDataSize_Byte:8 位字节

    • DMA_PeripheralDataSize_HalfWord:16 位半字

    • DMA_PeripheralDataSize_Word:32 位字

数据宽度不匹配说明

  • 当源数据宽度小于目标数据宽度时,源数据会被零扩展到目标宽度

  • 当源数据宽度大于目标数据宽度时,源数据的高位会被丢弃,只保留低位

3.3 什么时候传输结束

这部分由以下两个成员决定:

复制代码
uint32_t DMA_Mode;                // 传输模式
uint32_t DMA_Priority;            // 通道优先级
  1. DMA_Mode:配置 DMA_CCR 寄存器的 CIRC 位(位 5),指定传输模式:

    • DMA_Mode_Normal:正常模式,传输完成后通道自动停止

    • DMA_Mode_Circular:循环模式,传输完成后自动重新加载传输数目,开始新一轮传输

  2. DMA_Priority:配置 DMA_CCR 寄存器的 PL[1:0] 位(位 12-13),指定通道的软件优先级,取值如 2.3 节所述。

四、常用 DMA 固件库函数

4.1 DMA 初始化函数

复制代码
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);
  • 功能:根据 DMA_InitStruct中的参数初始化 DMA 通道

  • 参数:

    • DMAy_Channelx:指定要初始化的 DMA 通道,如 DMA1_Channel4

    • DMA_InitStruct:指向 DMA 初始化结构体的指针

4.2 DMA 使能函数

复制代码
void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);
  • 功能:使能或禁用指定的 DMA 通道

  • 参数:

    • DMAy_Channelx:指定要操作的 DMA 通道

    • NewStateENABLE使能通道,DISABLE禁用通道

4.3 状态查询函数

复制代码
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);
void DMA_ClearFlag(uint32_t DMAy_FLAG);
  • 功能:查询或清除 DMA 通道的状态标志

  • 常用标志:

    • DMA1_FLAG_TC4:DMA1 通道 4 传输完成标志

    • DMA1_FLAG_HT4:DMA1 通道 4 传输过半标志

    • DMA1_FLAG_TE4:DMA1 通道 4 传输出错标志

4.4 中断配置函数

复制代码
void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);
  • 功能:使能或禁用 DMA 通道的中断

  • 参数:

    • DMA_IT:指定要配置的中断类型,如 DMA_IT_TC(传输完成中断)、DMA_IT_HT(传输过半中断)、DMA_IT_TE(传输出错中断)

五、注意事项

  1. 通道选择限制:P2M 和 M2P 模式必须严格按照通道映射表选择通道,不能随意使用

  2. 数据宽度匹配:建议源和目标的数据宽度保持一致,避免数据丢失或不必要的扩展

  3. 地址增量配置:对于单个外设数据寄存器(如 USART_DR、ADC_DR),外设地址增量应设置为禁用

  4. 循环模式使用:循环模式适用于需要持续传输数据的场景,如串口打印、ADC 连续采集

  5. 传输完成判断:在 Normal 模式下,可以通过查询传输完成标志位来判断传输是否结束

参考出处

  1. 视频讲解:STM32F103 DMA 直接存储器访问(理论篇)

  2. 《零死角玩转 STM32F103-指南者》第 22 章 DMA 直接存储器访问

相关推荐
咸甜适中5 小时前
rust语言学习笔记Trait(十一)Deref、DerefMut(解引用)
笔记·学习·rust
hj2862515 小时前
Linux存储空间管理完整笔记
linux·运维·笔记
_She0015 小时前
硬件知识 cadence16.6 导入log 的笔记及其他问题
笔记
玄米乌龙茶1236 小时前
思维导图笔记:大模型幻觉问题
笔记
AI小技巧6 小时前
商务英语在线学习哪家好?主流平台深度测评与避坑指南
学习
共享家95276 小时前
Langchain的学习(三)
学习·langchain
陌上花开缓缓归以6 小时前
定时器和延时函数选型
单片机
断眉的派大星6 小时前
SSD(Single Shot MultiBox Detector)超详细笔记
笔记·目标检测·计算机视觉
华普微HOPERF6 小时前
电视冰箱洗衣机、空调风扇热水器,Matter协议如何塑造全屋智能?
嵌入式硬件·物联网·智能家居·matter协议·全屋智能