2、MCU的睡眠模式详解:待机模式、停止模式、休眠模式的区别与选择策略
做低功耗设计,说白了就是跟MCU的“睡法”打交道。
很多工程师一上来就翻数据手册,看到Sleep、Stop、Standby三个词就头大。我刚开始做项目时也踩过这个坑——选错了模式,要么功耗下不去,要么唤醒后系统直接“失忆”。
这一节,咱们就把这三种模式彻底讲透。
2.1 三种模式的本质差异
先看一张总览表,心里有个底。
| 特性 | 休眠模式 (Sleep) | 停止模式 (Stop) | 待机模式 (Standby) |
|---|---|---|---|
| CPU时钟 | 关闭 | 关闭 | 关闭 |
| SRAM/寄存器 | 保持 | 保持 | 丢失 |
| 主要时钟源 | 运行 | 可关闭 | 全部关闭 |
| 唤醒源 | 任意中断 | 有限中断/事件 | 特定唤醒引脚/RTC |
| 唤醒时间 | ~1 µs | ~10 µs | ~100 µs ~ ms |
| 典型电流 | mA级 | µA级 | nA级 |
| 代码执行连续性 | 完全连续 | 连续 | 重新启动 |
你想想看,这三种模式其实是在“功耗”和“唤醒代价”之间做权衡。没有绝对的好坏,只有合不合适的场景。
2.2 休眠模式(Sleep Mode)—— 打个盹
休眠模式是MCU最浅的睡眠。CPU停了,但外设和时钟还在跑。
我记得有一次调试一个传感器采集项目,采样间隔只有1ms。用Stop模式根本来不及唤醒,最后选了Sleep模式,配合DMA传输,完美搞定。
适用场景:
- 需要频繁、快速响应的任务(如按键扫描、通信轮询)
- 外设仍在工作(如定时器、ADC连续采样)
- 唤醒延迟必须控制在微秒级
代码示例也很简单:
// 进入休眠模式(以STM32为例)
HAL_SuspendTick(); // 暂停系统滴答,避免频繁唤醒
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
// 醒来后继续执行下一行
HAL_ResumeTick();
这里有个坑:WFI(Wait For Interrupt)和WFE(Wait For Event)的区别。WFI需要中断发生才能唤醒,WFE只要有事件就能唤醒。我个人习惯用WFI,因为更可控。
2.3 停止模式(Stop Mode)—— 睡个整觉
停止模式就狠多了。CPU停了,大部分时钟也停了,但SRAM和寄存器内容还在。
为什么说“大部分”?因为你可以选择保留低速时钟(如LSI、LSE)给RTC或独立看门狗用。
我的经验:
在物联网终端设备中,Stop模式是最常用的。比如LoRa节点,每几秒醒来发一次数据,平时就待在Stop模式。电流能压到几个µA,唤醒时间几十微秒,完全够用。
进入Stop模式的代码:
// 进入停止模式,保留RTC
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// 系统时钟需要重新配置!
SystemClock_Config();
注意:从Stop模式唤醒后,HSE/PLL等高速时钟默认是关闭的。你必须手动重新配置系统时钟,否则MCU会以低速时钟运行,性能大打折扣。我曾经因为这个原因,导致一个显示刷新任务卡了整整半天。
2.4 待机模式(Standby Mode)—— 深度冬眠
待机模式是功耗最低的模式,没有之一。SRAM没了,寄存器没了,除了备份域(Backup Domain)里的RTC和几个唤醒引脚,其他全部断电。
唤醒后,MCU的行为跟复位几乎一样——从main函数重新开始执行。
代码示例:
// 进入待机模式
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
HAL_PWR_EnterSTANDBYMode();
// 唤醒后从这里重新开始
关键点:
- 唤醒后系统复位,所有变量需要重新初始化
- 备份域(Backup SRAM)可以保存少量关键数据
- 唤醒源只有:WKUP引脚上升沿、RTC闹钟、入侵检测等
我曾经在一个电池供电的温湿度记录仪上用过Standby模式。设备每10分钟醒来一次,采集数据存到Flash,然后继续睡。一节CR2032电池撑了两年多。
2.5 选择策略:到底该用哪个?
这个问题没有标准答案,但我给你一个决策流程,照着走基本不会错。
总结一下我的个人经验:
- 需要频繁响应(ms级间隔) → 休眠模式
- 需要低功耗且保留上下文 → 停止模式
- 需要极低功耗且可以接受复位式唤醒 → 待机模式
避坑指南:
我曾经在一个项目中,为了追求极致功耗,直接用了Standby模式。结果发现每次唤醒后,外设初始化时间太长,导致数据采集出现了时间戳错位。后来改成了Stop模式,虽然功耗多了2µA,但系统稳定多了。
记住:低功耗设计不是一味追求最低功耗,而是在满足功能的前提下,选择最合适的模式。