资讯动态

PMIC+I2C:便携设备电源管理与低功耗调压设计实践

发布时间:2026/10/9 10:57:10 来源:尧图企业网站定制
之前做便携式小盒子时最困扰我的不是算法怎么写而是电源管理方案太碎充电一颗、升压一颗、LDO 两颗各管各的互相之间还要用逻辑引脚去协调整板 BOM 快赶上主板了。后来在某个模拟项目 X 里把主控换成 PIC18F86J16电源部分换到 PCA9422 上整套系统瞬间清爽了很多。这块 PMIC 把充电管理、多路输出、I2C 配置和中断上报都收到一颗芯片里MCU 只需要通过 I2C 去规划电压、使能通道、切换工作模式整机的电源树就有了统一的控制入口。这篇内容适合正在做电池供电便携设备、智能穿戴或 IoT 节点电源管理的朋友。如果你也打算把分散的电源模块整合进 PMIC或者想让 MCU 对电源有更强的控制力可以直接参考我这次的完整实现从硬件选型、外围电路到 I2C 配置、动态调压、低功耗切换再到调试过程里踩过的坑一次讲清楚。1. 项目整体思路为什么把电源管理交给 PMIC 和 MCU 的组合1.1 从分立电源到集成 PMIC省的不只是 BOM先算一笔账。原来分立方案里锂电池进来要先分两路一路给充放电管理芯片一路经过一个升压或降压给系统供电然后再挂两片 LDO 分别给 MCU 和外设。充电芯片要 MCU 用 GPIO 去模拟握手时序升压芯片要外加使能控制和软启动电容LDO 的输入输出电容还得按手册严格来。关键问题是这些芯片之间的上电时序、欠压保护、短路保护都是割裂的出了问题很难定位。换到 PCA9422 之后输入输出轨、充电回路、保护逻辑都在同一颗芯片内部管理。它有多路输出通道每一路都可以通过 I2C 独立配置电压、开关、放电顺序还集成了针对单节锂电池的充电管理。MCU 这边只保留一个任务通过 I2C 下发配置并在关键节点读取状态、响应中断。整个电源控制从分散的逻辑电平控制变成了统一的寄存器管理调试时看寄存器状态就能知道每个通道在干什么效率完全不一样。1.2 两颗芯片的分工PCA9422 管的是电能怎么进来、怎么存、怎么送出去。它负责电池充电、系统供电、各路输出的通断和电压设定也负责把过压、欠压、充电完成等事件通过中断脚上报给 MCU。PIC18F86J16 管的是什么时候用多少电。它本身是一颗 8 位 MCUFlash 和 RAM 对这个场景足够用I2C 外设也够稳定关键是功耗低、启动快。系统在工作状态时MCU 正常运行进入待机时MCU 把不用的输出通道关掉、把电压调低最后自己也进入低功耗模式需要充电时MCU 通过 I2C 读取充电状态并上报。我按功能画了一下这套系统的工作流大致是上电时 PMIC 按默认配置输出MCU 先跑起来再去修改 PMIC 配置运行过程中 MCU 根据负载状态调压或关断外设电源电池电量低时 PMIC 上报中断MCU 进入低功耗并等待唤醒。这个模型下MCU 虽然不做功率变换但它是整个电源策略的决策者。2. 硬件设计细节外围电路选型与板级注意点2.1 PCA9422 外围电路的设计要点PCA9422 这种 PMIC 虽然集成度高但外围也不是零器件。我拿到这颗料之后先跟原厂手册对齐了引脚功能再按系统需求把输入、输出和充电三部分分别规划。输入侧是最需要注意的。如果系统同时支持 USB 和电池输入那么 USB 的 5V 路径上要加过压保护和防倒灌电池正极到 PMIC 的路径要尽量短而且靠近芯片引脚要放一个 10uF 左右的陶瓷电容再加上一颗 0.1uF 高频退耦。这组电容不能省我实测过输入路径长了之后负载切换瞬间 PMIC 容易触发输入欠压保护。输出侧的电感要根据每路负载电流选。一般 PMIC 手册里会给一个推荐电感量范围和饱和电流要求我的原则是选择饱和电流至少是最大负载电流 1.5 倍的电感不然大电流瞬间电感饱和输出电压直接掉下去。另外输出电容决定了纹波和动态响应我通常先在手册推荐值基础上用然后实测纹波再微调。充电回路的重点是电流设定电阻和电池温度检测。PCA9422 的充电电流可以通过外部电阻设定也可以通过 I2C 修改我推荐硬件先按最大充电电流定好一个保守值比如 500mA再在软件里根据电池容量往下调这样即使初始化代码没跑硬件也在安全范围。注意我第一次画板时把电池负端直接大面积铺铜接到 PMIC 的 GND结果充电电流采样不准。原因是 PMIC 的充电电流采样需要独立的采样路径电池负极到芯片之间不该有大电流 GND 平面共享后来单独走线才正常。2.2 PIC18F86J16 侧的连接与 I2C 上拉计算PIC18F86J16 的供电我直接取 PCA9422 的一路 LDO 输出这样 MCU 的电源可以被 PMIC 控制待机时可以把 MCU 电源轨也关掉实现整板低功耗。I2C 的两条线 SCL、SDA 接到 PMIC 的对应引脚中断输出 INT 接到 PIC 的外部中断输入用于事件唤醒。I2C 上拉电阻是很多人容易忽略的点。PCA9422 支持最高 400kHz 的 I2C 速率PIC18F86J16 的 MSSP 外设也能跑到 400kHz但总线上的上拉电阻得配合总线电容来选。我当时的 SCL/SDA 走线不长板级电容估算在 100pF 左右3.3V 供电下选了 4.7kΩ 上拉实测 400kHz 波形上升沿稍微有点缓但通信正常。走线超过 5cm 的话建议把上拉降到 2.2kΩ 或者降速到 100kHz稳定性优先。布局上要注意模拟地和数字地。PCA9422 的充电电流采样属于模拟信号PIC18F86J16 的数字噪声比较大两块区域最好单点连接PMIC 的开关节点 L受机远离 MCU 的晶振引脚我第一版就是开关节点绕到了晶振下面干扰导致 MCU 偶发复位。3. 软件设计与初始化流程3.1 PIC18F86J16 的 I2C 主模式配置PIC18F86J16 的 MSSP 模块配置成 I2C 主模式并不复杂但有几个细节必须处理好。首先是时钟MSSP 工作在 Fosc/4 的时钟源下波特率通过 SSPADD 寄存器设置。以 400kHz 目标速率、16MHz Fosc 为例时钟分频后需要配置的 SSPADD 大致是 (Fosc / (4 * Fosc_derived)) - 1 这一类计算实际值我会在初始化时结合示波器波形微调。I2C 通信我用的是轮询加超时。没有操作系统不用担心任务切换问题但必须防止从机拉死总线导致程序卡死。每次发送起始条件、写地址、写寄存器地址、写数据、停止条件的每一步都要加一个超时变量超时就把总线复位。这里贴一下我当时写的核心代码框架XC8 环境下编译// I2C 初始化目标 400kbps void i2c_init(void) { SSPCON1 0x28; // I2C 主模式使能 SSP SSPCON2 0x01; // ACK 状态 SSPADD I2C_BRG; // 根据实际时钟计算 SSPSTAT 0x80; // Slew rate control } // 写 PMIC 寄存器 unsigned char i2c_write_reg(unsigned char addr, unsigned char reg, unsigned char val) { unsigned int timeout I2C_TIMEOUT; SSPCON2 0x01; // 发起开始条件 while (!PIR1bits.SSPIF timeout--); PIR1bits.SSPIF 0; // 地址 写位 SSPBUF (addr 1) | 0; // 后续逐字节发送 reg 和 val并检查 ACK // ... SSPCON2 0x03; // 结束条件 return 0; }实际工程里我会把起始、结束、发送、接收都封装成底层函数上层再去拼寄存器读写。不建议在应用层直接操作 SSPBUF那样逻辑会乱。3.2 PMIC 寄存器初始化顺序PCA9422 的寄存器不少但初始化顺序可以归纳成一套固定流程。我每次做新板子都会按这个顺序来能少踩很多坑。第一步先读 ID 和版本寄存器确认 I2C 地址正确、通信正常。如果这一步读数不对后面所有配置都白搭。第二步配置每路输出的目标电压和限流值这个阶段不要使能输出先把参数写好。第三步使能需要开启的输出通道观察电流和电压是否正常。第四步配置充电相关的参数包括充电电压、充电电流、截止电流、预充电流。第五步配置中断掩码把充电完成、电池欠压、过温等关键事件打开接到 PIC 的中断脚。顺序里最关键的一条先写电压配置再使能输出。我第一次调试时图省事把电压和使能写成一个复合操作先写了使能位结果输出通道在电压寄存器还没更新时启动了处于一个不确定的电压状态后端负载直接进入欠压保护。后来的代码里我严格规定每次修改某个通道的电压都要先读当前使能状态如果是使能状态就先清使能位再写电压再恢复使能避免中间状态。注意PCA9422 这类 PMIC 的寄存器有些是写入后立即生效有些需要额外触发命令才生效。我遇到过一次写好电压但输出没变排查后才发现忘了发应用新配置的命令。这个细节不同批次芯片可能不一样最好看手册确认。3.3 上电和掉电时序的软件实现上电时序对多电源轨系统特别重要。我这次系统里有三路主要输出VDD_MCU、VDD_SENSOR、VDD_RF。手册和负载要求是 MCU 先上电等 MCU 初始化完成之后再打开传感器和射频电源。软件实现的逻辑是主控上电后先从 PMIC 读取当前状态确认 VDD_MCU 已经稳定然后再写寄存器打开 VDD_SENSOR延时几毫秒等传感器电源稳定再打开 VDD_RF。每一路使能之后我都会读一次电压状态寄存器确认输出真的建立起来才进入下一步。如果某一步超时没稳定就把系统切到安全状态关所有输出、亮故障灯、记录错误寄存器。掉电时序也是同样思路先关射频、再关传感器、最后关 MCU 电源顺序反了容易造成倒灌电流。我这次还遇到一个情况MCU 已经写了掉电命令但 PMIC 的输出放电时间很长电压跌落太慢导致负载在低电压下工作异常。后来我开启了输出放电功能掉电瞬间快速泄放问题才解决。4. 动态调压与低功耗模式设计4.1 为什么必须做动态电压调节便携设备对功耗的要求往往比性能更敏感。我这个项目里有一个传感器数据采集的应用场景CPU 全速跑的时候需要 3.3V 供电电流约 80mA传感器数据准备好之后进入浅度睡眠只需要 1.8V 保持供电电流不到 5mA。如果一直用 3.3V浅睡眠时无用功耗就是 (3.3-1.8)x5mA7.5mW看似不多但电池只有几百毫安时累积下来损耗可观。动态调压的作用就是让电压跟随负载状态调整。PCA9422 支持通过 I2C 修改输出电压PIC18F86J16 在进入低功耗前把 VDD_SENSOR 从 3.3V 降到 1.8V唤醒后再升回 3.3V。这个操作看起来简单但省下的功耗在低功耗场景里非常有意义。4.2 运行中调整输出电压的实现调节电压本身不复杂但要注意时序。我的代码逻辑是先读目标通道的当前电压寄存器计算目标值对应的寄存器码如果目标值比当前值低就先写新电压、等待稳定、再降电流如果目标值比当前值高就先确保负载不会过流然后写新电压、等待稳定。这里有一个实操技巧调压前后最好读一次实际电压输出。PCA9422 内部有电压反馈但外部走线阻抗会导致实际负载端电压和芯片端读数有偏差。我这次就在 PCB 走线长的一路输出上遇到了 0.1V 的压差调压目标值和实际负载电压对不上。后来我在调压后加了 ADC 回采用 PIC 的 ADC 引脚直接量负载端电压形成闭环。软件之外动态调压还受负载瞬态影响。我实测从 1.8V 调到 3.3V 时如果负载电流同时从 5mA 跳到 80mAPMIC 的输出会有一个比较明显的跌落只要负载端电压不低于最低工作电压就可以接受。4.3 低功耗模式的整体策略完整的低功耗不只是调压而是一整套状态切换流程。我按系统工作状态设计了四个模式正常运行模式所有输出开启电压设定为满载值PMIC 和 MCU 都处于全速状态。浅度睡眠模式传感器等大功率外设电源关闭主 MCU 电压降到最低保持电压PMIC 充电功能保留系统等待定时唤醒。深度睡眠模式除了 PMIC 自身维持和 MCU 的备份供电之外所有输出通道都关闭MCU 进入休眠外部按键或 PMIC 的中断事件唤醒。充电管理模式系统不工作充电器对电池充电充电完成后 PMIC 进入低功耗充电维护状态。模式切换的软件实现本质上就是一组寄存器写操作。我封装了set_system_mode(uint8_t mode)函数内部根据模式表依次配置各路输出通断和电压。整个切换必须按固定顺序执行避免切换过程中出现多路同时开关造成电池电流毛刺。提示深睡模式下 PMIC 自身功耗也要重点关注。我实测这套组合在深度睡眠时整板待机电流控制在 20uA 以内关键是关闭了不用的输出通道、关闭了充电完成指示灯、MCU 选择了最低功耗的休眠模式同时保持 I2C 总线上拉不产生额外漏电。5. 调试实录实测中踩过的几个坑5.1 I2C 通信时好时坏根因是上拉电阻和总线电容这应该是我调试中最费劲的一个问题。现象是 PMIC 的寄存器读出来大部分正确但偶尔会读错一个字节有时候连续读写十几分钟又完全正常。一开始我怀疑 PMIC 芯片体质问题换了芯片还有。后来用示波器抓 SCL/SDA 波形才发现400kHz 模式下 SDA 的上升沿明显变缓低电平时间正常但高电平建立太慢导致从机在采样边沿时电平还没稳定。解决方案分两步。第一步把 I2C 速率降到 100kHz 临时验证通信立即稳定第二步重新计算上拉电阻把原来的 4.7kΩ 改为 2.2kΩ总线上拉能力增强后恢复 400kHz波形干净了很多。现在我做这类板子I2C 上拉阻值一定会根据总线电容实测来计算不再直接抄参考设计。5.2 使能顺序错乱导致输出打嗝另一个印象深刻的坑是 PMIC 的输出在启动时打嗝电压起来又掉下去反复几次才稳定。现象出现在一次修改初始化代码之后我把通道使能放在中间位置执行和电压配置顺序错开了一步。PMIC 检测到该通道输出电压建立太慢以为发生过流触发了保护关断输出电压掉下去之后保护条件消失又重新尝试启动形成打嗝。解决方法是严格按照先配置电压、再使能通道的步骤同时检查了该通道的过流阈值配置确保阈值低于实际负载启动电流。我后来还加了一步启动后的状态读取确认输出稳定再继续彻底杜绝了这类问题。5.3 充电管理判满不准背后是采样路径问题充电管理这块我的板子在初期出现了充满电压判不准的现象。用电池测试仪确认电池电压只有 4.0V但 PMIC 上报已经充满。排查之后发现是电池负极和 PMIC 充电采样点之间的走线压降问题。充电电流 500mA 时一条不够宽的采样走线产生了比较大的压差芯片内部看到的电池电压高于电池实际电压于是提前判满。解决方法是把电池负端采样线单独拉出来走线加宽直接连到 PMIC 的采样引脚避免大电流路径和采样路径共用。修改后充电曲线恢复正常判满电压和实测电池电压基本一致。5.4 系统硬复位时 PMIC 状态错乱还有一次系统在异常复位后 PMIC 既不理睬 I2C 命令、输出也不正常只有断电重启才恢复。排查后确认是 PIC 复位时 I2C 总线处于不确定状态正好和 PMIC 的配置状态机发生了竞争PMIC 收到了半截命令进入了错误状态。处理办法是软件复位序列PIC 复位后先拉低 PMIC 的复位引脚如果有没有复位引脚的话就用 I2C 先发软复位命令确保 PMIC 回到默认状态再执行常规初始化。我在项目里约定了一个规则任何 RMII 复位或看门狗复位之后第一步都是重新初始化 PMIC 到已知状态不允许直接跑业务代码。6. 常见问题排查速查表现象可能原因排查与处理I2C 读写不稳定上拉电阻太大、总线电容过大、速率过高示波器抓波形减上拉电阻降到 100kHz 验证某路输出无电压通道未使能、电压值配错、硬件损坏读寄存器确认使能位测电感两端换通道对比输出启动后反复重启电压配置和使能顺序错误、过流阈值设定偏低严格先配电压再使能检查阈值和负载电流充电判满过早采样路径压降、充电参数设置不当单独走采样线核对截止电流和充电电压整板待机功耗偏高输出通道未全关、I2C 上拉漏电、MCU 未进入低功耗逐项关断并实测电流关 PMIC 指示功能电压调整后负载工作异常调压后未回采实际电压、负载端压降大加 ADC 闭环回采PCB 加宽供电走线调试这类电源系统我的建议是先打通通信、再玩配置、最后才做策略。通信不稳定的时候不要盲目调参数先把波形和时序确认好。另外每次修改 PMIC 配置代码之后一定要做完整的掉电重启测试因为很多问题只在冷启动时暴露。另外配置代码建议做成表格驱动。把每一路输出、每一个通道的参数放到一个结构体数组里初始化时统一遍历写入后续修改电压和切换模式只改表项不会牵动大段逻辑。我在这个项目里把运行参数、充电参数、低功耗参数都做成了独立表调试时定位问题效率高很多。最后分享一个小技巧给所有 PMIC 寄存器读写函数加上日志输出在调试时打印地址、数据、返回状态。这看起来不起眼但电源问题排查时能很快定位到底是写入被吞了还是读取时序错了。等系统稳定了再把日志关闭不影响运行性能。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