STM32F4 低功耗 STOP 模式下 DMA 传输的可行性分析与实测
👁 1 阅读 · 2026-08-27 · 嵌入式
在电池供电的物联网设备中,低功耗与数据吞吐往往难以兼得。STM32F4 系列在 STOP 模式下,外设时钟被关闭,但 DMA 能否继续搬运数据?本文从芯片架构、时钟树、外设总线入手,深入分析 STOP 模式下 DMA 的冻结行为,并通过实际代码与波形测量验证可行性,给出替代方案(如 LPTIM+LPUART 或 RTC+DMA),帮助开发者避开低功耗设计的常见陷阱。
# STM32F4 低功耗 STOP 模式下 DMA 传输的可行性分析与实测
## 一、问题背景
在低功耗嵌入式设计中,STOP 模式是常用策略:内核停止、时钟关闭,功耗降至 µA 级。但若外设(如 ADC、UART)需要持续采集数据,DMA 能否在 STOP 模式下继续搬运?很多开发者想当然地认为“DMA 是硬件,应该可以”,但实测往往打脸。本文以 STM32F407 为例,从架构层面剖析,并给出实测数据。
## 二、STOP 模式下的时钟与总线行为
### 2.1 时钟树关键点
- STOP 模式下,**所有时钟(HSE、HSI、PLL)均被关闭**,仅 LSI 或 LSE 可继续运行(供 RTC、IWDG 使用)。
- **AHB1、AHB2、APB1、APB2 总线时钟全部停止**,这意味着挂载在总线上的外设(包括 DMA)的时钟源被切断。
- 但部分外设具有**独立时钟源**(如 RTC 使用 LSE,LPTIM 使用 LSI),它们不依赖系统时钟,可在 STOP 下运行。
### 2.2 DMA 的依赖关系
- DMA 控制器本身挂载在 AHB1 总线上,其时钟由 `RCC->AHB1ENR` 控制。
- DMA 的传输需要**系统时钟(HCLK)** 驱动其状态机,以及**外设时钟**(如 ADC 时钟)产生触发事件。
- 在 STOP 模式下,HCLK 停止,DMA 的寄存器无法被访问,传输状态机冻结,**DMA 不可能继续传输**。
> 结论:**STM32F4 在 STOP 模式下,DMA 完全停止,无法保持传输。** 这与 STM32L4 系列不同(L4 的 DMA 支持 LP 模式,但仅限特定外设)。
## 三、实测验证
### 3.1 测试环境
- 硬件:STM32F407VET6 开发板,USART1 连接 USB-TTL,ADC1 采样内部温度传感器。
- 软件:HAL 库,Keil MDK 5.3。
- 目标:在 STOP 模式下,尝试用 DMA 搬运 ADC 数据,观察是否成功。
### 3.2 代码设计
```c
// 初始化 ADC1 + DMA(正常模式)
void ADC_DMA_Init(void) {
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
// DMA2 Stream0 配置为 ADC1 通道
hdma.Init.Channel = DMA_CHANNEL_0;
hdma.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma.Init.PeriphInc = DMA_PINC_DISABLE;
hdma.Init.MemInc = DMA_MINC_ENABLE;
hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma.Init.Mode = DMA_CIRCULAR;
HAL_DMA_Init(&hdma);
__HAL_LINKDMA(&hadc, DMA_Handle, hdma);
// ADC 配置略...
}
// 进入 STOP 模式,并尝试继续 DMA
void EnterStopMode_Test(void) {
HAL_ADC_Start_DMA(&hadc, (uint32_t*)adc_buffer, 10);
HAL_Delay(10); // 确保 DMA 开始工作
// 进入 STOP 模式
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// 唤醒后(通过 EXTI 或 RTC 唤醒)检查数据
HAL_ADC_Stop_DMA(&hadc);
// 打印 adc_buffer,观察是否有新数据
}
```
### 3.3 实测结果
- 进入 STOP 后,用示波器测量 ADC 的 EOC 信号,发现**无任何脉冲**,说明 ADC 未工作。
- 唤醒后读取 `adc_buffer`,数据与进入 STOP 前完全一致,**无更新**。
- 功耗测量:STOP 模式下电流约 8µA(符合预期),但数据采集完全中断。
**结论:实测证实,STOP 模式下 DMA 传输不可行。**
## 四、替代方案:如何在低功耗下保持数据采集
### 4.1 方案一:使用 LPTIM + LPUART(仅限特定型号)
- STM32F4 系列**没有 LPUART**(L0/L4 系列才有),但部分 F4 型号(如 F410)有 LPTIM。
- LPTIM 可使用 LSI 时钟,在 STOP 模式下运行,并产生事件唤醒 MCU,但**不能直接驱动 DMA**。
- 可行做法:LPTIM 定时唤醒 MCU,在短暂运行模式下用 DMA 采集数据,然后再次进入 STOP。
### 4.2 方案二:RTC 周期性唤醒 + 快速采集
- RTC 使用 LSE,可在 STOP 下运行,产生闹钟事件唤醒 MCU。
- 唤醒后,在短时间内完成 DMA 传输(如 ADC 采样),然后重新进入 STOP。
- 优点:功耗低(唤醒时间短),数据不丢失;缺点:实时性差,适合低频采集。
### 4.3 方案三:使用外部 ADC + SPI(主从模式)
- 外部 ADC 由独立电源供电,通过 SPI 接口与 MCU 通信。
- MCU 在 STOP 模式下,SPI 不工作,但外部 ADC 可自行采集并存储(需自带 FIFO)。
- MCU 唤醒后一次性读取,适合高速采样场景。
## 五、注意事项
- **不要试图在 STOP 模式下访问任何外设寄存器**,包括 DMA,否则会触发总线错误或死机。
- 进入 STOP 前,务必关闭 DMA 并等待传输完成,否则可能丢失数据。
- 唤醒后,需重新初始化外设时钟(HAL 库会自动处理),但 DMA 配置可能需要重新设置。
- 使用 `HAL_PWR_EnterSTOPMode` 时,注意选择稳压器模式(`PWR_LOWPOWERREGULATOR_ON` 比 `PWR_MAINREGULATOR_ON` 功耗更低,但唤醒时间更长)。
- 若必须连续采集,考虑使用 **STOP2 模式(仅限 L4 系列)** 或 **SLEEP 模式**(功耗略高,但 DMA 可用)。
## 六、总结
STM32F4 的 STOP 模式设计目标是极致省电,因此牺牲了大部分外设功能。DMA 依赖系统时钟,在 STOP 下必然停止。开发者应根据应用需求,选择合适的低功耗策略:要么接受中断式采集,要么升级到支持 LP 模式的系列(如 STM32L4)。实测数据表明,任何绕过 STOP 限制的尝试都是徒劳的,但通过合理设计唤醒机制,仍可满足低功耗与数据采集的平衡。