3、电源管理单元(PMU)配置:PMU工作模式,唤醒事件配置,电源域划分
好,咱们接着聊PMU。这东西说白了就是芯片的“总电闸”加“值班室”。你想想看,一个嵌入式设备要低功耗,不能一直开着所有电路,但又不能完全死掉——得留个“耳朵”听命令。PMU就是干这个的。
我个人习惯,拿到一款新芯片,第一件事就是翻它的PMU章节。为什么?因为功耗优化的天花板,其实在PMU这里就定死了。你后面软件再怎么调,也跳不出硬件划分的框框。
3.1 PMU的工作模式
PMU不是只有“开”和“关”两种状态。实际上,它有好几个档位。我把它分成三类:
- 运行模式(Active):全速跑,所有电源域都供电。这时候功耗最高,但性能也最强。
- 睡眠模式(Sleep):CPU停了,但外设和内存还在供电。适合那种“随时要响应”的场景。
- 深度睡眠模式(Deep Sleep):大部分电路断电,只留PMU和几个关键外设(比如RTC、唤醒IO)。这是我最常用的模式。
嗯,这里要注意:不同厂家的叫法不一样。ST叫Stop和Standby,NXP叫VLPS和LLS,TI叫Deep Sleep和Hibernate。但本质都一样——用功耗换响应时间。
核心原则:睡眠越深,唤醒越慢。你不可能既要纳秒级唤醒,又要微安级功耗。这是物理定律,绕不过去。
3.2 唤醒事件配置
唤醒事件,就是那个“耳朵”。我遇到过不少工程师,功耗降下来了,但设备唤不醒了——这就尴尬了。
常见的唤醒源有这些:
- GPIO中断:最常用。按键、传感器触发都可以。
- RTC闹钟:定时唤醒。比如每秒钟起来发个心跳包。
- 比较器输出:模拟信号触发。比如电池电压低于阈值就唤醒。
- 通信接口:UART的RX引脚、CAN总线活动等。
配置的时候,我建议你画一张表:
| 唤醒源 | 适用场景 | 典型功耗 | 唤醒时间 |
|---|---|---|---|
| GPIO下降沿 | 按键唤醒 | ~1μA | ~10μs |
| RTC闹钟 | 定时任务 | ~0.5μA | ~100μs |
| UART RX | 串口唤醒 | ~2μA | ~50μs |
我曾经在一个项目里,用了GPIO唤醒,结果发现引脚配置错了——上拉电阻没开,导致电平不确定,芯片一直在唤醒和睡眠之间来回跳。功耗反而比正常跑还高。所以,唤醒配置一定要做去抖处理,硬件上串个RC,软件上做个延时判断。
我的小技巧:调试唤醒时,先别急着测功耗。用示波器抓唤醒引脚的波形,确认信号干净了,再去看电流。省得走弯路。
3.3 电源域划分
电源域划分,是PMU配置里最体现功力的地方。说白了,就是把芯片内部电路分成几个“独立电表”,哪个不用就拉闸。
典型的划分方式:
- VDD_CORE:CPU核心、Cache、内部总线。功耗大户,睡眠时必须关。
- VDD_PERI:外设模块。UART、SPI、I2C这些。按需供电。
- VDD_BACKUP:备份域。RTC、备份寄存器、唤醒逻辑。永远不断电。
- VDD_IO:IO口供电。有些芯片可以独立控制。
我见过一个失败的案例:某团队把WiFi模块和MCU放在同一个电源域里。结果MCU想睡,WiFi还在发包,整个系统功耗降不下来。后来把WiFi单独拉一个域,用PMU的负载开关控制,功耗直接降了80%。
注意:电源域切换时,要考虑“上电顺序”。有些外设对供电时序很敏感,比如DDR内存,必须先给VDD再给VTT。乱来会烧芯片。我吃过这个亏,那次返修了200多块板子...
最后,给个代码片段。这是我在STM32L4上配置PMU进入Stop模式的例子:
// 进入Stop模式,保留SRAM,RTC唤醒
void enter_stop_mode(void)
{
// 配置PMU寄存器
PWR->CR1 |= PWR_CR1_LPMS; // 选择低功耗模式
PWR->CR1 |= PWR_CR1_FPDS; // 闪存掉电
// 配置唤醒源:RTC闹钟
EXTI->IMR1 |= EXTI_IMR1_IM17; // 使能RTC中断
EXTI->RTSR1 |= EXTI_RTSR1_RT17; // 上升沿触发
// 进入睡眠
__WFI(); // Wait For Interrupt
}
嗯,代码很简单,但背后要考虑的东西不少。比如:进入Stop前,要不要关掉ADC?DMA传输完了吗?这些细节,决定了你的系统是“优雅入睡”还是“强行断电”。
总结一下:PMU配置,就是选模式、配唤醒、划电源域。这三步走对了,低功耗就成功了一半。剩下的,就是软件层面的配合了——咱们下一章聊。