低功耗设备电源管理方案:PCA9422 PMIC与STM32F100ZE协作实战

发布时间:2026/10/10 4:53:28
低功耗设备电源管理方案:PCA9422 PMIC与STM32F100ZE协作实战 做低功耗物联网设备的朋友应该都对电源管理这块又爱又恨。我前阵子用 PCA9422 和 STM32F100ZE 这两颗料完整搭过一套电源管理方案把锂电池充电、多路供电、电量监测、低功耗切换这几件事全收了进去。PCA9422 作为 PMIC 负责底层电源变换和充电控制STM32F100ZE 作为主控负责配置、监控和策略调度两端配合下来整个板子的电源部分非常干净。这篇文章就围绕这个组合把整体架构、硬件设计、固件实现和调试过程里比较关键的东西完整讲一遍适合正准备做类似低功耗产品、或者想搞明白 PMIC 如何跟 MCU 协作的朋友参考。1. 整体设计思路与方案选型1.1 这里说的“完整电源管理”到底要管什么很多人一提电源管理第一反应就是“能开机、电压对就行”但真正做产品就会发现远没那么简单。我当时做的项目是一个低功耗温湿度标签一节锂电池供电板上同时挂了主控、无线通信模块、传感器、LED 指示灯还有一块很小的屏幕。仔细一列需求发现电源这块要管的事特别多电池要能充充电电流要能根据电源适配器能力调整系统需要多路电压3.3V 给主控和传感器1.8V 给无线模块和部分外设LED 驱动还需要一个独立可关断的供电轨待机功耗要压到微安级否则标签放半个月就没电另外还要实时知道电池还剩多少电、有没有过温、充电有没有异常。如果这些事儿全用分离器件去拼电路会变得非常庞大。一路 LDO 加一路 DCDC再加一个充电管理 IC最后接一堆电平转换、MOS 管开关硬件改版一次软件也跟着遭罪。所以这类需求下最自然的选择就是把“电源管理”这件事交给一颗专门的 PMIC把“策略和控制”交给 MCU。PMC 管的不是某一路电而是一个完整的电源子系统。1.2 为什么选 PCA9422 搭配 STM32F100ZE先说 PCA9422。这颗 PMIC 吸引我的点主要有三个。第一它把充电回路和多路 DC-DC 整合在一起外围只需要很少的阻容和电感BOM 很干净。第二关键参数全部可以通过 I2C 改写输出电压、充电电流、中断使能这些都不用改电阻调试阶段特别省事。第三它内部带了 ADC 和放电监测相关电路电池电压、电流、温度这类信息可以直接从寄存器里读省掉了外部分压采样网络。再说为什么主控选了 STM32F100ZE。这颗芯片虽然是 Cortex-M3 内核、主频 24MHz性能不算强但做电源管理策略绰绰有余。而且它的外设资源非常齐全I2C、USART、ADC、定时器、丰富 GPIO 全都有144 引脚封装给扩展留了很大余量。我当时手上正好有这颗料加上它价格实在就直接定了。这里有个经验选主控不要只看算力要看接口数量够不够、低功耗模式好不好用、调试工具熟不熟。F100ZE 的低功耗模式在 Stop 下能保持 RAM 内容配合 RTC 唤醒做低功耗标签项目完全够用。这类组合的另一个优势是芯片之间的协作关系非常清晰。PCA9422 负责“把电池和外部输入变成各路稳定的电源”STM32F100ZE 负责“告诉 PMIC 怎么配置、读取状态、在合适时机切到合适的电源策略”。相当于 PMIC 是执行层MCU 是管理层职责边界清楚出了问题也容易定位。1.3 系统电源树设计与启动顺序电源树是整个设计的骨架我一般先画清楚再动电路。这个项目的电源树大致是这样的电源通道输出电压主要负载时序/开关策略输入 VBAT3.0V~4.2V电池直接通路始终在线BUCK 通道 03.3VMCU、传感器、指示灯常开系统启动后输出BUCK 通道 11.8V无线模块、电平转换由 GPIO 控制使能LDO 通道3.0VLCD 背光/模拟电路按需开低功耗时关断充电输入5V USB充电回路检测到 VBus 才启用这个划分的原则有两条。一是主控供电必须最可靠所以 3.3V 这一路放在常开通道上上电先建立确保 MCU 第一时间跑起来。二是耗电大或不需要一直供电的外设尽量放在可独立关断的通道上这样进入低功耗模式时可以直接把对应输出切掉把待机电流压下去。启动顺序方面PCA9422 上电后先进入默认安全状态由 MCU 初始化完成后写入新的配置再逐个使能输出通道。这样就避免了外设在主控还没初始化时就进入未知状态。这套设计下来比原来的分离器件方案简洁很多。硬件上少了一堆 LDO、MOS 管和分压电阻软件上也统一成一个 I2C 读写的问题整个项目后续迭代都轻松不少。2. 硬件设计要点与关键参数2.1 PCA9422 的功能拆解PCA9422 这一类 PMIC 的寄存器结构虽然各家有差异但功能模块大致是固定的。我按功能拆开讲方便大家对照手册快速定位。第一个模块是充电控制。它支持对单节锂电池进行线性充电输入一般接 5V USB。需要关注的寄存器主要是充电电流设定、充电截止电压、充电超时时间、充电状态标志。充电电流建议根据电池容量来定我实际用的是 0.5C 左右也就是 1000mAh 的电池按 500mA 充既能保证速度又不会让电池温升太快。如果输入电源能力有限还需要把输入电流限制配小一点防止把适配器拉垮。第二个模块是降压输出通道。PCA9422 上有多个功率输出通道我用到的有降压通道和 LDO 通道。降压通道效率高适合电流大的负载LDO 通道纹波小适合模拟电路但压差大时功耗也会大。输出通道的电压值、软启动时间、使能控制都在寄存器里配置。第三个模块是监测与中断。内部 ADC 可以采电池电压、充电电流、芯片温度等参数状态寄存器里也会有过压、欠压、过温、充电完成、充电异常这些标志。中断引脚 INT 可以配置成事件触发MCU 通过外部中断来感知电源状态变化不用一直轮询。使用 PCA9422 时最重要的一点是上电默认值不一定适合你的系统。有些输出通道可能默认关闭有些中断默认屏蔽所以初始化代码里第一件事就是完整配置一遍而不是假设“上电就能用”。2.2 STM32F100ZE 的资源分配与引脚规划STM32F100ZE 的资源在这个项目里不算紧张但引脚规划我还是提前做了表避免画板时乱了。功能STM32F100ZE 引脚/外设说明I2C 总线I2C1SCL/SDA 接到 PCA9422400kHz 快速模式加 4.7k 上拉电源中断输入GPIO 外部中断如 PA0下拉配置上升沿/低电平有效需按手册充电状态 LEDPB0 推挽输出接 LED 限流电阻无线模块使能PB1 推挽输出控制 BUCK 输出通道使能RTC 唤醒内部 RTC用于周期性唤醒低功耗状态SWD 调试口PA13/PA14保留方便调试I2C 这块要特别注意。PCA9422 是标准的 I2C 从机地址由硬件或寄存器决定上电后建议先读一次芯片 ID 确认总线没问题。STM32 的 I2C 引脚默认是开漏模式所以外部必须有上拉电阻我用的是 4.7kΩ400kHz 下波形很好。如果板上还有其他 I2C 设备要注意地址冲突和总线电容总线过长或挂载设备过多时要适当降低速率。引脚分配上另一个容易忽视的点是中断引脚。PCA9422 的 INT 脚要接到 STM32 上带外部中断能力的引脚并且要配置为上拉或下拉的输入模式防止悬空误触发。我在早期调试时就是没注意这个充电器一插上就触发中断查了半天才发现是引脚配置问题。2.3 PCB 布局与滤波的细节电源电路的 PCB 布局直接影响纹波和稳定性。PCA9422 的降压通道用的电感我建议选屏蔽式功率电感型号按输出电流和纹波要求来。电容方面输入输出都要放足够的陶瓷电容特别要注意靠近芯片引脚放置缩短回路路径。有两种比较容易踩的坑。一是地回路处理不当大电流的功率地和小信号的模拟地混在一起导致 ADC 采样值乱跳。二是电感底下的铺铜处理大面积铺铜会改变电感特性反而可能让噪声变大。比较好的做法是按照芯片手册里的参考布局来画功率回路尽量短粗反馈走线远离电感保持 PCB 布局整洁。另外如果板上同时有无线模块电源噪声会直接影响射频性能。我在布局时尽量让无线模块的供电线远离电感并在靠近无线模块的位置额外加了一级小电容滤波实测对射频灵敏度有帮助。3. 固件实现与核心流程3.1 I2C 驱动编写与寄存器读写封装固件开发的第一步是把 I2C 驱动跑通。STM32F100ZE 的 I2C1 用标准外设库或 HAL 都可以我这边用的是 HAL 库先把初始化写好#include stm32f1xx_hal.h I2C_HandleTypeDef hi2c1; void MX_I2C1_Init(void) { hi2c1.Instance I2C1; hi2c1.Init.ClockSpeed 400000; hi2c1.Init.DutyCycle I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 0; hi2c1.Init.AddressingMode I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 0; hi2c1.Init.GeneralCallMode I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode I2C_NOSTRETCH_DISABLE; HAL_I2C_Init(hi2c1); }初始化完成后读写封装成两个函数#define PCA9422_I2C_ADDR 0x28 // 实际地址以芯片手册为准 uint8_t pca9422_read_reg(uint8_t reg) { uint8_t val 0; HAL_I2C_Mem_Read(hi2c1, PCA9422_I2C_ADDR 1, reg, I2C_MEMADD_SIZE_8BIT, val, 1, 100); return val; } void pca9422_write_reg(uint8_t reg, uint8_t val) { HAL_I2C_Mem_Write(hi2c1, PCA9422_I2C_ADDR 1, reg, I2C_MEMADD_SIZE_8BIT, val, 1, 100); }寄存器地址和具体位域定义建议在头文件里做成宏方便维护。封装层面我习惯再加一层“读改写”函数因为很多寄存器只有某些位是可写的直接整片覆盖容易误清状态位。比如先读回寄存器值改完目标位段再写回去这样能减少因为不了解保留位含义而踩的坑。3.2 上电初始化流程与关键配置系统上电以后STM32F100ZE 先执行基础时钟配置和 I2C 初始化然后就进入 PCA9422 的初始化流程。我的实际顺序如下void pca9422_init(void) { uint8_t id 0; // 第 1 步检查 I2C 通信是否正常 id pca9422_read_reg(REG_CHIP_ID); if (id ! EXPECT_CHIP_ID) { error_handler(); return; } // 第 2 步设置各路输出电压 pca9422_write_reg(REG_BUCK0_CFG, 0x1A); // 3.3V pca9422_write_reg(REG_BUCK1_CFG, 0x0F); // 1.8V pca9422_write_reg(REG_LDO_CFG, 0x14); // 3.0V // 第 3 步配置充电电流与截止电压 pca9422_write_reg(REG_CHG_CFG, 0x32); // 500mA pca9422_write_reg(REG_CHG_VLIM, 0x04); // 4.2V // 第 4 步使能需要的中断 pca9422_write_reg(REG_INT_MASK, 0x00); // 开启所有电源事件中断 // 第 5 步使能输出通道 pca9422_write_reg(REG_CTRL, 0x07); }每步为什么要这么做我简单说一下。第 1 步读芯片 ID 是最重要的一次握手它同时验证了地址、上拉、电平转换、I2C 时序如果这里不过后面全都不用谈。第 2 步必须在使能输出之前完成否则通道已经输出默认电压再改电压会有短暂波动可能引起负载复位。第 3 步充电参数放到输出使能之后配置是因为充电回路通常在检测到 VBus 以后才真正工作不会跟主电源输出抢初始化资源。第 4 步和第 5 步打开中断和输出顺序上先配中断再使能输出可以保证输出建立过程中的异常事件第一时间被捕获。需要提醒的是芯片上电默认的 ID 核对完成以后不要着急把整段初始化封装成一个“看不见细节”的黑盒函数。调试阶段尽量把每一步的寄存器值通过串口打印出来或者用逻辑分析仪抓 I2C 波形确认。曾经有一次我改了输出电压配置但代码里少写了一行寄存器使能结果输出还是默认值抓波形才发现写进去的值根本没生效。3.3 电量监测与低功耗状态切换电量监测这块我主要是通过 PCA9422 内部 ADC 读电池电压寄存器来实现配合软件做简单的电量百分比映射。比如读回电压值经过换算得到毫伏再按电池放电曲线分几个区间显示成电量百分比。不要求非常精确的话这个方案性价比很高。uint16_t get_battery_mv(void) { uint8_t adc_h pca9422_read_reg(REG_VBAT_ADC_H); uint8_t adc_l pca9422_read_reg(REG_VBAT_ADC_L); uint16_t raw (adc_h 8) | adc_l; return (uint16_t)((float)raw * ADC_LSB_MV); }低功耗状态切换是整个项目里比较关键的部分。我的做法是STM32F100ZE 需要进入 Stop 模式前先把外设关掉然后把 PCA9422 不需要的输出通道关闭再设置 RTC 唤醒时间最后执行 STOP 指令void enter_low_power_mode(void) { // 关闭无线模块供电通道 pca9422_write_reg(REG_CTRL, 0x03); // 仅保留 3.3V 通道 // 关闭无关外设时钟 __HAL_RCC_GPIOB_CLK_DISABLE(); __HAL_RCC_GPIOA_CLK_DISABLE(); // 关闭 I2C省掉总线静态功耗 HAL_I2C_DeInit(hi2c1); // 配置 RTC 唤醒 HAL_RTC_SetAlarm_IT(hrtc, sAlarm, RTC_ALARM_A); // 进入 Stop 模式 HAL_SuspendTick(); HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); }唤醒以后重新初始化 I2C把 PCA9422 的输出通道重新打开再恢复外设配置。这中间要注意一个细节从 Stop 模式唤醒后外设时钟状态可能已经改变不能直接继续原先的操作而是要重新做一遍初始化。我的代码里把“电源管理初始化”单独抽成了一个函数唤醒和上电都调用它减少重复代码。3.4 中断处理与故障恢复PCA9422 的 INT 引脚接到 STM32 的外部中断中断回调里读状态寄存器判断具体是什么事件void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin INT_PIN) { uint8_t status pca9422_read_reg(REG_INT_STATUS); if (status FLAG_CHG_DONE) { // 充电完成更新电池状态 } if (status FLAG_CHG_FAULT) { // 充电异常进入保护逻辑 pca9422_write_reg(REG_CTRL, 0x00); } if (status FLAG_OVERTEMP) { // 过温保护关闭非必要输出 pca9422_write_reg(REG_CTRL, 0x01); } } }中断处理的第一原则是快进快出。中断里不要做 I2C 长阻塞操作尤其是 400kHz 通信在中断里等应答这种事会拖慢整个系统。我一般是在中断标志位置位后只做最少的处理具体逻辑放到主循环的任务里执行。如果某些状态必须立即响应那也要设置超时保护防止读状态寄存器卡死在中断里。故障恢复方面比较有效的做法是维护一个“电源状态机”把正常运行、低功耗、充电中、故障保护这些状态管理起来。每个中断事件都触发状态机迁移避免出现多套逻辑互相打架。我早期没做状态机时出现过充电完成中断和低功耗切换同时发生导致输出混乱的情况后来统一用一个状态机管理问题就没了。4. 调试实战与问题排查记录4.1 I2C 通信异常的排查顺序这个项目里我遇到最多的就是 I2C 通信问题。整理一下排查顺序基本能解决九成的情况。第一检查地址。PCA9422 的 7 位地址写没写错发送时有没有正确左移一位变成 8 位地址。我第一次就犯过这个错直接把 7 位地址传给了 HAL 库结果总线 ACK 一直收不到。第二检查上拉电阻。I2C 开漏总线没有上拉啥都白搭4.7k 是常用值但总线过长、挂载设备多时可以换 2.2k 试试。第三抓波形。用逻辑分析仪抓 SCL/SDA看起始条件、地址帧、数据帧的时序对不对。很多“偶发错误”其实是上拉太弱导致上升沿过缓。第四看电平匹配。如果 PCA9422 的电源域和 STM32 的 I2C 引脚电平不一致需要加电平转换否则读到的数据会乱码。4.2 电源纹波超标的处理有段时间无线模块的发射距离明显不够排查到最后发现是 1.8V 电源轨纹波超标。改动主要有三处把降压电感的额定电流提高了一档避免大电流时电感饱和导致纹波变大在输出端增加了一颗 10µF 陶瓷电容同时保证它尽量靠近负载端把反馈走线从电感下方绕开。改完以后纹波从 60mV 降到了 20mV 以内问题解决。4.3 充电管理上的典型 Bug充电这块最开始有个问题插上 USB 后充电状态一直显示异常。后来发现是充电电流设得太大而 USB 输入端的限流保护被触发了。把充电电流从 800mA 降到 500mA 以后问题消失。还有个问题是电池电压采样不稳定最后确认是 PCB 上采样走线太靠近电感在地回路里出现了电压偏置调整走线位置后数据就稳定了。4.4 实测数据与优化记录项目优化前优化后待机电流35µA8.5µA无线发射时系统电流67mA61mA1.8V 纹波60mV18mV电池电量误差±20%±8%待机电流从 35µA 降到 8.5µA主要是把 LDO 通道彻底关断、I2C 总线释放、并且把 INT 引脚的中断配置成了仅在事件发生时唤醒避免每 10 秒就会被唤醒一次去轮询状态。电量误差减小是因为在软件里做了电压补偿并且过滤了瞬时负载变化引起的电压跌落。这几个问题排查下来我最大的体会是电源调试不能靠猜。每次改动只动一个变量改完以后用示波器或电流表记录数据前后对比比凭感觉试要高效得多。尤其是 PMIC 这种 I2C 配置的设备寄存器状态和硬件电路是绑在一起的错误的寄存器值会让硬件表现得很像一个“硬件故障”这时候一定要先回到寄存器层面验证配置。最后分享一个小技巧在做这类电源管理项目时板上一定预留一个独立的调试串口和一对 I2C 测试点。调试阶段把初始化过程、状态切换、中断触发都通过串口打印出来I2C 测试点用来夹逻辑分析仪探头很多看似玄学的问题抓到波形和日志以后基本都能定位到具体原因。这套 PCA9422 加 STM32F100ZE 的方案我后续在低功耗传感类产品上还会继续用整体来说是省心且可控的组合。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询