第2章 电源管理单元(PMU)深度解析

各位做嵌入式开发的同行,大家好。今天我们来聊聊CH32系列里一个容易被忽视、但实际非常关键的部分——电源管理单元,也就是PMU。

说实话,我刚开始接触CH32的时候,也以为PMU就是个简单的开关控制。直到有一次做电池供电的项目,发现设备待机电流怎么都降不下来,折腾了两天才发现是PMU的电压调节器配置不对。从那以后,我每次做低功耗设计,都会先把PMU的寄存器从头到尾捋一遍。

2.1 PMU的核心功能与寄存器概览

PMU说白了就是芯片的“供电调度中心”。它负责三件事:

  • 电压调节:给内核和IO提供稳定的工作电压
  • 电源模式切换:在运行、睡眠、待机、掉电等模式间切换
  • 唤醒管理:控制哪些外设能唤醒芯片

CH32V203系列的PMU寄存器并不多,但每个都很关键。我整理了一张表,方便大家对照查阅:

寄存器名称 偏移地址 主要功能
PMU_CTRL0 0x00 电压调节器控制、低电压检测使能
PMU_CTRL1 0x04 内核电压选择、IO电压匹配
PMU_CSR 0x08 状态标志、唤醒标志、复位标志
PMU_WAKEUP 0x0C 唤醒源配置、唤醒引脚选择

嗯,这里要注意:PMU_CTRL0 和 PMU_CTRL1 是配置的核心,大部分低功耗调优都跟这两个寄存器有关。

2.2 电压调节器配置——核心功耗的“水龙头”

电压调节器(Voltage Regulator,简称VR)是PMU里最耗电的模块之一。它负责把外部输入的电压(通常是3.3V或5V)转换成内核需要的低压(1.2V~1.8V)。

我个人习惯把VR比作一个“水龙头”:开得越大,水流越猛,但浪费的水也越多。在CH32里,VR有几种工作模式:

  • 正常模式:全速运行,响应快,功耗高
  • 低功耗模式:降低输出能力,适合睡眠状态
  • 关闭模式:彻底断电,仅保留备份域供电

我曾经在一个温湿度采集项目里,把VR一直设在正常模式,结果待机电流高达200μA。后来改成低功耗模式,直接降到了8μA。你想想看,差了25倍!

关键配置代码(基于CH32V203):

// 配置电压调节器为低功耗模式
PMU->CTRL0 &= ~PMU_CTRL0_VR_MODE_Mask;  // 清除配置位
PMU->CTRL0 |= PMU_CTRL0_VR_MODE_LowPower; // 设置为低功耗模式

// 等待电压稳定
while((PMU->CSR & PMU_CSR_VR_RDY) == 0);  // 轮询就绪标志

这里有个坑:切换VR模式后,一定要等 VR_RDY 标志位置位,否则内核电压可能不稳定,导致程序跑飞。我刚开始就吃过这个亏,代码里没加等待,结果芯片时不时死机。

2.3 内核电压与IO电压的协同——别让它们“打架”

CH32系列的内核电压(VDD_CORE)和IO电压(VDD_IO)是分开供电的。内核电压通常较低(1.2V~1.8V),而IO电压取决于外部供电(1.8V~3.6V)。

为什么要分开?说白了就是为了灵活性。内核跑得再快,IO口也得配合外部设备的速度。如果两者电压不匹配,轻则信号失真,重则烧毁引脚。

我遇到过最典型的问题:一个客户把IO电压设为3.3V,内核电压却配成了1.2V,结果GPIO输出高电平时只有1.2V,外部设备死活不认。后来改成1.8V内核电压,问题才解决。

配置内核电压的寄存器在 PMU_CTRL1 里:

位域 名称 描述
[3:0] CORE_VSEL 内核电压选择:0000=1.2V, 0011=1.5V, 0111=1.8V
[7:4] IO_VSEL IO电压匹配:0000=3.3V, 0001=2.5V, 0010=1.8V

警告: 内核电压不能超过IO电压!如果VDD_CORE > VDD_IO,IO口可能会反向漏电,导致芯片发热甚至损坏。我建议内核电压至少比IO电压低0.5V以上。

2.4 PMU状态机与电源模式切换流程

PMU内部有一个状态机,控制着芯片在不同电源模式间切换。我画了一张图,把核心流程展示出来:

PMU电源模式切换状态机 运行模式 睡眠模式 待机模式 掉电模式 切换说明 • 运行→睡眠:关闭CPU时钟,外设可选保持 • 运行→待机:关闭VR,仅备份域供电 • 运行→掉电:完全断电,仅RTC和唤醒引脚工作 • 虚线箭头表示唤醒/复位后自动回到运行模式

从图里可以看到,从运行模式切换到低功耗模式,只需要一条指令。但唤醒回来,却要经过一系列状态恢复。我建议在切换前,先把不需要的外设关掉,这样能省不少电。

2.5 实战中的避坑指南

做PMU配置时,有几个坑我反复踩过,今天一并分享给大家:

  • VR模式切换后未等待就绪:前面说过,一定要轮询VR_RDY标志。我曾经因为没加等待,导致芯片在低功耗模式下电压不稳,数据采集全乱套。
  • 内核电压与IO电压不匹配:如果IO电压是3.3V,内核电压至少设到1.5V以上,否则IO口驱动能力不足。
  • 唤醒源配置冲突:多个唤醒源同时使能时,要确保它们不会互相干扰。我遇到过GPIO唤醒和定时器唤醒同时使能,结果芯片频繁误唤醒,功耗反而更高。
  • 备份域供电被忽略:掉电模式下,备份域(RTC、备份寄存器)仍然需要供电。如果外部电池没接,掉电后RTC时间会丢失。

小技巧: 调试PMU时,可以用一个GPIO来指示当前电源模式。比如进入睡眠前拉低,唤醒后拉高。用示波器一看,就知道芯片有没有真正进入低功耗状态。这个方法我用了好多年,屡试不爽。

2.6 总结一下

PMU是低功耗设计的起点。电压调节器的配置、内核电压与IO电压的协同,直接决定了芯片的功耗表现。我个人觉得,与其在代码里到处优化,不如先把PMU吃透——基础打好了,后面的事就顺了。