news 2026/10/21 3:01:53

基于PCA9422与PIC18F96J65的电池供电电源管理设计

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于PCA9422与PIC18F96J65的电池供电电源管理设计

做电池供电的手持设备,电源管理从来不是把几颗 DC-DC 摆上去那么简单。两年前我在做一台便携采集终端,系统里要同时跑 5V、3.3V、1.8V、1.2V 四路电源,最初用分立方案,上电时序靠 RC 延时网络硬拼,结果低温环境下时序完全漂移,板子间歇性起不来。后来换成PCA9422这颗带 I2C 接口的 PMIC,配上PIC18F96J65这颗 8 位 MCU 专门做电源管理状态机,整套系统才算真正稳定下来。这篇文章把这次方案的设计思路、寄存器配置、软件状态机、实测数据以及踩过的坑完整记录下来,适合正在做便携设备、工业仪表或者电池供电产品的硬件和嵌入式工程师参考。

1. 选型逻辑:电源管理这件事,为什么需要一颗专门的 PMIC 配一颗 8 位 MCU

很多人一开始会问:电源管理不就是几个 DC-DC 加 LDO 吗,为什么非要搞一颗 PMIC 再加一颗 MCU,是不是过度设计?我先从实际场景说起。

1.1 我在项目里遇到的电源问题:四路电源的时序噩梦

我的项目里有四路主要电源:5V 给传感器和电机驱动,3.3V 给数字逻辑,1.8V 给存储接口,1.2V 给 MCU 核心。最开始用的是两颗 DC-DC 加两颗 LDO 的分立方案,每颗芯片的 EN 引脚上接一个 RC 延时网络,让它们按顺序上电。

这个方案在常温下看起来没问题,但产品要做 -20℃ 低温测试时问题全出来了。电容的容值随温度变化,RC 延时时间漂移,有时 1.2V 比 3.3V 先起来,存储器的 I/O 域还没建立就收到了操作指令,直接导致系统反复复位。只能用示波器四通道一遍遍抓时序,用一把电烙铁换来换去调 RC 参数,一个简单的时序问题折腾了快两周。

那时候我才意识到:上电时序这种东西,靠硬件延时网络去拼,本质上是把逻辑写死在电阻电容里,一旦环境变了或者负载变了,根本没有自适应能力。正确的做法是让"时序"成为一段可编程的配置,而不是一堆焊在板子上的 RC 参数。

1.2 PCA9422 的定位:能做什么,不能做什么

PCA9422 是一颗带 I2C 接口的电源管理芯片,内部集成了多路降压转换器、LDO、时序控制单元、电压监测和故障保护逻辑。它最核心的能力是三件事:

  • 多路电源轨的输出电压可以通过寄存器配置,芯片内部有精确的反馈基准,不需要靠外部电阻分压器去调电压。
  • 各路电源的上电顺序、延迟时间可以通过寄存器配置,时序控制由芯片内部逻辑完成,不受温度影响。
  • 具备过压、欠压、过流、过温保护,而且故障状态可以通过中断引脚通知外部控制器。

但它的局限也很清楚:PCA9422 只是一颗执行器,它不知道系统当前处于什么状态,不知道用户有没有按电源键,不知道应用层的任务跑完没有。它的能力边界是"把各路电源按配置的时序打开,并维持它们稳定输出",而"什么时候打开、打开哪些路、异常之后怎么处理"这些决策必须由外部控制器来做。

1.3 PIC18F96J65 的定位:低成本高确定性的"电源大脑"

PIC18F96J65 是一颗 8 位 MCU,在这套方案里担任电源管理大脑的角色。有人可能会觉得,搞电源管理为什么不上 32 位 MCU,性能更强、外设更多。

我的考虑其实很直接。第一,电源管理是一个纯粹的状态机逻辑,不需要跑操作系统,不需要复杂计算,8 位 MCU 的算力绰绰有余。第二,8 位 MCU 的功耗下限通常更低,PIC18F96J65 这类器件在深度睡眠模式下静态电流可以做到微安级,这对电池供电产品至关重要。第三,PIC 系列在工业环境下的稳定性和供货周期是经过验证的,做电源控制这种关键功能,可靠性比性能重要得多。

