1. 低功耗概览:STM32L4 系列低功耗特性总览
做嵌入式这么多年,我见过不少工程师一上来就怼着代码调功耗,结果折腾半天发现选错了模式。说白了,低功耗设计的第一步不是写代码,而是搞清楚你的芯片到底能睡多深。
STM32L4 系列是意法半导体专门为低功耗场景打造的。它基于 Cortex-M4 内核,带 FPU 和 DSP 指令,性能不差,但真正厉害的是它的功耗模式设计。我刚开始用 L4 的时候,也被那一堆模式搞得有点晕——Run、Sleep、LP Run、LP Sleep、Stop、Standby…… 每个模式功耗差好几个数量级,唤醒时间也完全不同。
这一章我们先搭个框架,把 L4 的低功耗家底摸清楚。
1.1 功耗模式对比
先看这张图,我把 L4 的功耗模式按功耗从高到低排了个序。你一眼就能看出,从 Run 到 Standby,电流差了 6 个数量级。
这张图我建议你存下来。每次选模式的时候,对着它看一眼,基本不会选错。
核心原则:功耗越低,唤醒越慢,保留的外设越少。没有免费的午餐。
1.2 各模式详解
下面我把每个模式拆开讲。你注意看表格里的「保留内容」和「唤醒源」这两列,这是选型的关键。
| 模式 | 典型电流 | CPU 状态 | RAM 保持 | 主要唤醒源 | 典型场景 |
|---|---|---|---|---|---|
| Run | ~100 µA/MHz | 运行 | 全部 | — | 正常处理 |
| Sleep | ~50 µA/MHz | 暂停 | 全部 | 任何中断/事件 | 等待外设完成 |
| LP Run | ~8 µA/MHz | 运行 (低频) | 全部 | — | 低负载持续处理 |
| LP Sleep | ~3 µA/MHz | 暂停 (低频) | 全部 | 任何中断/事件 | 低频等待 |
| Stop 0 | ~30 µA | 关 | 全部 | RTC / 外部中断 / 部分外设 | 秒级休眠 |
| Stop 1 | ~3 µA | 关 | 全部 | RTC / 外部中断 / 部分外设 | 分钟级休眠 |
| Stop 2 | ~1 µA | 关 | 全部 | RTC / 外部中断 / 部分外设 | 分钟级休眠 |
| Standby | ~100 nA | 关 | 丢失 | RTC / WAKEUP 引脚 / 复位 | 长时间休眠 |
这里有个细节我提醒你一下:Stop 0/1/2 的区别不只是电流。Stop 2 关闭了更多外设时钟,但 RAM 内容全部保留。我有个项目做温湿度记录仪,采样间隔 5 分钟,用的就是 Stop 2 + RTC 唤醒,整机平均电流做到了 2.3 µA 左右。
我的习惯:如果休眠时间小于 1 秒,用 Stop 0;1 秒到 1 分钟,用 Stop 1 或 Stop 2;超过 1 分钟,直接上 Standby。当然,前提是你的数据能接受 RAM 丢失。
1.3 功耗测量方法
说到测量,我踩过不少坑。最早我用万用表直接串在电源上测,结果发现读数跳来跳去,根本不准。后来才明白,低功耗电流是脉冲式的——芯片醒来那几十微秒电流可能冲到几毫安,然后迅速掉回微安级。万用表的积分时间太长,测出来的是平均值,但你看不到瞬态行为。
我个人习惯用这几种方法:
- 精密万用表(6.5 位以上):测稳态电流,比如 Standby 模式。Fluke 8846A 或 Keysight 34461A 都行。
- 示波器 + 电流探头:看瞬态波形,比如从 Stop 唤醒时的电流尖峰。探头带宽建议 50 MHz 以上。
- 专用功耗分析仪:比如 Joulescope 或 Otii,能同时测电压、电流、功率,还能积分算总能耗。我最近的项目基本都用 Otii,省事。
- 串联采样电阻法:低成本方案,用 10Ω 电阻串在电源上,示波器测电阻两端电压。注意电阻压降会影响芯片供电,别选太大。
我曾经犯过的错:用普通万用表测 Stop 2 模式的电流,读数显示 0.8 µA,我以为很完美。结果用示波器一看,芯片每 100 ms 偷偷醒来一次,电流尖峰 3 mA,持续 200 µs。算下来平均电流其实有 6 µA 左右。所以记住:低功耗测量一定要看波形,不能只看数字。
1.4 快速上手:测量一个最简单的 Standby 电流
说了这么多,我们来动动手。下面这段代码让 STM32L4 进入 Standby 模式,你可以用它验证你的测量环境。
/* 进入 Standby 模式示例 */
#include "stm32l4xx_hal.h"
void Enter_Standby(void)
{
/* 1. 清除唤醒标志 */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
/* 2. 使能电源时钟 */
__HAL_RCC_PWR_CLK_ENABLE();
/* 3. 设置 Standby 模式 */
HAL_PWR_EnableSleepOnExit(); /* 可选:退出中断后自动休眠 */
HAL_PWR_EnterSTANDBYMode();
/* 不会执行到这里 */
}
烧录后,用你的万用表串在 VDD 上,应该能看到电流掉到 100 nA 左右。如果读数偏高,检查一下有没有外部上拉电阻或者未使用的 GPIO 在漏电。
一个小技巧:进入 Standby 前,把所有未使用的 GPIO 配置为模拟模式(GPIO_MODE_ANALOG),可以再省几十 nA。别问我怎么知道的——有一次我测出来 500 nA,查了半天发现是 PA3 悬空,在数字输入模式下来回翻转。