2. MCU的睡眠模式:STM32的睡眠模式、停止模式、待机模式的原理与区别
好,咱们开始聊STM32的睡眠模式。说实话,很多新手工程师一上来就盯着主频、外设、算力这些指标,觉得跑得越快越好。但做低功耗产品,你得学会让MCU“偷懒”——该干活时干活,该睡觉时睡觉。
STM32提供了三种主要的低功耗模式:睡眠模式(Sleep Mode)、停止模式(Stop Mode)和待机模式(Standby Mode)。它们就像三个不同深度的“睡眠状态”,功耗逐级降低,但唤醒代价也逐级增大。我个人习惯把它们比作:打个盹、睡个午觉、和深度冬眠。
2.1 睡眠模式(Sleep Mode)——打个盹
睡眠模式是功耗最低的“清醒”状态。说白了,CPU核心时钟停了,但所有外设、SRAM、寄存器都保持原样。你想想看,CPU不干活了,但其他东西都还通着电。
原理:执行WFI(Wait For Interrupt)或WFE(Wait For Event)指令后,内核时钟关闭。但系统时钟(HCLK、PCLK等)仍然在跑,给外设供电。
唤醒方式:任何中断或事件都能唤醒。我在项目中遇到过用定时器中断做周期性唤醒的场景——每100ms醒来一次,采集传感器数据,然后继续睡。这种方式特别适合传感器轮询类应用。
关键点:睡眠模式下,代码执行状态完全保留。唤醒后直接从WFI/WFE的下一条指令继续执行。就像你打了个盹,醒来后接着刚才的事干。
// 进入睡眠模式示例
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
// 唤醒后从这里继续执行
我的经验:睡眠模式适合那些需要频繁唤醒、且唤醒后要快速响应的场景。比如蓝牙信标广播,每几秒醒来发一次包。功耗大概在mA级别,比正常运行时低一个数量级。
2.2 停止模式(Stop Mode)——睡个午觉
停止模式就深入多了。CPU停了,所有外设时钟也停了,但SRAM和寄存器内容仍然保持。嗯,这里要注意:内部稳压器可以配置为低功耗模式,进一步省电。
原理:关闭所有时钟源(HSE、HSI、PLL等),但1.2V域(包括SRAM、寄存器、备份域)仍然供电。系统时钟完全停止,只有RTC和部分唤醒逻辑还在工作。
唤醒方式:任何外部中断(EXTI)、RTC闹钟、或者特定的外设事件(如USART的起始位检测)都能唤醒。我曾经用RTC闹钟做每天固定时间唤醒的物联网终端——白天睡大觉,凌晨起来上传数据。
避坑指南:我曾经踩过一个坑——停止模式下,如果使用了HSE作为系统时钟,唤醒后需要重新配置时钟源。因为HSE在停止模式下是关闭的,唤醒后默认切回HSI。如果你外设对时钟精度有要求,记得在唤醒后重新初始化时钟树。
// 进入停止模式示例
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// 唤醒后需要重新配置系统时钟
SystemClock_Config(); // 别忘了这步!
| 特性 | 睡眠模式 | 停止模式 |
|---|---|---|
| CPU时钟 | 关闭 | 关闭 |
| 外设时钟 | 保持 | 关闭 |
| SRAM/寄存器 | 保持 | 保持 |
| 典型功耗 | ~mA级 | ~μA级 |
| 唤醒时间 | ~几个时钟周期 | ~几十μs |
2.3 待机模式(Standby Mode)——深度冬眠
待机模式是STM32功耗最低的模式,没有之一。说白了,除了备份域(RTC、备份寄存器、备份SRAM)和唤醒逻辑,其他所有电路都断电了。SRAM内容丢失,寄存器复位,系统几乎回到上电状态。
原理:关闭内部稳压器,1.2V域完全断电。只有VBAT供电的备份域还在工作。唤醒后,系统会从复位向量开始执行——就像重新上电一样。
唤醒方式:只有三种方式:WKUP引脚上升沿、RTC闹钟/唤醒事件、以及NRST引脚复位。我做过一个电池供电的温湿度记录仪,平时待在待机模式,RTC每10分钟唤醒一次,采集数据后存到备份寄存器,然后继续睡。一节CR2032电池撑了两年多。
重要区别:待机模式唤醒后,程序是从头开始执行的!如果你需要保留某些状态,必须用备份寄存器(RTC Backup Registers)来保存。我刚开始用的时候忘了这茬,结果每次唤醒后数据全丢了,排查了半天才发现。
// 进入待机模式示例
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
HAL_PWR_EnterSTANDBYMode();
// 唤醒后从这里开始?不!是从Reset_Handler开始!
我的建议:待机模式适合那些唤醒频率极低(比如一天一次)、且唤醒后不需要保留复杂状态的应用。如果你需要频繁唤醒,还是用停止模式更合适——毕竟待机模式唤醒后的初始化开销也不小。
2.4 三种模式的对比与选择
好了,三种模式都讲完了。你可能会问:到底该用哪个?我个人的经验是:
- 睡眠模式:适合需要频繁唤醒(ms级)、且对响应速度要求高的场景。比如电机控制中的电流环采样。
- 停止模式:适合中等唤醒频率(s级到分钟级)、且需要保留运行状态的场景。比如传感器数据采集节点。
- 待机模式:适合极低唤醒频率(小时级到天级)、且可以接受“冷启动”开销的场景。比如远程环境监测终端。
说白了,没有最好的模式,只有最合适的模式。你得根据你的应用场景——唤醒频率、响应时间要求、数据保留需求——来权衡。我见过有人为了省电,把所有场景都硬塞进待机模式,结果每次唤醒后初始化花了几百ms,反而更费电。嗯,这就是典型的“捡了芝麻丢了西瓜”。
下一章,咱们聊聊如何在实际项目中动态切换这些模式,以及如何测量真实的功耗数据。到时候我会分享一个我踩过的坑——关于电流测量中的“假低功耗”问题。