它在这套方案里的具体角色:通过 I2C 访问 PCA9422 的寄存器,读取各路电源状态,接收 PCA9422 的中断信号,执行按键开关机逻辑,并且在系统异常时做出降级处理。一句话总结:PCA9422 负责"干活",PIC18F96J65 负责"决定干什么"。

如果非要说选型逻辑的教训,那就是:不要因为一颗芯片功能多就去选它,先把"谁执行、谁决策"这条边界划清楚,再决定每颗芯片的分工。

2. 接口与电路:PCA9422 和 PIC18F96J65 的脚位级连接

选型理由聊清楚了,接下来就是最枯燥也最容易翻车的硬件连接环节。这一节不谈理论,只讲我实际画过的原理图上的细节。

2.1 最小连接关系:I2C、中断、PGOOD、按键开机

PCA9422 和 PIC18F96J65 之间的核心接口是 I2C,但完整的电源管理还需要几个状态信号配合。我的连接关系如下表:

PCA9422 引脚PIC18F96J65 引脚连接说明
SCL / SDA对应 MSSP 模块引脚两根线都接 3.3kΩ 上拉到 3.3V
INT(中断输出,低有效)RB0(外部中断输入)PMIC 检测到故障时拉低,通知 MCU
PGOOD(各路输出已就绪)RA1(普通 GPIO)用于软件轮询上电状态,不做硬复位
EN / PWRONRA2(普通 GPIO)MCU 控制 PMIC 主使能
按键输入RA3 + 按键到 GND按键信号同时给 PMIC 和 MCU

有几点细节需要特别说。I2C 上拉电阻的位置要靠近 PCA9422 那侧,而不是靠近 MCU 那侧。很多人习惯把上拉放在 MCU 端,但总线上如果串了排阻或者经过连接器,远端信号边沿会变差,长时间运行容易偶发通信错误。我是把一颗 3.3kΩ 排阻放在 PMIC 附近,示波器实测 SCL 上升沿大约 80ns,很干净。

按键开机这部分,我把按键信号同时接给 PMIC 的使能引脚和 MCU 的一个 GPIO。这样做的原因是:完全关机状态下,PMIC 的输出全关断,MCU 自身也断电,此时只有按键直接触发 PMIC 使能,系统才能从"死亡状态"重新上电。等 MCU 起来之后,再通过 GPIO 锁住电源状态,此时按键就变成一个普通的输入信号,由软件判断短按、长按。

2.2 电感电容选型:额定电流之外的几个经验值

PCA9422 的 buck 输出电压高了之后,电感选型是最容易出问题的地方。我的第一版 PCB 选了一颗额定电流刚好等于负载最大电流的电感,结果满载工作半小时后电感温度升到 75℃ 都不止,效率也明显下降。

后来我总结了一套在参考设计基础上修正的选型规则:

  • 电感饱和电流至少留 40% 余量。比如 1.2V 输出最大 1A,电感的饱和电流必须选 2.5A 以上。电感饱和不只是发热问题,饱和后感值急剧下降,输出纹波会突然变大,严重时甚至引起环路不稳定。
  • DCR 优先选尽量低的。对电池供电设备,一颗电感的 DCR 每高 10mΩ,满载时就要多 10mV 的压降和一部分热损耗,这个账一定要算。
  • 输出电容用 X5R 或 X7R 陶瓷电容,但要注意直流偏压特性。22μF 的陶瓷电容在加 3.3V 直流偏压后,实际容量可能只剩 12μF 左右,所以我在每路输出用了并联两到三颗小封装的电容,而不是单独一颗大封装电容。

PCA9422 数据手册里一般会给典型应用电路,我的做法是:先按典型电路的参数搭第一版,然后根据实测纹波和负载阶跃响应微调。直接抄参考设计不是不行,但一定得理解每个元件为什么在那里。

2.3 PGOOD、INT 与复位信号怎么接才不容易误动作

这里有一个我印象深刻的坑:一开始我把 PGOOD 直接连到了 PIC18F96J65 的 MCLR 复位引脚,想着电源出问题就自动复位 MCU,多省事。

实际调试时被坑惨了。PCA9422 在负载瞬时变化时,PGOOD 信号会因为输出电压短暂跌落产生一个几百微秒的低脉冲。这个脉冲直接复位了 MCU,然而过流或欠压的故障原因未必存在。更麻烦的是,电源恢复之后 PGOOD 又变高,MCU 重启之后根本查不到刚才发生了什么,电路表现就是"莫名其妙复位"。

