在 STM32 微控制器中,DMA(Direct Memory Access,直接存储器访问) 是一种硬件机制,可以在不占用 CPU 的情况下,在 外设 和 内存 之间,或者 内存与内存 之间高速传输数据。
为了实现自动、高效的数据传输,DMA 的启动(触发)通常是由某个外设事件或定时器事件来触发的,而不是每次都由软件手动启动。
一、DMA 触发源(DMA Request Sources)概述
DMA 触发源 ,就是指能够 启动一次 DMA 数据传输的外设事件或信号。这些触发源可以是:
- 外设产生的 DMA 请求信号(如 UART 接收到数据、SPI 发送完成、ADC 转换完成等)
- 定时器事件(如 TIMx 的更新事件、比较事件、触发输出 TRGO)
- 其他内部信号
STM32 的每个 DMA 控制器(如 DMA1、DMA2)支持多个 DMA 通道(Channels) ,每个通道通常固定绑定某些外设的 DMA 请求,或者说每个外设的 DMA 请求会连接到某个固定的 DMA 通道上。
二、DMA 触发源的分类
我们可以从两个角度来看 DMA 的触发源:
1. 按来源类型分:
| 类型 | 说明 | 示例 |
|---|---|---|
| 外设触发源 | 由某个外设模块在特定事件发生时发出 DMA 请求 | 如 USART 接收完成、SPI 发送、I2C 接收、ADC 转换完成等 |
| 定时器触发源 | 由定时器(如 TIMx)在某个事件(如更新、比较、触发)时发出 DMA 请求 | 如 TIM1_CC1、TIM2_UP、TIM3_TRGO 等 |
| 软件触发 | 由软件手动启动 DMA 传输(非自动触发) | 使用 DMA 软件触发(较少用,一般用硬件触发) |
2. 按 STM32 系列与外设的实际连接(重点)
每个 DMA 通道 通常被 固定分配给某些外设的 DMA 请求,例如:
- DMA1 Channel1 可能连接的是 TIM2_CH3 / ADC1 / SPI1_RX 等(视芯片系列而定)
- DMA2 Channel5 可能连接的是 USART1_TX / TIM1_CH1 等
⚠️ 不同 STM32 系列(如 F1、F4、H7、G4、L4、U5 等)的 DMA 请求映射关系是不同的!
所以,要准确知道某个外设的 DMA 请求连接到哪个 DMA 通道,必须查阅你所使用的具体 STM32 型号的参考手册(Reference Manual)中的 "DMA requests" 或 "DMA channel mapping" 部分。
三、常见外设的 DMA 触发源(以常见 STM32 系列为例)
以下是一些 常见外设的 DMA 请求(触发源),以及它们通常用于什么场景:
1. ADC(模数转换器)
- 触发源名称 :
ADC1 DMA请求(如 ADC1_DMAReq) - 作用:当 ADC 转换完成后,自动触发 DMA,将转换结果搬运到内存
- 常见应用:高速数据采集、多通道采样、波形采样等
- 触发方式 :通常由 规则组或注入组转换完成事件 触发
2. USART / UART(串口)
- USART_RX:接收数据寄存器非空(RXNE),可触发 DMA 接收数据
- USART_TX:发送寄存器空(TXE),可触发 DMA 发送数据
- 常见应用:高速串口通信、无线模块、蓝牙、GPS 等数据收发
3. SPI
- SPI_RX / SPI_TX:接收或发送数据完成时可触发 DMA
- 常见应用:高速传感器通信(如 Flash、传感器)、显示屏通信等
4. I2C
- I2C_RX / I2C_TX:数据收发完成事件触发 DMA
- 常见应用:EEPROM、传感器、显示屏等 I2C 设备通信
5. 定时器(TIMx)
这是重点,很多用户用定时器触发 DMA,尤其是做 PWM调制、多路采样、DAC输出、电机控制 等。
- TIMx_UP:定时器更新事件(计数器溢出/下溢)
- TIMx_CCx:定时器某个通道的捕获/比较事件(如 TIM1_CC1)
- TIMx_TRGO:定时器的触发输出信号(可用于同步多个外设,包括 DMA)
- 常见应用 :
- 定时器触发 ADC 采样(如电机电流采样)
- 定时器触发 DAC 输出波形
- 定时器触发 DMA 刷新显示缓冲区、PWM 调制等
✅ 定时器的 DMA 触发源通常是通过配置定时器的 DMA 请求(如 TIMx_DIER 中的 CCxDE、UDE、TDE 等位)以及选择合适的触发事件来实现的。
四、如何查找你所用的 STM32 的 DMA 触发源?
由于不同 STM32 系列的 DMA 请求映射不同,推荐以下方法:
方法 1:查看 参考手册(Reference Manual)
- 搜索关键字:"DMA requests" 或 "DMA channel mapping"
- 找到你用的外设(如 ADC1、TIM1、USART1)对应的 DMA 请求名称
- 查看该请求连接到哪个 DMA 控制器(DMA1 或 DMA2)的哪个通道
🔗 例如 STM32F103 参考手册中会有类似如下表格:
| 外设 | DMA 请求 | 对应 DMA 通道(DMA1) |
|---|---|---|
| ADC1 | ADC1 | Channel 1 |
| SPI1 RX | SPI1_RX | Channel 2 |
| SPI1 TX | SPI1_TX | Channel 3 |
| USART1 RX | USART1_RX | Channel 5 |
| USART1 TX | USART1_TX | Channel 4 |
| TIM2_CH3 / TIM2_UP | TIM2_UP / CH3 | Channel 7 |
| TIM1_CC1 / TRGO | TIM1_CC1, TIM1_TRGO | Channel 2 / Channel 11(因系列而异) |
每个 STM32 系列(如 F4、H7、G4、L4 等)该表格可能完全不同!
方法 2:使用 STM32CubeMX 工具
- 在 CubeMX 中配置你的外设(如 ADC、TIM、USART)
- 启用该外设的 DMA 请求
- CubeMX 会 自动分配一个 DMA 通道,并显示该外设连接到了哪个 DMA 通道
- 你也可以从图形界面中看到 DMA 触发源选项
🔧 CubeMX 极大简化了 DMA 与外设的配置,强烈推荐使用!
方法 3:查看 数据手册(Datasheet) 或 HAL 库函数说明
- 有些信息也会在 HAL 库函数注释 或 CMSIS 寄存器描述 中提到
- 但不如 Reference Manual 直观
五、常见 DMA 触发源总结表(通用版,以常见 STM32 为例)
| 外设 | DMA 请求事件 | 说明 | 常用 DMA 通道(举例,具体看型号) |
|---|---|---|---|
| ADC1 | ADC DMA 请求 | 转换完成触发 DMA | DMA1 Channel 1(常见于 F1) |
| USART1_RX | USART1_RX DMA 请求 | 接收数据触发 DMA | DMA1 Channel 5 |
| USART1_TX | USART1_TX DMA 请求 | 发送数据触发 DMA | DMA1 Channel 4 |
| SPI1_RX | SPI1_RX DMA 请求 | 接收数据触发 DMA | DMA1 Channel 2 |
| SPI1_TX | SPI1_TX DMA 请求 | 发送数据触发 DMA | DMA1 Channel 3 |
| TIM1_CC1 | TIM1 捕获/比较通道1事件 | 可触发 DMA(如 PWM 调制) | DMA1 Channel 2(常见) |
| TIM1_TRGO | TIM1 触发输出信号 | 可触发 ADC/DMA 等 | 作为触发源,非固定通道 |
| TIM2_UP | TIM2 更新事件 | 计数器溢出时触发 DMA | DMA1 Channel 7 |
| TIM3_TRGO | TIM3 触发输出 | 用于同步或触发 | 作为触发信号 |
🎯 注意:通道号和映射是芯片型号相关的!一定要查自己芯片的 Reference Manual!
六、总结
| 项目 | 说明 |
|---|---|
| 什么是 DMA 触发源? | 指能够启动 DMA 数据传输的信号,通常来自外设或定时器的某个事件 |
| 常见触发源类型 | 外设事件(如 ADC、USART、SPI、I2C)、定时器事件(如 TIMx_UP、TIMx_CCx、TIMx_TRGO) |
| 如何确定某个外设的 DMA 触发源? | 查阅所用 STM32 的 Reference Manual ,找到 "DMA Requests" 相关章节;或使用 STM32CubeMX 工具自动配置 |
| DMA 触发源是否固定? | 是的,大多数 STM32 的 DMA 通道与外设请求是 固定映射 的,不能随意更改 |
| 如何使用? | 在外设和 DMA 都使能的前提下,配置好触发源,DMA 即可在事件发生时自动搬运数据 |
✅ 如果你有具体的 STM32 型号(如 STM32F103、F407、H743、G431、L432 等),或者你想实现某个具体的功能(如 TIM1 触发 ADC 采样、定时器触发 DMA 刷新 DAC、USART 用 DMA 接收数据),欢迎告诉我,我可以给你提供:
- 该型号的 DMA 通道与外设对应关系
- CubeMX 配置建议
- 寄存器或 HAL 库代码示例
这样你可以更精准地实现你的应用!