4. STM32低功耗模式详解
STM32的低功耗设计并不是“一个模式打天下”,而是一组按功耗、保持域、唤醒延迟和可用唤醒源逐级取舍的状态集合。以STM32U5/L4等常见低功耗系列为例,Sleep、Stop0/1/2、Standby、Shutdown构成了一条从“内核停、外设活”到“几乎全断、仅少数引脚可唤醒”的连续谱。理解这条谱系的关键,不是背表格,而是抓住三个维度:哪些电源域还活着、哪些时钟还开着、哪些事件能把MCU拉回来。
一、Sleep:最轻的“打盹”
Sleep模式只停CPU内核时钟,外设时钟、SRAM、寄存器全部保持。进入方式极简单:执行__WFI()或__WFE(),内核即停。任何使能的中断都能把它唤醒,唤醒延迟几乎为零。它的典型电流在mA级,适合“主循环里等一个事件”的场景,比如等待ADC转换完成、等待串口收包。但要注意:如果外设时钟没关,功耗降不下来;真正省电的做法是进Sleep前把不用的外设时钟关掉。
二、Stop0/1/2:逐级关断的“深睡”
Stop系列停掉所有高速时钟(HSI/HSE/PLL),SRAM和寄存器保持,但调压器状态不同。Stop0保留主调压器,Stop1切到低功耗调压器,Stop2进一步关闭调压器并只保持部分SRAM(如SRAM2)。三者唤醒源相同:EXTI线(任意GPIO边沿)、RTC闹钟/唤醒定时器、LPUART/LPTIM等低功耗外设。唤醒后从__WFI()下一行继续执行,不需要重新初始化,唤醒时间在µs级。
进入Stop的典型代码序列:
// 以Stop2为例
HAL_SuspendTick(); // 停SysTick,否则会立刻唤醒
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
// 唤醒后时钟恢复为HSI,需重新配置系统时钟
SystemClock_Config();
HAL_ResumeTick();
这里有两个容易踩的坑:一是SysTick没关,中断会立刻把MCU唤醒,看起来“根本没睡”;二是唤醒后系统时钟默认切回HSI,如果应用依赖HSE精度,必须重新调用时钟配置。
三、Standby与Shutdown:接近“关机”
Standby关闭所有电源域,SRAM和寄存器内容丢失,只有备份域(RTC、备份寄存器)靠VBAT维持。唤醒源只剩WKUP引脚、RTC闹钟、独立看门狗等少数几个。唤醒后MCU执行复位序列,程序从main()重新开始,因此必须在唤醒后判断是上电复位还是Standby唤醒,再决定是否恢复现场。Shutdown比Standby更彻底,连备份域都关,仅WKUP引脚能唤醒,功耗最低,适合“长期休眠、偶尔按键唤醒”的产品。
四、唤醒源配置要点
EXTI唤醒需要把对应GPIO配置为中断模式并使能EXTI线,同时在PWR寄存器中允许该线唤醒。RTC唤醒则要配置RTC闹钟或唤醒定时器,并确保RTC时钟源(LSE/LSI)在低功耗下仍在运行。LPUART唤醒要求波特率匹配,且唤醒后要检查LPUART_ISR中的WUF标志。所有唤醒源配置完成后,建议先用调试器观察进入低功耗前后的电流,确认没有“假睡”。
五、功耗数据与实测判断
数据手册给出的典型值只能作为起点。实际产品中,GPIO漏电流、外部上拉电阻、LDO静态电流、未关的外设时钟都会让实测值远高于手册。建议在进入低功耗前,把未使用的GPIO配置为模拟输入或输出低,关闭所有不用的外设时钟,再测量VBAT和VDD电流。如果实测电流比预期高一个数量级,优先检查:是否有GPIO悬空、是否有外设时钟未关、调试器是否还连接着(SWD引脚会引入漏电)。
掌握这五种模式的进入退出条件和唤醒源差异,才能在“响应速度”和“功耗”之间做出有依据的取舍,而不是盲目地把MCU停到最深一级却发现唤不醒或丢数据。