第4章 低功耗模式概览:五种模式的特点与切换
做嵌入式开发,尤其是电池供电的项目,功耗管理是绕不开的坎。STM32 提供了五种功耗模式,从「全速跑」到「几乎关机」,各有各的用武之地。我刚开始接触低功耗设计时,总觉得模式越多越复杂,后来才发现——选对模式,比写一堆优化代码更管用。
这一章,咱们把这五种模式掰开揉碎,看看它们各自的特点、适用场景,以及怎么在代码里切换。
5种模式,一张表说清楚
先来个全景图。我习惯把 STM32 的功耗模式想象成「五档变速」:
| 模式 | CPU状态 | SRAM/寄存器 | 外设时钟 | 唤醒源 | 典型功耗 |
|---|---|---|---|---|---|
| 运行 (Run) | 运行 | 全部保留 | 全开 | — | ~100μA/MHz |
| 睡眠 (Sleep) | 暂停 | 全部保留 | 全开 | 任何中断/事件 | ~50μA/MHz |
| 停止 (Stop) | 关 | 全部保留 | 部分关闭 | EXTI、RTC、USB等 | ~2-10μA |
| 待机 (Standby) | 关 | 仅备份域 | 几乎全关 | WKUP引脚、RTC、NRST | ~0.3-2μA |
| 关机 (Shutdown) | 关 | 全部丢失 | 全关 | WKUP引脚、NRST | ~0.1μA |
嗯,这张表值得你截图保存。后面每个模式我都会展开讲,但先记住一个原则:功耗越低,唤醒代价越大。
运行模式——默认状态,没什么好说的
运行模式就是芯片上电后的默认状态。CPU 全速跑,所有外设时钟都开着。说白了,这就是「不省电模式」。如果你的项目对功耗没要求,那就不用往下看了。
但实际项目中,大部分时间芯片其实不需要全速运行。比如一个温度传感器,每秒采集一次数据,剩下 999ms 都在空转——这就是浪费。
睡眠模式——CPU 歇着,外设继续干活
睡眠模式是最轻量的低功耗模式。CPU 暂停执行指令,但 SRAM、寄存器、外设时钟都保持原样。任何中断都能把它唤醒,而且唤醒速度极快——几乎就是几个时钟周期的事。
怎么进睡眠?HAL 库提供了两个函数:
// 进入睡眠模式(WFI:等待中断)
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
// 进入睡眠模式(WFE:等待事件)
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFE);
WFI 和 WFE 的区别?简单说:WFI 靠中断唤醒,WFE 靠事件唤醒。我一般用 WFI,因为中断模型更直观。
停止模式——深度睡眠,但保留现场
停止模式就有点意思了。CPU 停了,主时钟也停了,但 SRAM 和寄存器内容全部保留。这意味着你醒来后,程序可以接着往下跑,就像什么都没发生过。
进入停止模式时,可以选择电压调节器的工作模式:
- MR(主调节器):唤醒快,功耗稍高
- LPR(低功耗调节器):唤醒慢,功耗更低
代码示例:
// 进入停止模式,使用低功耗调节器
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
唤醒停止模式,需要配置 EXTI 中断。比如用 RTC 闹钟唤醒:
// 配置 RTC 闹钟(略)
// 进入停止模式
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// 醒来后,需要重新配置系统时钟
SystemClock_Config();
SystemClock_Config() 重新配置,芯片会以 HSI 低速运行,外设时序全乱。别问我怎么知道的……
待机模式——几乎关机,只留备份域
待机模式比停止模式更「狠」。CPU、SRAM、大部分外设都断电了,只保留备份域(RTC、备份寄存器、备份 SRAM)。唤醒后,程序会从头执行——就像按了复位键。
进入待机模式:
// 清除唤醒标志
HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
HAL_PWREx_ClearPendingEvent();
// 进入待机模式
HAL_PWR_EnterSTANDBYMode();
唤醒方式有三种:
- WKUP 引脚上升沿(PA0 等)
- RTC 闹钟/唤醒事件
- NRST 复位引脚
注意:待机模式唤醒后,程序从 Reset_Handler 开始执行。所以你需要一种方式来判断是「上电复位」还是「待机唤醒」。我一般用 RTC 备份寄存器来标记:
// 进入待机前,写标记
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0xA5A5);
// 醒来后,检查标记
if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) == 0xA5A5) {
// 待机唤醒,恢复现场
} else {
// 上电复位,完整初始化
}
关机模式——真正的「断电」
关机模式是 STM32 功耗最低的模式。它比待机模式更进一步:连备份域的部分电路也断电了。唤醒后,芯片完全复位,所有 SRAM 和寄存器内容全部丢失。
进入关机模式:
// 进入关机模式
HAL_PWREx_EnterSHUTDOWNMode();
唤醒方式只有两种:
- WKUP 引脚上升沿
- NRST 复位引脚
RTC 闹钟?不行。关机模式下 RTC 也停了。
模式切换的核心逻辑
说了这么多,其实切换逻辑很简单。我画了张图,帮你理清思路:
这张图想表达的核心思想:越往下,功耗越低,但唤醒代价越大。你选哪个模式,取决于你的应用场景——是要求快速响应,还是追求极致续航。
实际项目中的选择策略
说了这么多理论,来点实际的。我总结了一个简单的选择矩阵:
- 需要频繁响应中断(ms级) → 睡眠模式
- 需要保留现场,但可以接受几十μs唤醒 → 停止模式
- 定时唤醒,不需要保留现场 → 待机模式
- 物理开关控制,完全断电 → 关机模式