1. 从一块板子的供电说起:为什么电源管理值得单独拎出来做
做过嵌入式项目的人大概都有过这样的经历:板子焊好了,程序烧进去了,跑起来却时不时复位,或者某个外设莫名其妙不工作。排查半天,最后发现是电源轨的时序不对,或者某路供电的纹波太大,把模拟部分的基准电压给带偏了。这类问题在实验室里用USB供电时往往看不出来,一旦切到电池供电或者工业现场的长线供电,问题就全暴露出来了。
这次要聊的,是一个围绕PCA9422这颗电源管理芯片搭配STM32F405RG主控做的完整电源管理方案。STM32F405RG是ST家F4系列里很经典的一颗料,Cortex-M4内核带FPU,168MHz主频,1MB Flash加192KB SRAM,做运动控制、数据采集、便携式仪器都很合适。但它的电源需求其实不简单:核心电压要1.2V左右,IO要3.3V,如果板子上还挂了ADC基准、传感器模拟供电、显示屏背光,那电源轨的数量和上电顺序就够让人头疼了。
PCA9422是NXP推出的一颗高度集成的电源管理IC,专门面向低功耗MCU和便携设备。它内部集成了多路降压转换器、LDO、电池充电管理、电量计接口,还支持通过I2C动态调节输出电压和上电时序。换句话说,它把过去需要一堆分立DCDC加LDO才能搭出来的电源树,压缩到了一颗芯片里,而且所有轨的电压、时序、使能都可以用软件配置。
这个组合的价值在于:它让STM32F405RG这种性能不弱但功耗也不算低的MCU,能够在一个真正便携、电池供电的场景里稳定工作,同时把电源部分的PCB面积和BOM成本压下来。适合谁看?如果你正在做便携式数据采集设备、手持仪器、电池供电的工业传感器节点,或者你只是单纯想搞清楚一颗PMIC到底该怎么和MCU配合工作,那这篇内容应该能给你一些可以直接抄作业的东西。
我下面会从芯片选型的逻辑讲起,然后拆解PCA9422的内部结构和寄存器配置思路,接着讲STM32F405RG这边的电源域怎么划分,再给出完整的I2C配置流程和上电时序设计,最后聊几个我在实际调试中踩过的坑。整个过程会尽量把“为什么这么做”讲清楚,而不是只丢一堆寄存器值。
2. PCA9422到底解决了什么问题:芯片选型背后的取舍
2.1 为什么不用分立DCDC加LDO的方案
很多人第一反应是:电源管理嘛,用几颗DCDC芯片加LDO不就行了,为什么要上一颗PMIC?这个问题我在项目初期也纠结过。分立方案的好处是灵活,每路电源可以单独选型,成本看起来也低。但实际算下来,事情没那么简单。
STM32F405RG的典型工作电流在168MHz全速运行时大概在50mA到80mA之间,加上外设可能到150mA。如果板子上有SD卡、显示屏、无线模块,峰值电流可能冲到500mA以上。用分立方案,你需要至少一路3.3V的主DCDC,一路1.2V的内核DCDC(或者用LDO从3.3V降下来,但效率会很难看),再加上电池充电电路、电量检测电路。光是这些芯片的封装、外围电感电容,就占掉不少PCB面积。
更麻烦的是上电时序。STM32F405RG要求内核电压和IO电压的上升顺序不能乱,虽然它内部有POR电路,但如果外部电源轨的建立时间差异太大,可能导致启动时IO先于内核上电,出现短暂的漏电流路径。分立方案要控制时序,得加专门的时序控制芯片或者用MCU的GPIO去控制各路的使能,软件复杂度上去了,可靠性反而下降。
PCA9422把这些东西都集成进去了。它内部有:
- 两路高效降压转换器(Buck),可以输出0.4V到3.3V可调,最大电流分别能到1A和500mA
- 三路LDO,输出范围0.5V到3.3V,给低噪声模拟部分供电
- 一路线性电池充电器,支持最大1A充电电流
- 电量计接口和系统监控ADC
- I2C接口,所有输出电压、上电时序、使能都可以软件配置
这意味着整个电源树可以用一颗芯片搞定,PCB面积大幅缩小,而且时序控制变成了寄存器配置,不需要额外的硬件。
2.2 PCA9422的关键参数与STM32F405RG的匹配度
选PMIC不是看它功能多就行,得看它的输出能力和MCU的需求能不能对上。我整理了一个对照表,把STM32F405RG的主要电源需求和PCA9422的能力放在一起看:
| 电源域 | STM32F405RG需求 | PCA9422对应资源 | 配置要点 |
|---|---|---|---|
| 内核电压VDD | 1.2V典型,最大120mA | Buck1输出,0.4-3.3V可调,1A能力 | 设为1.2V,上电时序最先建立 |
| IO电压VDDIO | 3.3V典型,最大200mA | Buck2输出,0.4-3.3V可调,500mA能力 | 设为3.3V,在内核之后建立 |
| 模拟供电VDDA | 3.3V,噪声敏感 | LDO1输出,低噪声 | 从Buck2后级或独立LDO供电 |
| 备份域VBAT | 1.8-3.3V,微安级 | LDO2或直接电池 | 低功耗模式保持 |
| 传感器/外设 | 视具体外设而定 | LDO3或Buck2扩展 | 注意总电流不超限 |
从表里能看出来,PCA9422的资源对STM32F405RG来说是够用的,而且有余量。Buck1的1A能力给内核供电绰绰有余,Buck2的500mA给IO和外设也基本够。真正需要注意的是总功耗预算:如果板子上有无线模块或者显示屏,峰值电流可能超过Buck2的能力,这时候要么把大电流外设挂到Buck1上(如果电压匹配),要么外扩一路DCDC。
还有一个细节是PCA9422的输入电压范围。它支持2.7V到5.5V输入,这意味着它可以直接从单节锂离子电池(3.0V-4.2V)或者USB 5V供电,不需要额外的预稳压。这对便携设备来说很关键,因为电池电压会随着放电从4.2V降到3.0V,PMIC必须能在这个范围内稳定输出。
2.3 什么场景下这个组合最合适
不是所有项目都值得上PMIC。如果你的板子是固定供电、功耗不高、对体积没要求,那用一颗LDO加一颗DCDC就够了,没必要增加PMIC的复杂度和成本。PCA9422加STM32F405RG这个组合,我觉得最适合以下几类场景:
第一类是电池供电的便携式数据采集设备。比如手持式振动分析仪、便携式环境监测站,这类设备需要长时间靠电池工作,对电源效率敏感,同时又要给模拟传感器提供干净的电源。PCA9422的Buck效率在轻载和重载下都能做到85%以上,LDO的PSRR也能满足模拟部分的需求。
第二类是需要多电压域和精确上电时序的工业控制板。有些工业传感器和执行器需要特定的上电顺序,用PMIC的时序配置功能可以精确控制每一路的建立时间和顺序,比用分立方案加延时电路可靠得多。
第三类是对PCB面积有严格限制的设计。PCA9422的QFN封装只有4mm x 4mm,加上少量外围元件,整个电源部分的面积可以控制在15mm x 15mm以内,这对小型化设备来说很有吸引力。
反过来说,如果你的项目是纯数字电路、5V供电、功耗固定,那这个方案就属于杀鸡用牛刀了。选型的第一原则永远是匹配需求,而不是堆料。
3. 硬件设计细节:从原理图到PCB布局的实战要点
3.1 外围元件选型:电感、电容和电阻的计算
PCA9422的Buck转换器需要外接电感和电容,这些元件的选型直接影响电源的效率和稳定性。数据手册里给的是典型值,但实际项目中需要根据你的负载特性做调整。
先说电感。Buck1的输出电流最大1A,开关频率默认是2MHz(可以通过寄存器调整)。电感值的选择要平衡纹波电流和瞬态响应。纹波电流一般取输出电流的20%到40%,按30%算:
ΔIL = 1A × 0.3 = 0.3A
电感值计算公式:
L = (Vout × (1 - Vout/Vin)) / (fsw × ΔIL)
假设Vin=3.7V(锂电池典型电压),Vout=1.2V,fsw=2MHz:
L = (1.2 × (1 - 1.2/3.7)) / (2×10^6 × 0.3) ≈ 1.35μH
所以选1.5μH的标准值比较合适。电感的饱和电流要大于峰值电流,峰值电流是输出电流加上一半的纹波电流:
Ipeak = 1A + 0.15A = 1.15A
所以电感的饱和电流至少要到1.5A,留点余量选2A的。DCR也要尽量小,减少导通损耗。
输出电容的选择主要看纹波电压要求。纹波电压由电容的ESR和容值共同决定:
ΔVout = ΔIL × (ESR + 1/(8 × fsw × Cout))
如果要求纹波小于10mV,ESR取5mΩ,可以反推需要的容值。实际选型时,用两颗22μF的X5R陶瓷电容并联,ESR可以做到很低,容值也够。注意陶瓷电容有直流偏压效应,标称22μF的电容在1.2V偏压下可能只剩15μF左右,所以要多留余量。
输入电容也不能省。Buck转换器的输入电流是脉冲式的,需要在Vin引脚附近放一颗10μF的陶瓷电容加一颗0.1μF的高频去耦电容,尽量靠近芯片引脚。
3.2 PCB布局:哪些走线必须短而粗
电源部分的PCB布局,核心原则就一句话:高di/dt的环路面积要最小。Buck转换器的输入环路和输出环路都是高di/dt路径,布局不好会带来严重的EMI和电压振铃。
具体来说,Buck1的输入电容要尽可能靠近PVIN引脚和PGND引脚,这两个引脚之间的环路面积要最小。电感要靠近SW引脚,输出电容要靠近电感输出端和负载。反馈引脚FB要远离SW节点,走线要短,并且用地线包围屏蔽。
散热焊盘的处理也很关键。PCA9422的QFN封装底部有一个大的散热焊盘,必须焊接到PCB的接地铜皮上,并且打过孔到内层地平面。过孔数量建议不少于9个,均匀分布在焊盘上,这样可以把芯片的热量传导到PCB上散掉。如果负载电流大,芯片会有一定温升,散热焊盘处理不好会导致过热保护甚至损坏。
还有一个容易被忽略的点:模拟地和数字地的分割。PCA9422内部有模拟电路(基准源、ADC),也有数字电路(I2C接口、控制逻辑)。虽然芯片内部已经做了隔离,但PCB上还是建议把模拟地和数字地在芯片下方单点连接,避免数字噪声串到模拟部分。LDO的输出电容要靠近负载,特别是给ADC或者传感器供电的那一路,走线要远离高频开关节点。
3.3 电池充电电路的设计注意事项
PCA9422内置了线性充电器,支持最大1A充电电流。充电电流通过外部电阻设定,公式在数据手册里有。假设要设500mA充电电流,对应的电阻值可以查表或者计算。
充电电路有几个设计要点:
第一,充电电流的设定电阻要选用精度1%的,因为充电电流的精度直接影响电池寿命和充电时间。电阻要靠近ISET引脚,走线尽量短,避免引入噪声。
第二,电池温度检测(NTC)功能如果不用,要把对应的引脚接到正确的电平上,不能悬空。很多项目为了省一个NTC电阻,把温度检测引脚悬空,结果充电器一直报温度故障,充不进电。
第三,充电状态指示引脚可以接LED,但要注意限流电阻的计算。LED的正向压降一般在1.8V到2.2V之间,如果引脚输出是3.3V,限流电阻按10mA算:
R = (3.3 - 2.0) / 0.01 = 130Ω
选150Ω的标准值就行。
第四,如果电池是可拆卸的,要在电池输入端加TVS管做ESD保护,防止人体静电通过电池触点打坏芯片。
4. I2C配置流程:把PCA9422真正跑起来
4.1 I2C地址与通信基础
PCA9422的I2C从机地址是7位的,具体值由芯片型号决定,常见的是0x62或者0x63(7位地址)。在STM32F405RG这边,用硬件I2C外设去访问,注意地址要左移一位,因为HAL库的I2C函数需要的是8位地址格式。
I2C的时钟频率建议用400kHz(快速模式),不要用100kHz,因为PCA9422的寄存器比较多,初始化时要写几十个寄存器,100kHz会拖慢启动时间。但也不能太高,1MHz以上对PCB走线和上拉电阻的要求会变高,容易通信失败。
上拉电阻的选择:如果总线电容在100pF以内,400kHz下用4.7kΩ上拉比较合适。如果总线走线长、挂的设备多,电容可能到200pF以上,这时候要减小上拉电阻到2.2kΩ,保证上升沿时间满足要求。上升沿时间公式:
tr = 0.847 × R × C
400kHz模式下tr要小于300ns,反推R×C要小于354ns。如果C=200pF,R要小于1.77kΩ,所以2.2kΩ可能都不够,得用1.5kΩ。这个计算在实际调试中很有用,通信不稳定的时候先量一下上升沿时间。
4.2 上电时序的寄存器配置逻辑
PCA9422最强大的功能之一就是可配置的上电时序。它内部有一个状态机,可以控制每一路输出的使能和建立顺序。配置思路是这样的:
首先,确定STM32F405RG需要的上电顺序。根据数据手册,VDD(内核)应该先于VDDIO建立,或者至少同时建立。VDDA通常和VDDIO一起或者稍后建立。所以顺序是:Buck1(1.2V内核)→ Buck2(3.3V IO)→ LDO1(3.3V模拟)。
然后,在PCA9422的时序配置寄存器里,给每一路分配一个时隙(slot)。PCA9422支持多个时隙,每个时隙之间的延时可以配置。比如:
- Slot 0:Buck1使能,延时0ms
- Slot 1:Buck2使能,延时2ms
- Slot 2:LDO1使能,延时4ms
这个延时不是随便定的。Buck1从使能到输出稳定需要一定时间,数据手册里叫软启动时间,典型值是1ms左右。所以Slot 1的延时至少要大于Buck1的软启动时间,确保内核电压建立后IO再上电。
配置寄存器的时候要注意,有些寄存器是带锁保护的,写之前要先解锁。解锁序列通常是向某个特定寄存器写一个特定的值,然后再写目标寄存器。这个细节数据手册里写得很清楚,但很容易漏掉,漏掉的话寄存器写不进去,电源就不受控。
4.3 用STM32 HAL库实现配置的代码框架
下面给一个基于STM32 HAL库的配置代码框架。注意这只是核心逻辑,实际项目中要根据具体的PCA9422型号和寄存器地址调整。
#include "stm32f4xx_hal.h" #define PCA9422_I2C_ADDR (0x62 << 1) // 7位地址左移 I2C_HandleTypeDef hi2c1; // 写单个寄存器 HAL_StatusTypeDef PCA9422_WriteReg(uint8_t reg, uint8_t value) { return HAL_I2C_Mem_Write(&hi2c1, PCA9422_I2C_ADDR, reg, I2C_MEMADD_SIZE_8BIT, &value, 1, 100); } // 读单个寄存器 HAL_StatusTypeDef PCA9422_ReadReg(uint8_t reg, uint8_t *value) { return HAL_I2C_Mem_Read(&hi2c1, PCA9422_I2C_ADDR, reg, I2C_MEMADD_SIZE_8BIT, value, 1, 100); } // 解锁寄存器写保护 HAL_StatusTypeDef PCA9422_Unlock(void) { HAL_StatusTypeDef ret; ret = PCA9422_WriteReg(0x0A, 0x5A); // 解锁序列第一步 if (ret != HAL_OK) return ret; ret = PCA9422_WriteReg(0x0B, 0xA5); // 解锁序列第二步 return ret; } // 配置Buck1输出1.2V HAL_StatusTypeDef PCA9422_ConfigBuck1(void) { // 假设电压步进是12.5mV,1.2V对应96 // 具体计算公式参考数据手册 uint8_t volt_code = 96; return PCA9422_WriteReg(0x20, volt_code); } // 配置上电时序 HAL_StatusTypeDef PCA9422_ConfigSequence(void) { HAL_StatusTypeDef ret; ret = PCA9422_Unlock(); if (ret != HAL_OK) return ret; // Slot0: Buck1使能 ret = PCA9422_WriteReg(0x30, 0x01); if (ret != HAL_OK) return ret; // Slot1: Buck2使能,延时2ms ret = PCA9422_WriteReg(0x31, 0x02); if (ret != HAL_OK) return ret; // Slot2: LDO1使能,延时4ms ret = PCA9422_WriteReg(0x32, 0x04); return ret; } // 初始化流程 void PCA9422_Init(void) { // 1. 配置各路输出电压 PCA9422_ConfigBuck1(); // ... 配置Buck2和LDO // 2. 配置上电时序 PCA9422_ConfigSequence(); // 3. 触发上电序列 PCA9422_WriteReg(0x3F, 0x01); }这段代码里,解锁序列的寄存器地址和值需要根据实际芯片手册确认,不同型号可能不一样。电压码值的计算也要看手册里的公式,有的是线性步进,有的是查表。
4.4 配置完成后的验证方法
代码写完了不代表配置就对了。我一般会做三步验证:
第一步,用I2C扫描工具确认芯片地址能正确应答。如果连地址都扫不到,先查硬件:供电有没有、上拉电阻有没有、焊接有没有虚焊。
第二步,读回所有配置寄存器的值,和写入的值对比。这一步能发现写保护没解锁、寄存器地址写错、I2C通信丢数据等问题。读回的时候要注意,有些寄存器是只读的,有些是读写但读回值可能和写入值不同(比如状态寄存器)。
第三步,用示波器量每一路输出的上电波形。把探头挂在Buck1、Buck2、LDO1的输出电容上,触发方式设为上升沿触发,看三路输出的建立顺序和延时是否符合预期。同时观察有没有过冲、振铃、掉电复位等异常。这一步是最直观的,也是最能发现问题的。
5. 调试中踩过的坑:从复位怪象到I2C死锁
5.1 上电复位不稳定的排查过程
项目第一次联调的时候,板子上电后STM32F405RG有时候能正常启动,有时候反复复位。用示波器抓复位引脚波形,发现复位信号在电源建立过程中有多次抖动。一开始怀疑是复位电路的问题,换了复位电容和电阻,问题依旧。
后来把注意力转到电源上。用示波器同时抓Buck1和Buck2的输出,发现Buck2的3.3V比Buck1的1.2V先建立,中间差了大概1.5ms。这就是问题所在:IO电压先于内核电压建立,导致STM32内部出现短暂的漏电流路径,触发了欠压复位。
回头查PCA9422的时序配置寄存器,发现Slot1的延时值设成了0,也就是说Buck2和Buck1几乎同时使能。但Buck2的软启动时间比Buck1短,所以它的输出先稳定。把Slot1的延时改成3ms后,问题解决。
这个坑的教训是:不要假设两路Buck的软启动时间一样。即使同时使能,输出建立时间也可能不同。时序配置一定要留足够的余量,最好用示波器实测每一路的建立时间,再根据实测值来设延时。
5.2 I2C通信在低功耗模式下的死锁
另一个比较隐蔽的问题是I2C死锁。现象是系统运行一段时间后,进入低功耗模式再唤醒,I2C通信就挂了,读PCA9422的寄存器一直返回超时。
排查后发现,问题出在低功耗模式下I2C引脚的状态。STM32进入STOP模式后,I2C引脚如果配置不当,会输出低电平,把总线拉死。而PCA9422作为从机,如果检测到总线被拉低超过一定时间,会进入总线恢复状态,等待总线释放。但STM32这边没有正确释放总线,就形成了死锁。
解决办法有两个:一是在进入低功耗前把I2C引脚配置为模拟输入或者浮空输入,不要让它们输出低电平;二是在唤醒后重新初始化I2C外设,而不是直接继续用。我最后用的是第二种方案,在唤醒回调里重新调用I2C初始化函数,问题再没出现过。
还有一个相关的问题是I2C的上拉电压。如果PCA9422的IO电压是3.3V,而STM32的I2C引脚在低功耗模式下电压域不同,可能会出现上拉电压不匹配的情况。这时候要确保上拉电阻接到正确的电压域上,或者用电平转换芯片。
5.3 电池充电时的温度保护误触发
电池充电功能调试时,遇到充电电流上不去的问题。配置的是500mA,实际只充到100mA就停了,状态寄存器报温度故障。
检查NTC电路,发现NTC电阻的选型和数据手册推荐的不一致。数据手册要求用10kΩ的NTC,我用了100kΩ的,导致温度检测电压落在故障区间内。换了10kΩ的NTC后,充电电流恢复正常。
这个坑提醒我:PMIC的辅助功能引脚,即使看起来简单,也要严格按照数据手册的推荐值来设计。NTC的B值、阻值、分压电阻的阻值,都会影响温度检测的准确性。如果不用温度检测功能,也要把引脚接到正确的电平上,不能悬空。
5.4 电源纹波对ADC精度的影响
板子上有一路12位ADC用来采集传感器信号,调试时发现ADC读数跳动很大,有效位数只有8位左右。用示波器量VDDA的纹波,发现上面叠加了大概20mV的高频噪声,频率和Buck的开关频率一致。
解决方法是给VDDA加了一级LC滤波。在LDO输出和VDDA之间串了一颗10μH的电感,再并一颗10μF加0.1μF的电容。滤波后纹波降到2mV以内,ADC的有效位数恢复到11位左右。
这个经验是:给模拟部分供电,不要直接从Buck输出取电,即使Buck的纹波指标看起来不错。Buck的开关噪声频谱很宽,会通过电源引脚耦合到ADC的基准上。用LDO做后级稳压,再加LC滤波,才能满足高精度模拟电路的需求。
6. 低功耗场景下的电源管理策略
6.1 STM32F405RG的低功耗模式与电源域关系
STM32F405RG支持多种低功耗模式:Sleep、Stop、Standby。不同模式下,芯片内部哪些电源域保持供电是不一样的。Sleep模式下,内核时钟停了,但所有电源域都保持;Stop模式下,内核电压可以降到更低,大部分外设断电;Standby模式下,只有备份域和少量唤醒电路保持供电。
配合PCA9422使用的时候,可以根据MCU的低功耗模式动态调整各路输出。比如进入Stop模式时,可以把Buck2的3.3V降到2.8V(如果外设允许),或者直接关掉不用的LDO。PCA9422支持通过I2C动态改输出电压,这个功能在低功耗场景下很有用。
但要注意,改电压之前要确保负载能承受。比如SD卡在2.8V下可能工作不正常,那就不能降。还有,改电压的时候输出会有短暂的波动,如果MCU正在跑关键代码,可能会触发复位。所以一般是在进入低功耗模式之前改电压,唤醒后再改回来。
6.2 动态电压调节的实现方法
PCA9422的Buck输出电压可以通过I2C实时调整,这给动态电压调节(DVS)提供了硬件基础。STM32F405RG虽然不像某些低功耗MCU那样原生支持DVS,但可以通过软件配合实现类似效果。
思路是这样的:在系统负载低的时候,把内核电压从1.2V降到1.0V,同时把主频从168MHz降到84MHz。这样功耗可以降低大概40%。负载上来的时候,先把电压升回1.2V,等电压稳定后再把主频升上去。
实现的时候要注意顺序:升频之前先升压,降压之前先降频。顺序反了会导致MCU在低压下跑高频,出现时序违例甚至死机。
代码实现上,可以封装两个函数:一个是System_PerformanceMode(),把电压和频率都设到高性能档;另一个是System_LowPowerMode(),把电压和频率都设到低功耗档。切换的时候严格按照“升压→升频”和“降频→降压”的顺序来。
6.3 电池电量监测与低电量保护
PCA9422内部有系统监控ADC,可以测量电池电压和充电电流。STM32可以通过I2C定期读取这些值,估算电池剩余电量。
电量估算的精度取决于电池的放电曲线。锂电池的电压和剩余电量不是线性关系,中间有一段平台区,电压变化很小但电量变化很大。所以单纯靠电压估算电量,在平台区误差会很大。更准确的方法是结合库仑计,对充电和放电电流做积分。
如果项目对电量精度要求不高,用电压查表法就够了。做法是:在实验室里对电池做一次完整的放电测试,记录电压和放电容量的对应关系,做成查找表存在STM32的Flash里。运行时读电压,查表得到剩余电量百分比。
低电量保护也很重要。当电池电压低于某个阈值(比如3.3V)时,系统应该主动降低功耗,关闭不必要的外设,提醒用户充电。如果电压继续降到3.0V以下,就应该保存关键数据并进入待机模式,防止电池过放损坏。
7. 写在最后:一些零散但有用的经验
整个项目做下来,关于PCA9422和STM32F405RG的配合,有几个零散的经验值得单独拎出来说。
第一,PCA9422的寄存器配置最好做成一个结构体数组,把寄存器地址、值、延时都放在一起,初始化的时候遍历数组依次写入。这样代码清晰,改配置的时候不容易漏。我见过有人把寄存器写入散落在各个函数里,后来要改一个电压值,找了半天才找到对应的写操作。
第二,I2C通信一定要加超时和重试机制。电源管理芯片的I2C挂了,整个系统就失控了。我的做法是每次读写都带100ms超时,连续失败3次就触发系统复位,让整个系统重新初始化。虽然粗暴,但可靠。
第三,调试电源部分的时候,示波器比万用表有用得多。万用表只能看平均值,看不到纹波、过冲、时序。一个四通道示波器,同时抓输入电压、Buck1输出、Buck2输出、复位信号,很多问题一眼就能看出来。
第四,PCB打样回来之后,先不要焊MCU,只焊电源部分,上电测各路输出。确认电源正常了再焊MCU。这样如果电源有问题,排查起来简单得多,不会因为MCU的存在而干扰判断。
第五,数据手册要反复看。PCA9422的寄存器有上百个,第一遍看的时候很容易漏掉细节。我的习惯是把关键寄存器的配置值整理成一个表格,贴在工位上,调试的时候随时对照。特别是上电时序、电压码值、保护阈值这些,一定要以手册为准,不要凭经验猜。
这个方案后续还可以扩展的方向包括:增加无线模块的电源管理(比如用PCA9422的LDO给蓝牙或者LoRa模块供电,通过I2C控制其开关),以及实现更精细的动态功耗管理(根据任务负载实时调整各路电压和频率)。但那是另一个话题了,先把基础电源管理做稳,后面的扩展才有意义。