2. STM32低功耗模式详解:睡眠、停止、待机

低功耗设计,说白了就是让芯片在没事干的时候少喝电。STM32给了我们三种省电模式:睡眠、停止、待机。很多初学者一上来就纠结选哪个,其实没那么复杂——你想想看,省电越狠,醒来就越麻烦,这是个取舍问题。

我个人习惯是先看项目需求:要保留什么、要多快醒来、能接受多大电流。搞清楚这三点,模式自然就定了。

2.1 三种模式的核心差异

先上一张对比表,后面再细说。这张表我建议你收藏,调试时经常翻出来看。

特性 睡眠模式 停止模式 待机模式
CPU时钟 关闭 关闭 关闭
SRAM/寄存器 保持 保持 丢失
外设时钟 可选关闭 关闭 关闭
唤醒源 任意中断/事件 有限中断/事件 RTC/WKUP引脚/复位
典型电流 ~mA级 ~μA级 ~nA级
唤醒时间 ~μs ~μs ~ms
代码是否继续 从WFI后继续 从WFI后继续 从头启动

关键判断点:待机模式会清空SRAM,相当于芯片复位。如果你的数据不能丢,就别选待机。我在项目中吃过这个亏,后面会讲。

2.2 睡眠模式(Sleep Mode)

睡眠模式是最温柔的省电方式。它只停了CPU的时钟,其他一切照旧。SRAM里的数据、外设的寄存器、中断控制器,全都在线。

进入方式很简单:执行WFI(Wait For Interrupt)或WFE(Wait For Event)指令。我一般用WFI,因为更直观——等一个中断来了就醒。

// 进入睡眠模式(WFI方式)
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);

// 醒来后,程序从下一行继续执行
// 注意:醒来后先进入中断服务函数,再回到这里

小技巧:进入睡眠前,先把不用的外设时钟关了。虽然睡眠模式本身省电有限,但配合外设时钟门控,能把电流从十几mA压到几mA。我习惯在进入睡眠前调用一次 HAL_RCC_DisableClock() 批量关掉无用外设。

睡眠模式的唤醒速度极快,基本在几个微秒内。适合那种频繁醒来、每次干活时间很短的应用,比如按键扫描、LED闪烁。

2.3 停止模式(Stop Mode)

停止模式才是真正开始省电的地方。它停了所有时钟,包括CPU和外设的。但SRAM和寄存器内容还在,因为主电源没断。

这里有个重要概念:稳压器模式。停止模式有两种稳压器设置:

  • 主稳压器开启(MR): 唤醒快,但电流稍大(~μA级)
  • 低功耗稳压器(LPR): 唤醒慢一点,但电流更低

我做过一个温湿度采集项目,每10秒醒一次,用的就是停止模式+LPR。实测电流在1.2μA左右,一节CR2032电池撑了两年多。

// 进入停止模式(低功耗稳压器)
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

// 醒来后需要重新配置系统时钟
SystemClock_Config();  // 这一步不能省!

注意:从停止模式醒来后,系统时钟默认用的是HSI。如果你之前用的是HSE或PLL,必须手动重新配置时钟树。我见过有人忘了这一步,醒来后串口乱码、定时器不准,查了半天才发现是时钟没恢复。

停止模式的唤醒源有限制:只能通过RTC闹钟、外部中断(EXTI)、USART等少数外设唤醒。不像睡眠模式那样任意中断都能醒。

2.4 待机模式(Standby Mode)

待机模式是省电的终极形态。它把主电源都关了,只留一个备份域供电。SRAM和寄存器全部丢失,芯片醒来后相当于按了复位键。

电流能压到多低?以STM32L4系列为例,待机模式典型电流只有30nA左右。这个级别,电池自放电都比芯片耗电多。

// 进入待机模式
HAL_PWR_EnterSTANDBYMode();

// 程序不会继续执行,芯片相当于复位
// 醒来后从main函数开头重新跑

待机模式的唤醒源只有三个:

  • RTC闹钟或唤醒定时器
  • WKUP引脚上升沿
  • NRST复位引脚

我曾经踩过的坑:有个产品需要记录累计运行时间,我用了待机模式。结果每次醒来SRAM清零,计时数据全丢了。后来改用RTC备份寄存器保存数据,才解决问题。记住:待机模式下,只有备份域(RTC、备份寄存器)的内容能保留。

2.5 选择策略:到底该用哪个?

这个问题没有标准答案,但我总结了一套判断逻辑,你可以照着走:

  1. 先问:数据能不能丢?
    • 不能丢 → 排除待机模式
    • 能丢 → 三种都可以考虑
  2. 再问:唤醒要多快?
    • 需要μs级响应 → 睡眠模式
    • μs级可以接受 → 停止模式
    • ms级无所谓 → 待机模式
  3. 最后问:电流目标是多少?
    • mA级够用 → 睡眠模式
    • μA级 → 停止模式
    • nA级 → 待机模式

我个人的经验是:80%的项目用停止模式就够了。睡眠模式省电有限,待机模式限制太多。停止模式在功耗和功能之间取得了最好的平衡。

2.6 三种模式的关系图

下面这张图展示了三种模式的层级关系。越往下,功耗越低,但唤醒代价越大。

STM32低功耗模式层级关系 睡眠模式 CPU停钟 · 外设可选 · 任意中断唤醒 停止模式 所有时钟停 · SRAM保持 · 有限唤醒源 待机模式 主电源断 · SRAM丢 · 复位式唤醒 ↓ 功耗递减 · 唤醒代价递增 · 功能保留递减 ~mA ~μA ~nA

2.7 实际项目中的选择案例

我整理了几个真实项目中的选择,供你参考:

应用场景 推荐模式 理由
蓝牙信标(每秒广播一次) 停止模式 需要μA级功耗,RTC定时唤醒
智能门锁(按键唤醒) 停止模式 需要保留锁状态,EXTI唤醒快
温湿度传感器(10分钟上报) 待机模式 nA级功耗,数据可重新采集
电机控制(频繁启停) 睡眠模式 需要μs级响应,外设不停
车载OBD诊断(CAN唤醒) 停止模式 需要保留CAN配置,CAN唤醒

我的建议:刚开始做低功耗设计时,先别追求极致。从停止模式入手,把功能跑通,再考虑要不要往待机模式压。我见过太多人一上来就搞待机,结果唤醒逻辑搞不定,项目延期。

嗯,三种模式的区别和选择策略就讲到这里。记住那个判断逻辑:数据能不能丢、唤醒要多快、电流目标是多少。下次调试低功耗项目时,按这个顺序走一遍,基本不会选错。