2. STM32L4 低功耗模式详解:睡眠、停止、待机
做低功耗产品,说白了就是跟电池容量较劲。STM32L4 这颗芯片之所以受欢迎,就是因为它给了你三种省电模式——睡眠、停止、待机。每种模式的功耗、唤醒速度、保留资源都不一样。
我刚开始做低功耗项目时,总觉得「能进停止模式就行」。结果产品做出来,待机电流死活降不下去。后来才发现,是没搞清楚这三种模式的本质区别。今天咱们就把它们掰开揉碎了讲清楚。
核心原则:功耗越低,唤醒越慢,保留的资源越少。没有万能模式,只有最适合当前场景的模式。
2.1 睡眠模式(Sleep Mode)
睡眠模式是功耗最低的「假寐」状态。CPU 停了,但外设还在跑。说白了,就是 CPU 把活丢给外设,自己睡大觉。
怎么进?执行 WFI 或 WFE 指令就行。在 FreeRTOS 里,空闲任务钩子函数就是干这个的。
// 进入睡眠模式
__WFI(); // Wait For Interrupt
唤醒源:任何中断或事件都能唤醒。定时器、串口、GPIO 外部中断,统统可以。
功耗数据:
| 参数 | 典型值 | 说明 |
|---|---|---|
| 核心电流 | ~100 µA/MHz | 外设还在跑,电流跟主频挂钩 |
| 唤醒时间 | 几个 CPU 周期 | 几乎无延迟,秒醒 |
| SRAM 保留 | 全部保留 | 数据不丢 |
我的习惯:在 FreeRTOS 空闲任务里调用 __WFI(),配合 tickless 模式,能省下不少电。但要注意——如果系统里还有高优先级任务在跑,空闲任务根本不会执行,WFI 也就进不去。
2.2 停止模式(Stop Mode)
停止模式才是真正意义上的「低功耗」。CPU 停了,大部分外设也停了,只有少数几个模块还在工作——比如 RTC、LPUART、LPTIM。
我有个项目做智能门锁,平时门锁待机,用 RTC 定时唤醒检查网络状态。用的就是停止模式。待机电流能做到 1.5 µA 左右,两节 AA 电池撑一年没问题。
怎么进?
// 进入停止模式(保留 SRAM1 和 SRAM2)
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
唤醒源:
- RTC 闹钟/唤醒定时器
- LPUART 接收中断
- LPTIM 超时
- GPIO 外部中断(部分引脚)
- 比较器触发
功耗数据:
| 配置 | 典型电流 | 唤醒时间 |
|---|---|---|
| Stop 0(主稳压器) | ~8 µA | ~5 µs |
| Stop 1(低功耗稳压器) | ~3 µA | ~10 µs |
| Stop 2(更低功耗) | ~1 µA | ~15 µs |
我曾经踩过的坑:停止模式下,HSE 和 HSI 都停了。如果你唤醒后需要高速时钟,得重新配置。有一次我忘了在唤醒后重新初始化 PLL,结果系统跑在 MSI 上,串口波特率全乱套了。
2.3 待机模式(Standby Mode)
待机模式是「深度睡眠」。除了 RTC 和备份域,其他全部断电。SRAM 里的数据?对不起,全没了。
这个模式适合什么场景?产品长期不用,只需要偶尔唤醒报个到。比如智能水表,一个月上报一次数据,平时就待在待机模式里。
怎么进?
// 进入待机模式
HAL_PWR_EnterSTANDBYMode();
唤醒源:
- RTC 闹钟
- WKUP 引脚上升沿(PA0、PC13 等)
- 复位(NRST 引脚或看门狗复位)
功耗数据:
| 参数 | 典型值 | 说明 |
|---|---|---|
| 待机电流 | ~100 nA | 仅 RTC 和备份域供电 |
| 唤醒时间 | ~50 µs | 相当于复位重启 |
| SRAM 保留 | 不保留 | 数据丢失,需重新初始化 |
我的建议:待机模式唤醒后,程序会从 main 函数重新开始执行。你可以在 startup 代码里检查复位原因,判断是上电复位还是待机唤醒。这样就能决定要不要重新初始化所有外设。
2.4 三种模式对比总表
| 特性 | 睡眠模式 | 停止模式 | 待机模式 |
|---|---|---|---|
| CPU 状态 | 停止 | 停止 | 断电 |
| 外设状态 | 运行 | 大部分停止 | 全部断电 |
| SRAM 保留 | 全部 | 全部或部分 | 不保留 |
| 典型电流 | ~100 µA/MHz | 1~8 µA | ~100 nA |
| 唤醒时间 | ~1 µs | 5~15 µs | ~50 µs |
| 唤醒源 | 任何中断 | 有限中断 | RTC/WKUP/复位 |
| 适用场景 | 频繁唤醒 | 周期性唤醒 | 长期待机 |
2.5 模式选择决策流程
你想想看,实际项目中怎么选?我一般按这个逻辑来:
- 唤醒频率高(每秒几十次以上)→ 睡眠模式
- 唤醒频率中等(每秒几次到几分钟一次)→ 停止模式
- 唤醒频率极低(几小时甚至几天一次)→ 待机模式
但要注意,这不是绝对的。如果睡眠模式下外设功耗太高,还不如进停止模式。我有个项目就是——睡眠模式跑着 LPUART 和 LPTIM,结果电流比停止模式还大。后来干脆改成停止模式,用 RTC 定时唤醒,反而更省电。
经验之谈:别只看芯片手册上的理论值。实际功耗跟你的外设配置、PCB 布局、甚至温度都有关系。我建议你拿到板子后,先跑一遍三种模式,用万用表实测一下,心里才有底。
2.6 实际项目中的避坑指南
最后,分享几个我实际项目中遇到的坑:
- GPIO 浮空问题:进入低功耗模式前,所有未使用的 GPIO 必须配置为模拟模式或上拉/下拉输出。浮空的 GPIO 会漏电,我见过一个项目因为几个浮空引脚,待机电流从 1 µA 飙到 50 µA。
- RTC 时钟源选择:停止模式和待机模式下,RTC 只能用 LSE(32.768 kHz 晶振)。如果用 LSI,精度不够,一天能差好几秒。
- 唤醒后时钟恢复:从停止模式唤醒后,系统默认使用 MSI 时钟。如果你需要高速时钟,记得在唤醒中断里重新配置 PLL。
- 调试器干扰:连接 ST-Link 调试时,芯片可能无法进入真正的低功耗模式。我一般用串口打印来调试低功耗代码,或者断开调试器直接测电流。
重要提醒:低功耗调试时,别只看电流表。用示波器抓一下唤醒瞬间的电流波形,看看有没有尖峰。有些外设在唤醒瞬间会有一个大电流脉冲,如果电源设计不够强壮,可能会把系统拉复位。