2. MCU工作模式详解:主动模式、睡眠模式、深度睡眠模式、待机模式的功耗对比与切换机制

各位做嵌入式开发的朋友,咱们今天来聊聊MCU的几种工作模式。说实话,这玩意儿是低功耗设计的核心。你想想看,一个电池供电的设备,如果不会用这些模式,那续航基本就废了。

我刚开始做低功耗项目时,踩过不少坑。有一次产品都量产了,发现待机电流比预期大了10倍。查了三天,最后发现是GPIO没配置好,导致深度睡眠模式下漏电。嗯,从那以后,我对每种模式的细节都格外小心。

2.1 四种核心工作模式概览

大部分MCU都提供这四种模式,从高功耗到低功耗排列:

  • 主动模式(Active Mode):CPU全速运行,所有外设都能用。功耗最高,一般在几十mA到几百mA。
  • 睡眠模式(Sleep Mode):CPU停了,但外设还在跑。像定时器、UART这些都能工作。功耗能降到几mA。
  • 深度睡眠模式(Deep Sleep Mode):CPU和外设大部分都停了,只保留少量唤醒源。功耗能到几十μA甚至几μA。
  • 待机模式(Standby Mode):几乎全停了,只留RTC和几个唤醒引脚。功耗最低,能做到1μA以下。

关键点:功耗每降一个数量级,恢复时间就会增加一个数量级。这是你需要权衡的。

2.2 功耗对比:一个真实的数据表

我拿STM32L4系列举个例子,这是我在项目中常用的芯片。数据来自官方手册,但我在实际测试中验证过,基本吻合。

工作模式 典型功耗 唤醒时间 可用外设 唤醒源
主动模式(@80MHz) ~100 μA/MHz 全部
睡眠模式 ~1.5 mA ~5 μs CPU停止,外设运行 任何中断
深度睡眠模式 ~30 μA ~50 μs RTC、LPUART、部分GPIO RTC、外部中断、LPUART
待机模式 ~0.3 μA ~5 ms RTC、唤醒引脚 RTC、WKUP引脚、复位

你看这个表,从睡眠到深度睡眠,功耗降了50倍,但唤醒时间也长了10倍。从深度睡眠到待机,功耗又降了100倍,但唤醒时间长了100倍。这就是我说的权衡。

我的习惯:在项目中,我会先算清楚设备的唤醒周期。如果每100ms唤醒一次,用深度睡眠就够了。如果每10秒唤醒一次,那待机模式更合适。

2.3 切换机制:怎么进怎么出

每种模式的切换方式都不一样。我给大家总结一下:

主动模式 → 睡眠模式

最简单。执行一条WFI(Wait For Interrupt)或WFE(Wait For Event)指令就行。CPU停下来了,但系统时钟还在跑。任何中断都能唤醒。

// 进入睡眠模式
__WFI();  // 等待中断
// 醒来后继续执行下一行代码

这里有个坑:我记得有一次,我用了WFI,但中断优先级没配好,导致中断响应后直接返回了睡眠状态。设备就卡死了。后来我加了个循环判断,确保中断处理完才继续。

主动模式 → 深度睡眠模式

需要配置寄存器。以STM32为例,要设置PWR寄存器,选择深度睡眠模式,然后执行WFI。

// 进入深度睡眠模式
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
// 或者用寄存器操作
PWR->CR |= PWR_CR_LPSDSR;  // 低功耗稳压器
__WFI();

为什么要先配稳压器?因为深度睡眠模式下,内核电压会降低,所以要先告诉电源管理单元做好准备。我刚开始没注意这个,结果进入深度睡眠后,SRAM数据全丢了。嗯,教训深刻。

主动模式 → 待机模式

这个最彻底。所有寄存器和SRAM都会丢失,只有备份寄存器和RTC保留。进入前要清空唤醒标志,然后设置待机位。

// 进入待机模式
HAL_PWR_EnterSTANDBYMode();
// 或者
PWR->CR |= PWR_CR_PDDS;  // 设置待机模式
PWR->CR |= PWR_CR_CWUF;  // 清除唤醒标志
__WFI();

警告:进入待机模式前,一定要保存好关键数据。因为醒来后,程序会从头开始执行,就像复位一样。我见过有人把重要变量放在SRAM里,结果待机后全丢了,产品直接死机。

2.4 实际项目中的选择策略

我个人习惯这样选:

  1. 需要频繁响应(1ms以内):用睡眠模式。比如电机控制、实时通信。
  2. 周期性任务(10ms-1s):用深度睡眠模式。比如传感器采集、LED闪烁。
  3. 长时间待机(1s以上):用待机模式。比如遥控器、智能门锁。

你想想看,一个智能门锁,大部分时间都在等用户按指纹。如果每100ms唤醒一次检查按键,用深度睡眠就够了。但如果用待机模式,唤醒要5ms,用户按了键要等5ms才有反应,体验就差了。

所以,没有最好的模式,只有最合适的模式。我在项目中经常做功耗测试,用示波器抓电流波形,看看实际功耗和唤醒时间是否满足要求。嗯,这一步不能省。

2.5 避坑指南

最后,分享几个我踩过的坑:

  • GPIO浮空:进入低功耗模式前,所有GPIO要配置成输出低或上拉输入。浮空引脚会漏电,我吃过亏。
  • 外设时钟没关:进入深度睡眠前,要手动关闭不用的外设时钟。有些MCU不会自动关。
  • 唤醒源没配置:进入待机模式前,要确保唤醒引脚配置正确。否则设备就睡死了,只能按复位键。
  • 调试器干扰:用JLink调试时,MCU可能无法进入深度睡眠。因为调试接口还在工作。我一般用串口打印来调试低功耗代码。

好了,这四种模式就讲到这里。下一章我会讲如何用RTOS配合这些模式,实现更灵活的低功耗调度。到时候咱们再聊。