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备份,问题解决。

三种模式的唤醒流程对比

我画了一张图,帮你理清这三种模式的唤醒路径差异:

Stop / Standby / Shutdown 唤醒流程对比 Stop 模式 外设中断唤醒 从断点继续执行 Standby 模式 WKUP/RTC唤醒 系统复位,从头执行 Shutdown 模式 仅WKUP引脚唤醒 完全复位,备份域丢失 关键差异总结 • Stop:唤醒最快,代码无缝继续,适合频繁唤醒场景 • Standby:唤醒较慢,系统复位但备份域保留,适合周期性任务 • Shutdown:唤醒最慢,完全复位,功耗最低,适合极低功耗场景

如何选择?我的经验法则

说了这么多,到底怎么选?我一般按这个思路来:

  1. 唤醒频率高(>10次/秒):用Stop0,唤醒快,功耗能接受
  2. 唤醒频率中等(1-10次/秒):用Stop1或Stop2,看你对功耗的敏感度
  3. 唤醒频率低(<1次/秒):用Standby,功耗优势明显
  4. 需要保存关键数据:别用Shutdown,用Standby+备份寄存器
  5. 电池供电,几个月不换:Shutdown,但要做好唤醒后的初始化

我的一个小习惯:在产品开发初期,先用Stop2模式调试,等所有功能稳定了,再根据实际功耗需求切换到Standby或Shutdown。这样调试方便,后期优化也有基准数据。