4. 电源管理模式(下):Stop模式、Standby模式与Shutdown模式
上一讲我们把Sleep和Run模式聊透了。这一讲,咱们进入真正的「低功耗深水区」——Stop、Standby和Shutdown。这三种模式,说白了就是让芯片进入不同程度的「休眠」,功耗一个比一个低,但唤醒代价也一个比一个大。
我个人习惯把Stop模式比作「浅睡」,Standby是「深睡」,Shutdown则是「关机」。你想想看,浅睡容易被吵醒,深睡需要闹钟,关机得按电源键——STM32的电源管理,道理差不多。
Stop模式:三种子模式,你选哪个?
Stop模式很有意思,它分了三个等级:Stop0、Stop1、Stop2。我在项目中遇到过不少工程师,一上来就选Stop2,觉得功耗最低就是最好。结果呢?唤醒时间太长,系统响应跟不上。所以选哪个,得看你的场景。
| 特性 | Stop0 | Stop1 | Stop2 |
|---|---|---|---|
| 内核电压保持 | 全保持 | 部分保持 | 几乎全关 |
| SRAM保留 | 全部 | 全部 | 全部 |
| 典型唤醒时间 | ~5 μs | ~10 μs | ~30 μs |
| 典型功耗 | ~200 μA | ~50 μA | ~5 μA |
关键点:Stop模式下,CPU时钟停摆,但SRAM和寄存器内容全部保留。唤醒后,代码从断点处继续执行——就像什么都没发生过。
Stop0:最快唤醒,功耗最高
Stop0保留了完整的内部稳压器。唤醒速度最快,但代价是功耗相对较高。适合那些需要频繁唤醒、每次唤醒后要快速响应的场景——比如电机控制中的电流环。
Stop1:折中方案
Stop1关掉了部分内部稳压器,但SRAM和寄存器依然保留。唤醒时间比Stop0长一倍左右,但功耗能降一个数量级。我个人习惯把它用在传感器数据采集上——每隔几百毫秒醒来一次,读个数据,再睡回去。
Stop2:最省电,唤醒最慢
Stop2几乎把内部稳压器全关了,只保留最低限度的供电。唤醒时间最长,但功耗最低。嗯,这里要注意:Stop2模式下,某些外设的时钟域会被切断,唤醒后需要重新配置。
我曾经踩过的坑:在Stop2模式下,我用了TIM作为唤醒源,结果死活唤不醒。查了半天才发现——TIM的时钟在Stop2下被关了。换成LPTIM(低功耗定时器)才搞定。
Stop模式的唤醒源配置
Stop模式的唤醒源,说白了就是那些「不需要CPU参与就能触发中断」的外设。常用的有:
- EXTI(外部中断):GPIO引脚电平变化,最常用
- LPTIM(低功耗定时器):定时唤醒,精度不错
- RTC(实时时钟):闹钟唤醒,适合周期性任务
- USART(串口):收到数据时唤醒,适合通信场景
- I2C:地址匹配时唤醒
配置代码其实不复杂,我贴一段典型的Stop模式进入流程:
// 进入Stop模式的标准流程
void Enter_Stop_Mode(void)
{
// 1. 配置唤醒源(以EXTI为例)
HAL_EXTI_SetConfigLine(&hexti, EXTI_CONFIG_LINE_0,
GPIO_PIN_0, EXTI_TRIGGER_FALLING);
// 2. 选择Stop子模式
HAL_PWREx_EnableLowPowerRunMode(); // 可选,进一步降频
HAL_PWREx_EnterSTOPMode(PWR_STOPENTRY_WFI,
PWR_STOPMODE_STOP2);
// 3. 唤醒后自动从这里继续
// 注意:唤醒后需要重新配置系统时钟!
SystemClock_Config();
}
小技巧:唤醒后第一件事就是重新配置系统时钟。因为Stop模式下,HSE和PLL都被关了,默认会切到HSI。如果你跑的是72MHz,醒来后变成8MHz,那感觉就像从高速路突然拐进小巷子。
Standby模式:真正的「深睡」
Standby模式比Stop更狠——它把整个1.2V内核域都断电了。SRAM内容?没了。寄存器?没了。唤醒后,芯片会像复位一样从头执行代码。
你可能会问:「那跟复位有什么区别?」区别在于——RTC和备份寄存器还在。也就是说,你可以保留一些关键数据在备份域里,唤醒后读出来。
| 特性 | Standby | Stop2 |
|---|---|---|
| 内核域供电 | 完全断电 | 部分保留 |
| SRAM内容 | 丢失 | 保留 |
| 备份寄存器 | 保留 | 保留 |
| 唤醒方式 | WKUP引脚/RTC/复位 | 多种外设中断 |
| 典型功耗 | ~0.5 μA | ~5 μA |
Standby的唤醒源
Standby的唤醒源非常有限,就那么几个:
- WKUP引脚:PA0、PC13、PE6等特定引脚,上升沿唤醒
- RTC闹钟:定时唤醒
- RTC入侵事件:安全场景用
- NRST引脚复位:外部复位
- IWDG复位:独立看门狗超时
重要提醒:Standby唤醒后,代码从SystemInit开始执行。如果你需要区分是「上电复位」还是「Standby唤醒」,可以检查PWR->SR1寄存器的WUF位。
Shutdown模式:功耗最低,代价最大
Shutdown模式是STM32的「终极省电模式」。它比Standby更进一步——连备份域的部分供电都切了。RTC?可能不工作了。备份寄存器?可能丢了。
说白了,Shutdown就是让芯片进入「几乎完全断电」的状态。功耗可以低到几十纳安。但代价是——唤醒后,芯片完全复位,连备份域的数据都不保证保留。
| 特性 | Shutdown | Standby |
|---|---|---|
| 备份域供电 | 部分或全部切断 | 保留 |
| RTC功能 | 可能不可用 | 可用 |
| 唤醒源 | 仅WKUP引脚 | WKUP/RTC/复位 |
| 典型功耗 | ~30 nA | ~0.5 μA |
我曾经犯过的错:在一个电池供电的产品里,我用了Shutdown模式,想着功耗最低最好。结果客户反馈说设备偶尔「死机」——其实是Shutdown唤醒后,RTC时间丢了,导致定时任务全乱套。后来换成Standby+RTC备份,问题解决。
三种模式的唤醒流程对比
我画了一张图,帮你理清这三种模式的唤醒路径差异:
如何选择?我的经验法则
说了这么多,到底怎么选?我一般按这个思路来:
- 唤醒频率高(>10次/秒):用Stop0,唤醒快,功耗能接受
- 唤醒频率中等(1-10次/秒):用Stop1或Stop2,看你对功耗的敏感度
- 唤醒频率低(<1次/秒):用Standby,功耗优势明显
- 需要保存关键数据:别用Shutdown,用Standby+备份寄存器
- 电池供电,几个月不换:Shutdown,但要做好唤醒后的初始化
我的一个小习惯:在产品开发初期,先用Stop2模式调试,等所有功能稳定了,再根据实际功耗需求切换到Standby或Shutdown。这样调试方便,后期优化也有基准数据。