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 代码设计
// 初始化 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 限制的尝试都是徒劳的,但通过合理设计唤醒机制,仍可满足低功耗与数据采集的平衡。