2、MCU低功耗模式详解:睡眠模式、深度睡眠模式、待机模式、唤醒源配置
各位同学,咱们接着聊。上一章我把MCU功耗的来龙去脉讲清楚了,这一章咱们直接上手——看看MCU到底怎么「睡」。
你想想看,一个物联网设备,大部分时间都在那傻等着。要么等传感器数据,要么等网络指令。如果这时候CPU还在全速跑,那电池不就跟漏了底似的?所以,低功耗模式就是让MCU在「没事干」的时候,把能关的都关了。
我个人习惯把MCU的功耗模式分成三个档次:打个盹、睡个觉、彻底躺平。对应到芯片手册里,就是睡眠、深度睡眠和待机。
2.1 睡眠模式:打个盹,随叫随到
睡眠模式是最浅的休眠。说白了,CPU核心停了,但外设和RAM都还活着。
我在项目中遇到过这种情况:一个温湿度采集器,每5秒读一次传感器。读数据的时候CPU全速跑,读完了就没事干了。这时候进睡眠模式最合适。为什么?因为唤醒速度极快,基本是纳秒级,醒来就能干活。
睡眠模式下,哪些东西还在工作?
- RAM内容完整保留
- 所有GPIO状态保持
- 定时器、UART、SPI等外设继续运行
- 中断控制器正常工作
嗯,这里要注意:睡眠模式虽然省电,但省得有限。一般电流在mA级别,比正常跑低一个数量级。如果你需要微安级别的功耗,那得往下看。
核心要点:睡眠模式 = CPU停 + 外设活 + RAM保。唤醒最快,功耗最高(相对其他低功耗模式)。
2.2 深度睡眠模式:睡个觉,省电又保数据
深度睡眠模式,这才是真正意义上的「低功耗」。CPU停了,大部分外设也停了,只留几个关键模块。
我记得有一次做电池供电的定位器,要求待机电流低于10微安。睡眠模式根本达不到,只能上深度睡眠。当时我保留了RTC和几个唤醒引脚,其他全关了。实测下来,整机待机电流才6.8微安,完美达标。
深度睡眠模式下,通常保留的东西:
- RAM内容保留(大部分芯片支持)
- RTC(实时时钟)继续走
- 指定的唤醒IO保持检测能力
- 部分芯片保留低功耗定时器
那什么东西被关了?
- 主时钟和PLL
- Flash控制器
- 大部分外设时钟
- ADC、DAC等模拟模块
唤醒时间就长了,一般在几十微秒到几百微秒。为什么?因为要重新锁相环、重新初始化时钟树。所以,如果你的应用需要频繁唤醒(比如每秒一次),深度睡眠反而不划算——唤醒那一下的功耗可能比多睡一会儿还高。
实战技巧:我一般这样选——唤醒间隔大于100ms,用深度睡眠;小于10ms,用睡眠模式。中间那档,看具体功耗预算。
2.3 待机模式:彻底躺平,最低功耗
待机模式,这是MCU的「终极省电形态」。说白了,除了几个唤醒引脚和RTC,其他全断电。连RAM里的数据都不保了。
我曾经做过一个货架标签项目,电池要用三年。这种场景下,设备99.9%的时间都在待机。每次唤醒就是更新一下显示内容,然后立刻又躺回去。待机电流能做到几十纳安,一颗纽扣电池撑三年完全没问题。
待机模式的特点:
- RAM数据丢失(重要!)
- 所有外设断电
- 只有RTC和唤醒逻辑在工作
- 唤醒后相当于复位,从头执行代码
警告:待机模式唤醒后,所有变量都丢了。如果你需要保留某些数据,要么存到RTC备份寄存器里,要么写Flash。我刚开始做项目时就吃过这个亏——待机唤醒后,计数器莫名其妙归零了,查了两天才发现是RAM没保住。
2.4 唤醒源配置:怎么叫醒MCU?
模式选好了,还得知道怎么唤醒。不同的模式,能用的唤醒源不一样。我整理了一张表,大家一看就明白:
| 唤醒源 | 睡眠模式 | 深度睡眠 | 待机模式 |
|---|---|---|---|
| 外部中断(GPIO) | ✓ | ✓ | ✓(特定引脚) |
| RTC闹钟 | ✓ | ✓ | ✓ |
| UART接收 | ✓ | ✗ | ✗ |
| 定时器溢出 | ✓ | ✗(部分芯片支持) | ✗ |
| 比较器触发 | ✓ | ✓(部分芯片) | ✗ |
| 复位引脚 | ✓ | ✓ | ✓ |
配置唤醒源,说白了就是三步:
- 选源:根据应用场景选合适的唤醒源。定时唤醒用RTC,外部触发用GPIO中断。
- 配置:设置触发条件。比如GPIO是上升沿还是下降沿,RTC闹钟定在什么时候。
- 使能:在进入低功耗模式前,确保唤醒功能已经打开。
我贴一段STM32的代码示例,大家感受一下:
// 进入深度睡眠模式,RTC闹钟唤醒
void enter_deep_sleep_with_rtc(void)
{
// 1. 配置RTC闹钟(假设RTC已初始化)
RTC_SetAlarm(RTC_Alarm_1, 0, 0, 0, RTC_AlarmDateWeekDaySel_Date, 1);
// 2. 使能RTC闹钟中断
RTC_ITConfig(RTC_IT_ALR, ENABLE);
// 3. 配置系统时钟进入深度睡眠
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
// 4. 唤醒后从这里继续执行
// 注意:需要重新配置系统时钟!
SystemClock_Config();
}
避坑指南:我曾经犯过一个低级错误——进入深度睡眠前忘了关外设时钟。结果功耗比预期高了10倍。后来养成习惯:进低功耗前,先遍历一遍所有外设,该关的关,该停的停。
2.5 三种模式怎么选?
最后,我给大家一个简单的选择逻辑:
- 需要频繁响应(毫秒级) → 睡眠模式
- 需要保RAM,唤醒间隔百毫秒以上 → 深度睡眠
- 追求极致功耗,RAM数据不重要 → 待机模式
嗯,其实很多项目里,这三种模式会混合使用。比如平时待机,有事件来了进深度睡眠处理,处理完了再躺回去。灵活搭配才是王道。
下一章,咱们聊聊电源管理单元(PMU)的硬件设计。那个坑更多,我到时候一个个给你们拆解。