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接收
定时器溢出 ✗(部分芯片支持)
比较器触发 ✓(部分芯片)
复位引脚

配置唤醒源,说白了就是三步:

  1. 选源:根据应用场景选合适的唤醒源。定时唤醒用RTC,外部触发用GPIO中断。
  2. 配置:设置触发条件。比如GPIO是上升沿还是下降沿,RTC闹钟定在什么时候。
  3. 使能:在进入低功耗模式前,确保唤醒功能已经打开。

我贴一段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)的硬件设计。那个坑更多,我到时候一个个给你们拆解。