正确的做法:PGOOD 只接 MCU 的一个普通 GPIO,任何复位动作都由 MCU 决策后执行。INT 引脚接外部中断输入,故障发生时 MCU 先读取 PCA9422 的中断状态寄存器,区分是过压、欠压、过温还是过流,再决定是记录日志、软复位还是直接关断输出。把"故障检测"和"故障处理"解耦,整个系统的鲁棒性会好很多。

3. 上电时序与电压配置:寄存器层面最先要写对的东西

硬件焊接完成、I2C 能够通信之后,第一件要做的事不是写完整驱动,而是把 PCA9422 的电压和时序配置弄对。这一步错了,后面所有调试都会被不稳定的电源干扰,而且很难排查。

3.1 先读 DEVICE_ID,再谈其他:I2C 通信确认这一步别省

我的调试习惯是:不管新的 PMIC 板卡多简单,上电后第一段代码永远是读 DEVICE_ID 寄存器,把读回的值和手册上的期望值对比。

这一步至少能验证三件事:I2C 地址对不对、寄存器映射是不是手册里描述的那一版、电平转换是否正常。我在某次调试中就遇到过,PMIC 实际从机地址的最低有效位由硬件引脚决定,而我原理图上画的是默认地址,结果读不响应。如果当时直接写配置代码,大概率就是"看起来写成功了,实际上什么都没发生",这种问题最难查。

#define PMIC_I2C_ADDR 0x48 // 我的板上 ADDR 引脚为高,地址见手册 #define REG_DEVICE_ID 0x00 // 器件 ID 寄存器,具体偏移以手册为准 #define REG_SYS_CTRL 0x10 // 系统控制寄存器(示例偏移) #define REG_BUCK1_CFG 0x12 // Buck1 电压配置(示例偏移) #define REG_BUCK2_CFG 0x15 // Buck2 电压配置(示例偏移) #define REG_LDO1_CFG 0x1A // LDO1 电压配置(示例偏移) #define REG_SEQ_CTRL 0x20 // 上电时序配置(示例偏移) #define REG_INT_STATUS 0x30 // 中断状态寄存器(示例偏移) uint8_t PMIC_Init(void) { uint8_t id = 0; if (PMIC_ReadReg(REG_DEVICE_ID, &id) != PMIC_OK) { return PMIC_ERR_COMM; // 通信失败,直接返回 } if (id != PMIC_EXPECT_ID) { return PMIC_ERR_ID; // 器件 ID 不匹配,停止配置 } // 先关断所有输出,再开始配置 PMIC_WriteReg(REG_SYS_CTRL, 0x00); // 配置 Buck1 = 1.2V,Buck2 = 3.3V,LDO1 = 1.8V PMIC_WriteReg(REG_BUCK1_CFG, PMIC_VOLT_1V2); PMIC_WriteReg(REG_BUCK2_CFG, PMIC_VOLT_3V3); PMIC_WriteReg(REG_LDO1_CFG, PMIC_VOLT_1V8); // 配置上电时序:Buck2 -> LDO1 -> Buck1 PMIC_WriteReg(REG_SEQ_CTRL, PMIC_SEQ_BUCK2_FIRST | PMIC_SEQ_LDO1_SECOND); // 使能三路输出,PMIC 内部按配置时序依次打开 PMIC_WriteReg(REG_SYS_CTRL, PMIC_EN_BUCK1 | PMIC_EN_BUCK2 | PMIC_EN_LDO1); return PMIC_OK; }

上面代码里的寄存器地址和电压宏定义值,是我针对手头这颗器件整理后的写法。不同批次、不同封装的 PCA9422 在寄存器偏移上可能有差异,抄代码之前务必对着实际手册核对一遍寄存器地图。我每次换一个新硬件版本,都会重新核对一遍,这个习惯帮我避过好几次坑。

3.2 输出电压与时序配置的几条原则

配置输出电压和时序的时候,有几条原则是我后来固化到团队规范里的:

第一,所有输出先全局关断,再逐项配置。如果你在配置过程中就使能了输出,某些电源轨可能在你写完整颗芯片配置之前就处于一个不确定的电压状态,下游器件可能已经启动了。一次干净的配置应该是:关断所有输出,写完所有电压值和时序参数,最后写一个"总使能"触发命令。

