简介
DMA(Direct Memory Access,直接内存访问)是一种允许外设直接与内存进行数据传输的技术,无需 CPU 干预,可大大提高数据传输效率。STM32F407 系列芯片配备了 2 个 DMA 控制器(DMA1 和 DMA2),共 16 个数据流,每个数据流可配置为不同的外设通道,支持多种传输模式,如内存到内存、外设到内存、内存到外设等。本文从 DMA 的基本原理出发,详细讲解 STM32F407 DMA 的配置方法、代码实现、传输模式以及实际应用案例,帮助你快速掌握 DMA 的使用技巧。
一、DMA核心概念与分类
1.1 基本概念
DMA 是一种允许外设直接与内存进行数据传输的技术,其主要特点包括:
- 减轻 CPU 负担:数据传输过程中 CPU 可执行其他任务
- 提高传输效率:避免 CPU 中断处理的开销
- 支持多种传输模式:内存到内存、外设到内存、内存到外设
- 支持多种触发方式:可由外设事件触发,实现自动化传输
- 支持多种数据宽度:8 位、16 位、32 位
关键参数:
- 数据流:DMA 控制器中的数据传输通道
- 通道:每个数据流可配置为不同的外设通道
- 传输方向:内存到内存、外设到内存、内存到外设
- 数据宽度:8 位、16 位、32 位
- 传输模式:正常模式、循环模式、双缓冲模式
1.2 STM32F407 的 DMA 资源
STM32F407 系列芯片配备了 2 个 DMA 控制器:
| DMA 控制器 | 数据流数量 | 通道数量 | 时钟源 | 适用场景 |
|---|---|---|---|---|
| DMA1 | 7 | 8 | AHB1 | 主要服务于 APB1 外设 |
| DMA2 | 9 | 8 | AHB2 | 主要服务于 APB2 外设和 AHB 外设 |
DMA1 数据流与通道对应关系:
| 数据流 | 通道0 | 通道1 | 通道2 | 通道3 | 通道4 | 通道5 | 通道6 | 通道7 |
|---|---|---|---|---|---|---|---|---|
| Stream0 | SPI3_RX | UART3_RX | TIM4_CH1/TIM4_TRGO | I2C1_RX | TIM2_CH1/TIM2_TRGO | - | - | - |
| Stream1 | - | SPI3_TX | TIM4_CH2 | I2C1_TX | TIM2_CH2/TIM2_UP | TIM3_CH4/TIM3_UP | - | - |
| Stream2 | - | - | TIM4_CH3 | I2C2_RX | TIM2_CH3 | TIM3_CH1/TIM3_TRGO | - | - |
| Stream3 | - | - | TIM4_UP | I2C2_TX | TIM2_CH4 | TIM3_CH2 | - | - |
| Stream4 | - | - | - | - | - | TIM3_CH3 | DAC1_CH1/DAC1_CH2 | TIM5_TRGO/TIM5_CH4 |
| Stream5 | - | - | - | - | - | - | DAC2_CH1 | TIM5_CH1/TIM5_CH2/TIM5_CH3 |
| Stream6 | - | - | - | - | - | - | - | TIM6_UP/TIM7_UP |
| Stream7 | - | - | - | - | - | - | - | - |
DMA2 数据流与通道对应关系:
| 数据流 | 通道0 | 通道1 | 通道2 | 通道3 | 通道4 | 通道5 | 通道6 | 通道7 |
|---|---|---|---|---|---|---|---|---|
| Stream0 | ADC1 | SPI1_RX | USART1_RX | - | - | - | - | - |
| Stream1 | - | - | - | - | - | - | - | - |
| Stream2 | - | - | - | - | USART1_TX | - | - | - |
| Stream3 | - | - | - | - | - | - | - | - |
| Stream4 | - | - | - | - | - | - | - | - |
| Stream5 | - | - | - | - | - | - | - | - |
| Stream6 | - | - | - | - | - | - | - | - |
| Stream7 | - | - | - | - | - | - | - | - |
关键特性:
- 支持 8 位、16 位、32 位数据宽度
- 支持正常模式、循环模式、双缓冲模式
- 支持内存到内存、外设到内存、内存到外设传输
- 支持外设和内存地址自动递增
- 支持多种中断:传输完成、半传输完成、传输错误等
- 支持 FIFO 模式和突发传输
二、DMA工作原理
2.1 基本工作原理
DMA 的基本工作原理是通过 DMA 控制器直接控制数据在外设和内存之间的传输,无需 CPU 干预。
传输流程:
- CPU 配置 DMA 传输参数(源地址、目的地址、传输长度等)
- CPU 使能 DMA 传输
- DMA 控制器根据配置参数执行数据传输
- 传输完成后,DMA 控制器触发中断(如果使能)
- CPU 在中断服务函数中处理传输完成事件
2.2 传输模式
DMA 支持多种传输模式:
正常模式:
- 传输完成后,DMA 控制器停止工作
- 需要重新配置 DMA 参数才能进行下一次传输
- 适用于单次传输场景
循环模式:
- 传输完成后,DMA 控制器自动重新开始传输
- 无需 CPU 干预,可实现连续传输
- 适用于连续数据采集或输出场景
双缓冲模式:
- 使用两个缓冲区交替进行数据传输
- 在一个缓冲区传输时,CPU 可以处理另一个缓冲区的数据
- 适用于需要实时处理数据的场景
2.3 数据流配置
DMA 数据流的配置参数包括:
外设地址:
- 外设数据寄存器的地址
- 可配置为固定地址或自动递增
内存地址:
- 内存缓冲区的地址
- 可配置为固定地址或自动递增
传输长度:
- 要传输的数据项数量
- 最大值为 65535
数据宽度:
- 外设数据宽度:8 位、16 位、32 位
- 内存数据宽度:8 位、16 位、32 位
传输方向:
- 外设到内存:从外设读取数据到内存
- 内存到外设:从内存发送数据到外设
- 内存到内存:从内存一个区域复制数据到另一个区域
优先级:
- 低、中、高、非常高
- 当多个数据流同时请求时,根据优先级决定传输顺序
三、DMA配置与代码实现
3.1 标准库配置步骤
以 DMA2 Stream0 Channel0(ADC1)为例,使用标准库配置 DMA 的基本步骤:
- 使能 DMA 时钟
- 配置 DMA 数据流参数
- 配置 DMA 通道
- 配置 DMA 中断(可选)
- 使能 DMA 数据流
3.2 代码实现(DMA2 Stream0 Channel0,ADC1)
#include"stm32f4xx.h"#defineADC1_DMA_BUFFER_SIZE100uint16_tADC1_DMA_Buffer[ADC1_DMA_BUFFER_SIZE];/** * @brief 初始化DMA2 Stream0 Channel0(ADC1) * @param 无 * @retval 无 */voidDMA2_Stream0_Init(void){DMA_InitTypeDef DMA_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;// 1. 使能DMA2时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);// 2. 配置DMA2 Stream0DMA_DeInit(DMA2_Stream0);while(DMA_GetCmdStatus(DMA2_Stream0)!=DISABLE