3、低功耗模式全景:STM32睡眠、停止、待机模式详解与唤醒源
做低功耗设计,说白了就是跟芯片的“休息方式”打交道。STM32 不像普通单片机只有一种睡法,它提供了三种深度不同的睡眠模式。选对了,功耗能压到微安级;选错了,要么醒不过来,要么功耗白降。
我个人习惯把这三模式比作“打盹”、“深睡”和“关机”。咱们一个一个拆开看。
3.1 三种低功耗模式的核心差异
先看一张总览表,心里有个底:
| 特性 | 睡眠模式 (Sleep) | 停止模式 (Stop) | 待机模式 (Standby) |
|---|---|---|---|
| CPU 状态 | 停止 | 停止 | 断电 |
| SRAM 状态 | 保持 | 保持 | 丢失 |
| 寄存器状态 | 保持 | 保持 | 丢失 |
| 外设时钟 | 可关闭 | 全部关闭 | 全部关闭 |
| 典型电流 | ~mA 级 | ~µA 级 | ~nA 级 |
| 唤醒时间 | ~µs 级 | ~10µs 级 | ~ms 级 |
| 唤醒源 | 任意中断 | EXTI、RTC、I2C、USART 等 | WKUP 引脚、RTC、NRST |
嗯,这里要注意:待机模式下的 SRAM 数据会全部丢失。如果你有需要保持的变量,必须放在备份寄存器里,或者干脆别用待机模式。
3.2 睡眠模式:最快进出,适合短时等待
睡眠模式是功耗最低的“清醒”状态。CPU 停了,但所有外设时钟还在跑。你想想看,如果你只是等一个 SPI 传输完成,或者等一个定时器溢出,用睡眠模式最合适。
进入方式很简单:执行 WFI 或 WFE 指令就行。HAL 库封装成了:
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
我在项目中遇到过一个问题:用睡眠模式时,如果中断优先级配置不当,唤醒后程序会卡在中断里出不来。后来发现是 SLEEPONEXIT 位被意外置位了。这个位会让 CPU 在执行完中断后再次进入睡眠,而不是返回主循环。
3.3 停止模式:深度睡眠,保留现场
停止模式是我用得最多的模式。它把 CPU 和所有外设的时钟都关了,但 SRAM 和寄存器内容还在。说白了,就是“按了暂停键”。
进入停止模式的代码:
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
这里有个关键参数:稳压器模式。你可以选主稳压器(MR)或低功耗稳压器(LPR)。LPR 功耗更低,但唤醒时间会变长。我一般做电池供电产品时用 LPR,做响应要求高的产品用 MR。
唤醒停止模式,必须通过 EXTI 中断。RTC 闹钟、外部 GPIO 引脚、甚至 USB 唤醒信号都可以配置成 EXTI 源。
3.4 待机模式:最低功耗,但一切归零
待机模式是 STM32 的“终极省电方案”。除了 RTC 和备份寄存器,整个芯片几乎都断电了。电流可以低到几十纳安。
进入待机模式:
HAL_PWR_EnterSTANDBYMode();
唤醒方式只有三种:
- WKUP 引脚上升沿(PA0 等,具体看型号)
- RTC 闹钟或唤醒事件
- NRST 复位引脚
注意,待机模式唤醒后,芯片会从头执行代码,就像按了复位键一样。所以你必须能在 main() 函数开头判断出是“冷启动”还是“待机唤醒”。
判断方法:
if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET) {
// 这是从待机模式唤醒的
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
} else {
// 这是正常上电复位
}
3.5 唤醒源配置实战
唤醒源配置是低功耗设计的核心。我画了一张图,帮你理清思路:
3.6 实际项目中的选择策略
我做了几个低功耗项目后,总结了一套选择逻辑:
- 如果唤醒时间要求 < 5µs → 用睡眠模式。比如传感器数据采集,每次采集间隔 1ms,睡眠模式足够快。
- 如果电池供电,且需要保持数据 → 用停止模式。比如智能手表,大部分时间屏幕熄灭,但 RAM 里的计步数据不能丢。
- 如果产品要放一年不充电 → 用待机模式。比如遥控器,平时完全断电,只有按键按下才唤醒。
3.7 避坑指南:我踩过的三个雷
讲真,低功耗模式看着简单,实际调试起来坑不少。我分享三个亲身经历:
- 坑一:GPIO 浮空漏电。 我曾经有个产品,待机电流比手册多了 10µA。查了两天才发现,有个没用的 GPIO 引脚没配置,处于浮空状态。浮空引脚会反复翻转,产生额外功耗。解决方案:把所有未使用的 GPIO 都配置成模拟输入模式。
- 坑二:RTC 时钟源没配好。 停止模式下,如果 RTC 用的是 LSE 外部晶振,而晶振起振时间太长,会导致唤醒延迟。我后来改用 LSI 内部低速时钟,虽然精度差一点,但唤醒稳定多了。
- 坑三:调试器影响功耗。 这个很多人不知道。SWD 接口的 SWCLK 和 SWDIO 在调试状态下会持续拉高,导致芯片无法真正进入低功耗模式。量产时一定要把这两个引脚配置成普通 GPIO 或上拉输入。