第二,时序延迟不是越小越好。有些工程师追求上电时间快,把各路间隔设到几百微秒。但下游器件的复位释放时间、晶体振荡器起振时间、Flash 初始化时间都比这长,时序间隔太短等于没有时序。我一般把相邻电源轨之间的间隔放在 1ms 到 5ms 之间,给下游电路留足稳定时间。

第三,读出后再修改,不要盲写。PMIC 寄存器通常是一个字节包含多个位段,比如高四位是目标电压,低四位是使能和模式。如果直接写入一个全新值,很容易把其他位段覆盖掉。正确的操作是先读回当前寄存器值,用掩码清理要修改的位段,再写回。

3.3 动态调压:运行中改电压的正确顺序

PCA9422 支持运行中动态调整某路输出电压,也就是 DVS。这个功能对需要 DVFS 的应用场景很有用,比如 MCU 在低负载时降到更低的核心电压,可以明显省电。

动态调压操作的正确顺序是:先读当前配置,修改目标电压位段,写回配置寄存器,然后再单独触发 DVS 切换命令。如果直接把目标电压和切换命令写在一个字节里,部分 PMIC 会立即执行切换,但实际上你连"写目标电压"这个动作都没完成,就可能出现电压跳变到错误值的风险。

uint8_t PMIC_SetBuck1Voltage(uint8_t new_mv) { uint8_t val = 0; if (PMIC_ReadReg(REG_BUCK1_CFG, &val) != PMIC_OK) { return PMIC_ERR_COMM; } // 清掉电压选择位段,填入新目标电压 val &= ~CFG_BUCK_VSEL_MASK; val |= (PMIC_MV_TO_CODE(new_mv) << CFG_BUCK_VSEL_SHIFT); // 第一步:先写目标电压 PMIC_WriteReg(REG_BUCK1_CFG, val); // 第二步:触发 DVS 切换 PMIC_WriteReg(REG_DVS_CTRL, DVS_UPDATE_BUCK1); return PMIC_OK; }

还有一点经验:调压之后不要立刻去读 PGOOD 判断完成与否,因为 DVS 切换需要一个斜坡时间。我在实际项目里用轮询周期 1ms,调压后等 5 到 10 个周期再检查电压是否稳定到目标值,基本不会误报。

4. 软件状态机:电源控制从硬件逻辑变成代码逻辑

寄存器配置只是把 PMIC 的"动作"准备好了,真正让整套方案运转起来的是 PIC18F96J65 里的电源状态机。这一节是整个软件的核心。

4.1 五种电源状态与迁移事件

我把系统电源分成了五个状态,分别是关断、保持、运行、睡眠和故障。每个状态定义了 PMIC 哪些输出打开、MCU 自身处于什么工作模式。

状态PMIC 输出状态MCU 状态典型电流
PWR_ST_OFF全部关闭,仅待机通道深度睡眠10μA 级
PWR_ST_HOLD仅保持通道电源运行配置阶段数 mA
PWR_ST_ON全部输出开启正常运行满载电流
PWR_ST_SLEEP部分关闭,保留唤醒通道轻度睡眠数百 μA
PWR_ST_FAULT按策略降级或全关记录状态并处理视策略而定

状态迁移事件包括按键短按、按键长按、PMIC 中断、PGOOD 超时、外部唤醒信号等。每个事件在状态机的入口处统一处理,避免在中断服务程序里做复杂分支。

4.2 状态机驱动核心代码骨架

状态机主体用一个大 switch 实现,每 10ms 在主循环里调用一次。这个周期对电源管理来说足够快,也不会给 8 位 MCU 带来太大负担。

typedef enum { PWR_ST_OFF = 0, PWR_ST_HOLD, PWR_ST_ON, PWR_ST_SLEEP, PWR_ST_FAULT } PowerState; PowerState pwr_state = PWR_ST_OFF; volatile uint8_t pmic_int_flag = 0; volatile uint8_t button_event = 0; void Power_StateMachine(void) { switch (pwr_state) { case PWR_ST_OFF: // 完全关机状态,按键低电平唤醒 if (button_event & B_EVT_PRESS) { PMIC_EnableHoldOn(); // 打开保持电源轨 pwr_state = PWR_ST_HOLD; } break; case PWR_ST_HOLD: // 等待 PGOOD 确认电源稳定 if (PMIC_CheckPgood()) { PMIC_EnableAllOutputs(); // 打开全部电源轨 pwr_state = PWR_ST_ON; } else if (pmic_int_flag) { pmic_int_flag = 0; PMIC_ReadIntStatus(); // 清中断并记录 pwr_state = PWR_ST_FAULT; } break; case PWR_ST_ON: if (button_event & B_EVT_LONG_PRESS) { App_FlushConfig(); // 关机前保存数据 PMIC_DisableAllOutputs(); pwr_state = PWR_ST_OFF; } else if (button_event & B_EVT_SHORT_PRESS) { PMIC_EnterSleepMode(); pwr_state = PWR_ST_SLEEP; } if (pmic_int_flag) { pmic_int_flag = 0; Power_HandleFault(); // 故障处理在函数内决定是否降级 } break; case PWR_ST_SLEEP: if (button_event & B_EVT_PRESS) { PMIC_ExitSleepMode(); pwr_state = PWR_ST_ON; } break; case PWR_ST_FAULT: // 故障状态只允许复位或者硬件断电恢复 if (button_event & B_EVT_LONG_PRESS) { PMIC_DisableAllOutputs(); pwr_state = PWR_ST_OFF; } break; default: pwr_state = PWR_ST_OFF; break; } // 每个周期清除一次事件标志,避免重复触发 button_event = 0; }

这个骨架很简单,但很可靠。实际产品里我在 HOLD 状态加了一个 50ms 的 PGOOD 超时判断,防止 PMIC 硬件异常导致系统卡在等待上。PGOOD 超时后进入故障状态,同时点亮一个故障指示灯,提示用户需要重新插拔电源。

4.3 中断处理原则:ISR 里绝不直接做 I2C 操作

PCA9422 的 INT 引脚是低有效中断输出。MCU 侧把它接到外部中断引脚,中断服务程序里的代码只有三件事:清标志位、记录中断时间、退出。真正的中断原因分析放在主循环里做。

不在 ISR 里做 I2C 操作的原因有两个:第一,I2C 通信本身有时序要求,ISR 里调用读写函数会占用不确定的时间,可能影响其他中断的响应;第二,PMIC 在故障状态下,I2C 总线不一定稳定,如果在 ISR 里读寄存器失败,还要处理错误返回,逻辑会变得非常复杂。我的做法是 ISR 只置一个 volatile 标志位,主循环的下一个周期去读 PCA9422 的中断状态寄存器,根据中断位区分过压、欠压、过温、过流,再决定执行什么动作。

这里有一个细节我觉得特别值得分享:清中断标志的顺序。我一开始先读 INT_STATUS 然后写回清位,但在某些 PMIC 上,如果故障源还存在,INT 引脚会一直保持低电平,读到的状态永远相同。正确做法是先处理完故障源,比如把引起过流的电源轨关掉,再读一次中断状态寄存器,确认故障已经恢复,最后清中断位。这样系统不会在同一个故障上反复进入中断。

5. 实测数据与调试排雷:纹波、动态响应、三个典型故障

软件状态机跑通之后,真正的验证工作才开始。电源管理芯片的数据手册上写着一堆指标,但那些都是在理想测试条件下测出来的,到了自己的 PCB 上,布局、地平面、负载特性都会影响最终表现。

5.1 我的测量方法:示波器怎么接、负载怎么切

测量电源纹波有一个非常容易踩的坑:示波器探头的接地线如果用鳄鱼夹,地线环路会像一个天线感应各种噪声,测出来的纹波可能比实际大十倍。正确的做法是用探头自带的弹簧接地短针,或者用同轴探头直接点在输出电容两端,最大限度缩小测量环路面积。

我测量纹波时同时做两件事:把示波器带宽限制在 20MHz,再打开平均模式。带宽限制去掉高频噪声干扰,平均模式减少随机噪声,这样读到的数值才接近真实纹波。测量负载阶跃响应时,我用电子负载设置从 10% 负载到 90% 负载、切换时间 1μs 的瞬态模式,看电压跌落多少、恢复时间多长。

上电时序用四通道示波器同时抓几个电压轨,触发放到最后启动的那路。实际测试时发现示波器探头的地线夹子接点位置对波形影响很大,最好把所有地线都接在同一个测试点上,避免地电位差。

5.2 实测数据:电压轨、纹波、启动时间的对应关系

以下是这套方案在常温下的实测数据:

电源轨目标电压稳态纹波(20MHz 限带)启动时间备注
Buck1(1.2V 核压)1.20V18mVpp1.6ms强制 PWM 模式下
Buck2(3.3V 数字)3.30V22mVpp2.2ms轻载时纹波略大
LDO1(1.8V 模拟)1.80V9mVpp2.8ms纹波最小

负载阶跃测试中,Buck1 从空载切换到 800mA 时,电压跌落约 85mV,恢复时间约 120μs;Buck2 从空载切换到 1A 时,电压跌落约 90mV,恢复时间约 150μs。这个数据在我的应用场景里是可以接受的,如果你的负载对电压跌落更敏感,可以适当增大输出电容,或者调整 PMIC 的环路补偿参数。

上电时序实测中,三路电源按配置顺序依次建立,相邻两路的间隔大约 2ms,没有出现电源轨重叠或者反串的情况。和之前 RC 延时方案相比,这套时序在 -20℃ 到 60℃ 范围内几乎没有漂移,误差来源只剩下 PMIC 内部的时钟精度,实测在 3% 以内。

5.3 三个让项目晚了两周的坑

第一个坑是 I2C 总线被钳位。我把 MCU 侧 I2C 上拉接到了 5V,但 PCA9422 的 I2C 引脚耐压上限只有 3.6V,总线一直处于一个模糊电平状态,通信时好时坏。排查方法也很费劲,因为现象不是完全不通,而是偶发性的写失败。后来用示波器抓 SDA 波形,才发现高电平只有 3.2V 而低电平没有完全拉低。解决办法是把上拉统一改到 3.3V,确认信号电平在芯片规格书允许范围内。

第二个坑是上电顺序配反导致下游器件反复复位。我把存储器的电源轨排在了核电压前面,但存储器的 I/O 域由另一路电源供电,I/O 域还没建立的时候存储器收到了来自控制器的操作信号,瞬间进入错误状态。这个问题在低温下特别明显,因为低温下存储器启动需要的时间更长。修改了时序寄存器之后,把控制逻辑电源放在最前,负载电源放在后面,问题消失。

第三个坑是轻载纹波被误判为环路振荡。Buck 在轻载模式下会自动进入 PFM 模式,PFM 模式下纹波相对较大,而且频率不固定,示波器上看着就像环路在振荡。我花了一整天在调补偿网络,后来翻手册才发现是轻载模式的正常行为。解决方法是软件里在轻载时把 Buck 切换到强制 PWM 模式,纹波降下来了,代价是静态电流增加约几百微安,但换来的稳定性完全值得。

6. 低功耗专项:待机电流从 15mA 压到 500μA 的实操

对电池供电设备来说,电源管理做得好不好,最终要落在待机电流这个数字上。这一节讲我在这套方案上压低待机电流的完整过程。

6.1 先拆功耗账再动手:每一毫安都要有出处

第一次测完整系统待机电流时,数字是 15.2mA,比预期的 1mA 以下高了一个数量级。我没有直接猜问题,而是把系统分成几个子电路,逐个量电流。

模块实测电流优化手段
PIC18F96J65 正常运行2.6mA转深度睡眠模式,电流降到 1.2μA
PCA9422 三路全开空载7.8mA睡眠时关掉 Buck1、Buck2
电源指示灯 LED 常亮2.2mA软件进入低功耗后关掉 LED
I2C 上拉电阻0.4mA保持,无法避免
传感器常供电2.2mA增加负载开关,睡眠时断开

拆完账就清楚了:主要消耗不是单颗芯片的性能差,而是"所有东西都在空转"。优化的核心思想是把不需要工作的模块在睡眠时彻底断电或者使其进入低功耗模式,而不是去换更贵的芯片。

第一版优化后待机电流降到 850μA,主要贡献来自 MCU 深度睡眠和 PMIC 关断两路 Buck。第二版把传感器的供电开关也断开,同时把未使用的 I/O 引脚全部配置成高阻或固定电平,待机电流进一步降到 530μA。第二版中一个容易被忽视的点是:MCU 上未使用的输入引脚如果悬空,可能因为内部保护二极管产生漏电电流,每个引脚几十微安,积少成多。把所有不用的 I/O 都初始化成输出低电平,问题立刻缓解。

6.2 按键开关机链路:硬件使能与软件关断的分工

低功耗产品必然会遇到一个问题:完全关机之后,怎么再开机。PCBA 上不能有人拿螺丝刀去碰 PMIC 的 EN 引脚,用户只能按一个电源键。

我的设计是:电源键信号同时接到 PCA9422 的硬使能引脚和 PIC18F96J65 的一个 GPIO。系统关机状态下,MCU 断电,PMIC 也不会因为按键之外的因素误开启。用户按下电源键后,PMIC 硬使能生效,保持电源轨先建立,MCU 开始启动。MCU 启动后,软件接管按键判断逻辑,区分短按唤醒和长按关机。

软件关机的顺序很重要。MCU 先向应用层发起保存请求,等待数据落盘,然后写 PMIC 寄存器关闭除保持轨之外的所有输出,最后执行一条 SLEEP 指令进入深度睡眠。此时 PMIC 的保持轨还在给 MCU 供电,但 MCU 已经停止刷程序,系统电流只有保持轨的静态消耗加 MCU 睡眠电流,大约 10μA 级。下一次按键到来时,PMIC 的 EN 引脚电平变化,MCU 从深度睡眠中被唤醒,整个系统重新进入运行流程。

有一个细节我优化了好几轮:关机状态下保持轨是否还需要给 MCU 的 RTC 供电。我的第一版是彻底切断所有输出,完全依靠按键使能,但这样 RTC 时间每次关机都会丢失,用户会抱怨时钟不对。后来改成保留 LDO1 作为常电给 RTC 供电,代价是待机电流增加几微安,但用户体验提升明显。这就是一个典型的工程取舍,低功耗不是越低越好,要结合产品的实际诉求去权衡。

6.3 进一步优化:测量方法、I/O 漏电和上拉电阻的细节

待机电流压到 530μA 之后,再往下压就进入细节战了。测量方法也要换:万用表的电流档内阻会引入压降,容易影响被测电路的工作状态。我改用高精度的电流探头串接在电池输出端,或者用并联采样电阻的方式测平均电流。

真正的细节问题来自三个方面。第一,I2C 上拉电阻在睡眠状态下仍然消耗电流。I2C 总线空闲时是高电平,上拉电阻会有一个持续的压降电流,我把上拉电阻从 3.3kΩ 改成 10kΩ,通信速率依然能满足 100kHz 的需求,但静态电流省了一半。第二,PMIC 的待机通道如果带载很轻,可以考虑把它切到更低功耗的模式。第三,电源路径上的保护二极管反向漏电流在温度升高时会成倍增加,我在选型时专门挑了一颗常温反向漏电只有 0.1μA 的型号,在 60℃ 环境下表现也比原来的普通二极管好很多。

这套方案做下来,我最深的体会是:电源管理不是一个硬件模块,而是一个横跨硬件和软件的子系统。PCA9422 把"动作"做好了,PIC18F96J65 负责"决策",两者配合之后,原来要十几个分立器件拼出来的时序和低功耗控制,变成了一份可配置的状态机代码,可靠性、可维护性和功耗表现都上了一个台阶。

最后分享一个量产阶段的小经验:在设计 PCB 时,一定要预留一组电源轨测试点,把 GND、3V3、1V8、1V2 用 1.27mm 排针引出来。生产抽检时四通道示波器同时抓上电时序,一次能省半天逐板测试的时间。这个细节看似不起眼,真到产线出问题需要快速定位的时候,价值就体现出来了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 7:41:35

PS5串流实战:不拆机不改硬件,主机变全屋可玩游戏中枢

最近我把家里落灰的主机“救”了回来&#xff0c;不是清灰&#xff0c;而是给它加了一套跨设备游玩方案&#xff0c;也就是这个被我命名为 AnyPS5 的小项目。一句话解释&#xff1a;它让主机不再锁死在客厅电视前面&#xff0c;而是能在卧室平板、办公笔记本、床头手机、甚至便…

作者头像 李华
网站建设 2026/10/20 15:24:19

遥感岩性智能识别:极端随机树与群体优化调参实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/19 14:03:06

SAM2微调实战:从数据标注到LoRA训练全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/20 6:49:47

基于深度学习的机场安检危险品识别:从数据标注到模型部署实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/20 12:34:15

PCA9422与STM32F429的PMIC电源管理实战方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 10:52:21

手持设备电源管理实战:基于PCA9422与PIC24HJ的低功耗设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华