多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

PCA9422+STM32F423RH低功耗电源管理方案详解

PCA9422+STM32F423RH低功耗电源管理方案详解 做电池产品的人都有一个共识系统功耗的大头往往不是主控算力而是电源转换链路里那一堆看不见的静态损耗。尤其是可穿戴、TWS充电仓这类空间狭小、电池又小的项目电源管理做得好不好直接决定了产品能不能在100mAh的电池里撑过一周。我最近在一个低功耗便携设备项目里用 PCA9422 搭配 STM32F423RH 搭配完成了一整套电源管理方案从硬件拓扑到I2C控制再到低功耗状态切换踩了不少坑也积累了一些比较通用的经验。这篇文章就把这套方案的完整设计和实操过程拆给大家看适合正在做电池产品、想用PMIC替代离散电源方案的开发者参考。1. 方案背景与系统架构1.1 先想明白为什么需要一颗PMIC很多开发者习惯用几颗DC-DC加两颗LDO拼出一套电源项目初期确实灵活但到了量产阶段问题就来了。离散方案至少需要5到8颗电源芯片每颗都要配输入输出电容、反馈电阻、电感PCB面积轻松吃掉三四平方厘米而且空载损耗参差不齐普遍在几十微安到上百微安。对于整机待机电流要求小于10μA的产品这种方案很难收敛。PCA9422这类PMIC的价值在于把充电管理、多路降压转换、电源路径切换、系统状态监测全部集成到一颗小封装芯片里。它的静态电流可以做到微安级三路DC-DC都能在轻载时自动进入省电模式并且每路输出电压都可以通过I2C动态调整。这等于把“电源系统”从一堆散件变成一个可控的外设主控可以随时了解电源状态也可以随时调整输出电压。1.2 主控选型STM32F423RH能干什么这套方案里STM32F423RH主要负责三件事一是榨干PMIC的配置能力通过I2C随时改电压、读状态二是根据业务场景切换系统运行模式把外设电源域整体关掉三是用内置ADC做电池电压和温度采样配合PMIC自身的中断实现保护逻辑。选择STM32F423RH而不是更低功耗的L系列有我的具体考虑。这个项目除了电源管理还有音频采集和按键检测需要Cortex-M4F的浮点运算能力。F423RH主频100MHz带512KB Flash和192KB SRAM算力余量足够。它还有一个AES-256硬件加速引擎后续做固件加密升级或者通信数据保护时不用额外挂一颗安全芯片。封装上选LQFP64手工样板焊接无压力量产成本也比较友好。1.3 整体电源拓扑设计这套系统的电源链路可以分成三条主路电池端直接进PCA9422内部负责充电和电源路径管理PCA9422的BUCK1输出1.8V给MCU的VDD内核和数字IO供电BUCK2输出3.3V给传感器、存储、音频Codec等外设供电BUCK3输出2.7V给显示屏和背光驱动供电此外PCA9422内部还有一路LDO输出专门给RTC和唤醒逻辑供电保证休眠时MCU的备份域不断电。整机工作状态时由电池或适配器经PMIC供电掉电后MCU进入Stop模式PCA9422把BUCK2和BUCK3关掉只保留BUCK1的1.8V和内部LDO整机休眠电流实测可以降到20μA以内。这套拓扑最让我满意的一点是主控可以完全掌控电源域而不是让各芯片自己在后台空转。2. 硬件设计拆解把每一路电源都抠明白2.1 PCA9422最小电路的关键节点PCA9422的外围电路看着简单但有几个位置设计错了会非常被动。首先是输入端的去耦电容电池输入VBUS到GND之间我并了1颗10μF陶瓷电容和1颗0.1μF高频电容这是给充电环路和DC-DC输入同时提供低阻抗通路。如果这里只放10μF大电流充电时输入电压纹波会明显变大严重时会影响电量计采样精度。其次是PMIC的I2C地址脚PCA9422一般提供两个地址配置脚可以组合出多个地址。我通过一个10kΩ电阻把地址脚接地设置为主机访问用的基础地址。这里要特别提醒地址脚的电平必须在PMIC上电复位前稳定所以不要用IO口直连去动态切换地址否则PMIC可能在错误地址上等待通信导致程序死活扫描不到设备。还有一路关键输入是PMIC的按钮检测引脚。这个引脚接的是机械按键按下产生低电平PMIC内部会做去抖并产生唤醒事件。我额外给它串了一个1kΩ电阻做ESD保护板端并联了100nF电容滤波。实测下来这个去抖效果不错快速双击也不会误触发。2.2 电感选型别只盯着电感量PCA9422的三路DC-DC都需要外挂电感选型时大家最容易只看电感量忽略饱和电流和直流电阻。以BUCK2的3.3V/600mA输出为例我选用的是2.2μH、饱和电流2A、DCR在80mΩ以内的功率电感。计算公式并不复杂纹波电流ΔI大致可以按 ΔI (V_IN - V_OUT) * D / (L * f_sw) 估算PCA9422的开关频率在1.5MHz左右算出来2.2μH对应的纹波电流约180mA在输出电流的三分之一以内是合理的。如果选4.7μH纹波更小但DCR通常更大轻载效率反而下降而且电感体积也更大。这里有个经验PMIC的数据手册通常给出建议电感范围但那是基于典型应用。如果你的负载是动态变化的比如蓝牙射频瞬时拉流一定要选饱和电流至少要大于最大负载1.5倍的电感。一旦电感进入饱和电感量骤降纹波会突然变大PMIC的反馈环路可能振荡表现为输出电压在负载跳变时出现几毫秒的跌落。2.3 输出电容与负载瞬态响应输出电容直接影响DC-DC的负载瞬态响应。我在每路输出都放了1颗22μF陶瓷电容同时并联1颗0.1μF高频去耦电容。这里的22μF选择耐压16V或10V都可以但要注意DC偏置特性小封装的22μF在3.3V偏压下实际容值可能掉到15μF左右所以宁可选大封装或者留出余量。做动态负载测试时我发现一个有意思的现象BUCK3给显示屏供电屏幕刷新瞬间电流从1mA跳到80mA输出跌了大约120mV。这个幅度在显示屏供电规格里是允许的但如果你给射频芯片供电可能就不行了。所以给射频等敏感负载供电时建议增加一阶RC滤波或者改用低纹波的LDO做二次降压PMIC的DC-DC输出直接给射频供电容易把开关纹波耦合到天线端。2.4 STM32F423RH的供电与去耦细节STM32F423RH有多个供电引脚VDD、VDDA、VREF等我统一接入BUCK1的1.8V但每个电源引脚都要就近放0.1μF电容。这里要格外注意VDDA的滤波因为内置ADC的参考电压直接影响到电池电压采样精度我在VDDA引脚单独加了一颗1μF电容通过一个小磁珠与主1.8V隔开实测ADC的噪声明显降低。F423RH的VCAP引脚需要外接一个2.2μF的电容这颗电容不能省也不能加大到10μF否则内部稳压器可能启动失败。我见过有人为了“保险起见”在这里并联多颗电容结果MCU反复上电失败。数据手册写什么就是什么这个位置按手册走最保险。I2C接口我用的是PB8/PB9外接4.7kΩ上拉电阻到1.8V。PCA9422的I2C电平要与MCU的IO电平匹配好在PMIC的VIO引脚可以直接接系统1.8V两边电平一致不需要额外电平转换。3. 软件控制流程把PMIC变成听话的外设3.1 I2C初始化与设备扫描写驱动第一步是确认I2C通信正常。STM32F423RH的硬件I2C外设初始化比较常规400kbps速率配置好之后用轮询方式发一条读ID的命令。PCA9422一般会提供设备ID寄存器读到预定值就能确认地址和通信都正常。这里分享一个调试心得第一次上电时不要直接初始化PMIC先把I2C的GPIO配置成开漏输出接上拉电阻后用示波器看SCL/SDA波形。很多情况下程序看起来没问题但波形上SDA一直为低是因为某个外设把总线拉死了。逐个断开外设排查比反复改软件效率高得多。PMIC的I2C地址我配置成0x08的7位地址总线访问时左移一位成为0x10写地址。如果你的系统里I2C总线上还有其他设备务必确认地址不冲突。PCA9422多个地址脚支持动态切换但前面已经说过必须上电前锁定所以这里强调软件初始化顺序先配置GPIO再初始化I2C外设最后才给PMIC发第一笔指令。3.2 输出电压配置流程PCA9422的每路DC-DC输出电压都通过寄存器配置通常包含一个电压选择位域支持从0.6V到3.3V左右的调节范围。我的配置目标如下BUCK11.8V给MCU供电BUCK23.3V给外设供电BUCK32.7V给显示屏供电。配置时我按寄存器位域写入对应数值。这里要注意PMIC的寄存器可能有写保护需要在配置前先解锁否则写入不生效。我当时忽略了这一点代码里连续写了五个寄存器结果读回来只有前两个生效后来查数据手册才发现有写保护位。所以建议大家写完关键配置后立刻回读校验一次别省这一步。另一个细节是每路DCDC都有“强制PWM模式”和“自动省电模式”的选择。处于自动省电模式时轻载下芯片会自动跳过一些开关周期来提高效率但输出电压纹波会变大。我给MCU内核供电的BUCK1使用自动模式因为MCU数字电路对纹波不敏感给ADC参考供电的BUCK2则强制为PWM模式保证纹波足够小。这个取舍在低功耗项目中非常关键。3.3 充电配置与状态读取PCA9422内置线性充电器充电电流通过外部电阻设定同时支持I2C读取充电状态。我在项目里把充电电流配置为最大500mA因为电池容量只有450mAh1C充电足够同时避免大电流在狭小机身里产生过多热量。充电状态机一般分为预充、恒流、恒压、完成四个阶段。软件侧我采用一个1秒周期的定时器去读PMIC的状态寄存器判断当前是否正在充电、是否充满、是否出现充电超时或温度异常。这个轮询周期不宜太短否则I2C频繁访问会额外增加功耗也不宜太长因为需要及时响应充满事件来点亮LED。实际调试中遇到过一个问题电池电压在3.2V附近时充电电流只有不到50mA状态寄存器显示预充。一开始以为是PMIC坏了后来发现是这个电池长期存放自放电过度内置的保护板处于激活模式必须用小电流预充一段时间才能唤醒。PMIC的预充逻辑正是为这种情况设计的所以不要强行加大电流去“激活”电池按照数据手册的预充流程等待即可。3.4 STM32的中断唤醒与PMIC事件联动完整的电源管理不能只是主控主动轮询还必须有事件驱动的机制。PCA9422通常有一个中断引脚接到MCU的EXTI外部中断充电完成、电源插入、按钮按下、系统过温等事件都会触发中断唤醒MCU。我的做法是把PMIC的中断脚连接到STM32F423RH的PA0配置为上升沿和下降沿都触发。中断服务函数里只做一件事读PMIC的中断状态寄存器把对应事件标志位置位后立即返回。主循环里再根据标志位去处理充电状态变化或按键事件这样既能保证实时性又不会在中断里做耗时的I2C通信。这里有个容易忽略的坑PMIC的中断状态寄存器读取后需要写“清除”位否则中断会一直挂着MCU会被反复唤醒。我在调试时遇到整机休眠电流突然飙到1mA查了大半天才发现是中断标志没清。把清除逻辑补上后休眠电流立刻恢复正常。记住这个动作读完中断状态后一定要清标志。4. 系统级电源模式切换与调度4.1 运行态、待机态、关机态三种模式的设计电源管理不只是一堆寄存器配置核心是把系统的运行状态和电源状态联动起来。我设计了三个明确的系统模式。运行态Active下BUCK1、BUCK2、BUCK3全部开启MCU以80MHz运行所有业务功能正常工作整机电流大约50mA到100mA视外设负载而定。待机态Sleep下业务暂停MCU进入Stop模式BUCK2和BUCK3由PMIC配置为关闭BUCK1保持1.8V输出给MCU和RTC。这个状态下整机电流降到20μA左右。唤醒源保留两个PMIC的按钮中断和RTC定时中断。按钮按下时PMIC产生事件给MCU一个外部中断MCU从Stop模式恢复后重新打开BUCK2和BUCK3进入运行态。关机态Off下我通过PMIC的GPIO或者寄存器关闭BUCK1整机仅保留PMIC自身静态电流和RTC备份域供电电流可以降到5μA以下。关机态的恢复只能依靠RTC闹钟或者充电器插入事件充电器插入时PMIC会自动上电系统。4.2 动态调压让屏幕亮度与电压联动PCA9422支持I2C动态调压这个能力在显示屏供电上非常实用。屏幕亮度分成五档每档对应一个背光占空比同时对应一个BUCK3输出电压档位。低亮度档时把BUCK3从2.7V降到2.5V背光LED的正向压降需求低降低电压能省下几十毫瓦高亮度档时再把电压拉回2.7V。实测的结果是低亮度模式下整机功耗降低了大约8%效果非常可观。这里要提醒动态调压时PMIC的输出电压不能跳变太快否则负载可能受不了。我在切换到高亮度时分三步把BUCK3电压逐级提升每一级间隔10ms整个过程屏幕没有任何闪烁。4.3 电池电压监测与低电量保护STM32F423RH内置12位ADC我用一路通道通过电阻分压采集电池电压。分压电阻选了100kΩ和200kΩ分压比是1/3电池满电4.2V时ADC输入约1.4V在ADC参考电压范围内。采样策略上用了“平均滤波滞后比较”的组合。对ADC值连续采样16次去掉最大最小各两个再取平均这样能滤掉DC-DC纹波带来的毛刺。低电量阈值设3.5V但恢复阈值设3.6V形成0.1V的迟滞。没有迟滞的话当系统在高负载状态下电压波动会导致频繁触发低电量告警甚至进入关机、又自动唤醒的循环。低电量处理逻辑分两级电压低于3.5V时软件关闭非必要外设只保留核心通信低于3.2V时通过I2C关闭BUCK2并在BUCK3关闭前把关键数据存入Flash再进入关机态。实测关机后电池电压慢慢回弹到3.4V但由于电源路径和按键唤醒逻辑已经被PMIC接管系统不会因为回弹电压自动重启。这点很重要不然会出现“关机后又自己开机”的灵异现象。5. 调试实录与常见问题排查5.1 输出耦合导致的复位异常第一版样机做回来测试时我遇到一个非常奇怪的问题屏幕上电瞬间MCU会偶尔复位。排查了一圈最后用示波器才找到真凶——BUCK3给显示屏供电而显示屏的排线从MCU的复位脚旁边走过电源切换瞬间的高频辐射耦合到了复位引脚让MCU误以为外部复位信号到来。解决方式是双管齐下一是把显示屏排线在PCB上远离复位引脚走线二是在复位引脚上并联了一个100nF电容做滤波。改版后问题没有再出现过。这种问题在原理图里看不出来只能靠Layout阶段的前瞻性来避免。5.2 PMIC寄存器写入后回读不一致调试中另一个高频问题是用I2C写PMIC配置后回读数值和写入值不一致。排查步骤可以按顺序来先确认I2C时钟频率PCA9422标称支持400kbps但最初我把速率配成1MHz宽裕度不足时出现偶发写入错误。把频率降到400kbps后问题频率明显降低。然后是写保护寄存器。部分PMIC把关键配置放在受保护寄存器区直接写会被忽略。需要先写一个解锁寄存器通常写入特定魔术字再操作目标寄存器。我在代码里加了一个“带解锁的写配置”函数每次写关键寄存器前自动判断是否需要解锁避免在业务代码里到处塞解锁逻辑。5.3 待机电流比预期高几十微安做完软硬件联调后测整机待机电流发现一直徘徊在70μA左右比预期高了50μA。用排除法一个一个外设断开排查最后定位到是一颗传感器的I2C地址残留导致它在总线空闲时反复拉低SDA。表面上看传感器已经被断电但它的IO口没有配置成高阻而是保持默认上拉状态电流从PMIC的1.8V通过上拉电阻流进了传感器内部。解决方法是给所有外设的电源域增加一个统一的EN开关由PMIC的GPIO控制关机时同时把外设的IO全部配置为模拟输入模式切断漏电路径。这个经验后来被我用到了所有低功耗项目里。5.4 充电指示灯闪烁异常的排查用户反馈充电时LED指示灯闪烁节奏不对一查是PMIC的充电状态寄存器读取太频繁。我在1秒轮询周期里读到“正在充电”标志后立即让LED点亮但接着又读到“预充完成”状态LED熄灭造成闪烁。后来仔细读了PMIC的状态定义原来线性充电在预充和恒流之间切换时会经历一个短暂的“复充”阶段需要软件进行状态过滤。我把充电状态机加了一个防抖判断连续三次读到同一状态才认为状态稳定。这样LED就稳定了不再乱闪。6. 这套方案还能怎么延伸整套方案跑下来我个人最深的感觉是PCA9422与STM32F423RH的组合真正把电源从“硬件工程师画完就固化”的东西变成了一套可以持续调校的软件系统。几个后续可以扩展的方向也在这里分享一下。一是利用STM32F423RH的AES引擎做固件签名验证。PMIC和MCU之间是I2C通信如果能再配合加密协议整个电源链路会更安全防止别人通过I2C干扰电源状态。二是做更细的电池SOC估算。现在只用电压查表法估算电量误差不小。如果后续加入电流采样通道可以做库仑计算法配合ADC同步采样估算精度能提升到5%以内。PCA9422本身有一定监测能力关键看主控侧算法怎么做。三是利用PMIC的GPIO扩展系统功能。比如用一路GPIO控制振动马达或者用一路GPIO做NFC场检测。这种集成思路可以减少主控外设占用尤其适合小封装项目。最后说个小技巧量产前最好把PMIC的寄存器配置表固化成头文件并且给每个寄存器写注释。原因是PMIC的寄存器太多芯片版本升级后可能有细微差异没有配置表的话后续换料或者做兼容版本会非常痛苦。我就是靠这份配置表在第二版硬件上几乎零调试就把电源部分跑通了。这套方案的实际效果整机运行电流在正常业务场景下大约60mA待机电流20μA关机电流低于5μA充电全程温升控制在可接受范围内。对于做便携设备的团队来说这套“硬件集成软件可控”的电源管理思路应该能帮大家少走不少弯路。
返回列表