前一阵整理一套小型备用电源的主控板时遇到一个绕不开的问题两串磷酸铁锂电池出厂明明是配对的跑了不到三个月中间抽头两侧的电压差就跑到了 80mV 以上。如果放着不管充电时电压高的那节电芯会先触发过压保护整组电池的实际可用容量会越用越小。后来用 MP2642GR-Z 这颗主动均衡芯片配合 PIC18F45K42 单片机重新做了均衡控制才把这个问题基本压住。这套方案很适合储能系统、小型 UPS、太阳能直流备用电源这类两串电池场景本文就把硬件搭建、控制思路和调试过程完整拆开讲一讲。1. 两串电池为什么会失衡以及为什么必须主动处理1.1 失衡的根源容量、内阻与温度的相互放大两节电池串联工作时流过它们的电流完全相同。按说充进去、放出来的电荷量都一样为什么电压会越来越不一致问题在于“电量相同”不等于“状态相同”。电池的实际容量会因为制造公差、循环老化而出现差异内阻也会随温度和使用历史发生漂移。假设 B1 的实际容量只有 B2 的 95%那么在放电时同样的电流下 B1 的电量下降速度更快端电压掉得更快充电时 B1 又比 B2 更早到达充电上限。自放电率不一致也会在静置时逐渐拉开两者的荷电状态。温度的影响更加隐蔽散热条件差的电芯温度更高内阻更低反而更容易过充形成恶心循环。拿水桶来类比会更直观两个水桶并排放用同一根水管同时注水和放水但桶底裂缝大小不同、桶的直径也不同注入相同水量后水位必然一高一低。一个已经溢出来了另一个可能还没满。电池组里的“溢出”就是过充。1.2 不平衡带来的实际后果最直接的影响是整组电池的可用容量被最差的那节电池锁死。充电时只要有一节电芯到达电压上限充电器就必须停机另一节电芯即使还没充满也只能陪跑。放电时同样如此电压最低的电芯先触底整个系统便无法继续供电。长期过充会带来正极材料结构破坏、电解液氧化分解甚至析锂长期过放会造成负极铜箔溶解、容量不可逆衰减。对于备用电源来说设备长期挂在浮充状态静置时间远大于工作时间自放电差异会持续累积电压偏差如果不做均衡电池组寿命会明显缩短。1.3 被动均衡与主动均衡的取舍传统做法是给每节电芯并联一个放电电阻充电时把电压高的电芯多余电量以热量形式耗散掉也就是被动均衡。它电路简单、成本低但有两个明显缺点一是发热集中电池仓散热压力大二是只能“放掉”不能把能量转移给低电量电芯均衡效率不高放电和静置状态下基本无法工作。主动均衡则不同它通过功率变换电路把高电量电芯的能量搬运到低电量电芯能量没有被浪费发热也小得多。MP2642GR-Z 就是一颗专门做两节串联电池主动均衡的芯片再加上一颗 PIC18F45K42 做系统监控和策略控制就能实现一套比较完整的电池均衡系统。2. MP2642GR-Z 的工作原理与硬件搭建要点2.1 电感电荷搬运一次均衡周期里发生了什么MP2642GR-Z 的核心工作方式可以理解为电感电荷搬运。芯片内部集成了功率开关管外部只需要一颗储能电感就能在 B1 和 B2 之间双向转移电荷。如果 B1 电压比 B2 高芯片内部会让电感从 B1 侧储能再把储存的能量释放到 B2 侧。这个过程以一定频率反复进行每个周期搬运一小份电荷宏观上就形成了一股从 B1 流向 B2 的均衡电流。反过来如果 B2 电压高于 B1功率级就反向工作电感从 B2 汲取能量向 B1 释放。这种拓扑相当于一个双向 Buck-Boost 变换器芯片内部的开关管替代了分立方案里的 MOSFET驱动、逻辑控制、电压检测都集成在芯片内部外部电路非常简洁。均衡电流大小由电感量、开关频率和占空比共同决定芯片会通过内部协议限制最大电流防止电感失控饱和。2.2 围绕 MP2642GR-Z 的最小系统连接搭建最小系统时第一步要把两节串联电池的节点接到 MP2642 对应的检测端和功率端。典型接法是B1 正极接电池组正极B1 负极/B2 正极作为中间抽头B2 负极接电池组负极地。外部电感接在芯片的开关节点和中间抽头之间芯片的电源端和检测端分别跨接两个电芯。I2C 接口只需要两根线SDA 和 SCL 分别接 PIC18F45K42 的对应引脚。两条线都要接上拉电阻阻值一般取 2.2kΩ 到 4.7kΩ具体取决于总线电容和通信速率。芯片的 EN 使能引脚由单片机控制FAULT 开漏输出引脚接单片机的外部中断或者普通 IO用于上报异常。我比较坚持的一点是电池组的采样线要尽量短并且从电池端子独立引出不要在 PCB 上和其他功率走线共享。因为均衡电流会带来地电位偏移共享走线会污染电压检测结果影响均衡判断。2.3 电感、电容与 PCB 布局的实战选择电感是这套方案里最重要的磁性元件。电感量太小时均衡纹波电流大开关管应力高电感量太大均衡电流上不去。以 0.5A 级别的均衡电流为例4.7µH 到 22µH 都是常见取值但必须确认电感的饱和电流高于均衡电流峰值否则均衡电流一旦增大电感量会断崖式下跌芯片会误判甚至过流。我在样板上来回换过几次电感最后选了饱和电流 2A 以上、DCR 尽量小的一颗功率电感。DCR 太大会白损耗能量发热也会从芯片转移到电感上。电容选择上输入和输出端各放一颗低 ESR 陶瓷电容容量不需要太大几微法到二十几微法都可以靠近芯片引脚放置。PCB 布局方面开关节点是 di/dt 最大的地方走线必须短而粗尽量减少回路面积。不要把 I2C 线平行贴着开关节点走否则 SDA 上会看到明显的开关噪声。电池电压采样走线可以考虑在单片机侧加一组 RC 滤波时间常数大约 1ms 到 10ms不影响均衡判断速度但能滤掉不少开关纹波。3. PIC18F45K42 在系统里的三层职责3.1 选型逻辑为什么不是随便拿一颗 MCU 应付MP2642GR-Z 自己就能完成基本的功率级均衡那为什么还要加一颗 PIC18F45K42因为实际产品里需要的不只是“搬电”还需要系统级的判断和保护。PIC18F45K42 的集成外设在处理这类任务时非常顺手。它自带多路 IOC、I2C 主模式、ADC 模块、DAC 模块、窗口比较器等不需要额外加独立 ADC 或比较器芯片。单片机可以直接通过内部 5V 供电运行IO 电平与 MP2642 的逻辑电平匹配省掉了电平转换电路。另外这系列单片机的引脚映射功能很有用外部中断、I2C、定时器都可以分配到不同引脚画 PCB 时布线自由度更高。做均衡控制并不需要很强的算力关键是外设搭配合理、休眠功耗低、温度范围宽这些正是它擅长的事情。3.2 I2C 通信与寄存器读写示例MP2642 通过 I2C 接口把两个电芯的电压、芯片状态、故障标志交给单片机同时接收单片机的启动、停止、模式配置命令。单片机作为主设备在初始化阶段完成 I2C 外设配置速率建议先用 100kHz 跑通再视情况提升到 400kHz。#include xc.h #define MP2642_ADDR 0x60 // 实际地址以芯片手册为准 #define MP2642_REG_CTRL 0x00 #define MP2642_REG_VCELL1 0x02 #define MP2642_REG_VCELL2 0x04 #define MP2642_REG_STATUS 0x06 void i2c_write_reg(uint8_t reg, uint8_t val) { i2c_start(); i2c_write((MP2642_ADDR 1) | 0); i2c_write(reg); i2c_write(val); i2c_stop(); } uint8_t i2c_read_reg(uint8_t reg) { uint8_t val; i2c_start(); i2c_write((MP2642_ADDR 1) | 0); i2c_write(reg); i2c_restart(); i2c_write((MP2642_ADDR 1) | 1); val i2c_read(0); // 最后一个字节回 NACK i2c_stop(); return val; }这里特意把“读最后一个字节时回 NACK”写了出来因为这是 I2C 通信最常见的卡壳点。如果读时序不对单片机会一直收不到完整寄存器数据。3.3 模拟量采集与均衡使能控制I2C 只能拿到电芯电压和芯片状态系统温度、总包电压这些信息还是得靠单片机 ADC 采集。我在电池附近放了一个 NTC 热敏电阻通过分压网络接到 PIC18F45K42 的 ADC 引脚每隔几百毫秒读一次温度。温度超过 55°C 时禁止启动均衡超过 65°C 时强制关闭均衡。EN 引脚的控制逻辑也要注意细节。上电阶段需要先让单片机完成初始化、读一次电池电压确认没有过压故障后再把 EN 拉高。如果上电瞬间就拉高 EN芯片会在电压检测尚未稳定时开始工作容易产生一次不必要的大电流冲击。FAULT 引脚建议连接到单片机的外部中断引脚同时开启内部弱上拉。FAULT 一旦拉低单片机立即进入故障处理状态而不是等着下一次轮询才发现问题。测试中发现轮询间隔 500ms 时FAULT 导致的问题往往会延迟一个周期才被处理对于电池保护来说这个时间太长了。4. 均衡策略与状态机别让电压搬运器傻跑4.1 何时均衡、何时停止、何时强制禁止均衡不是电压差超过 0V 就一直开着那样反而会引入不必要的循环损耗。实际策略需要设定开启阈值、关闭阈值和禁止条件。我用的参数供参考电芯静置电压读取压差大于 20mV 时开启均衡压差降到 10mV 以下时停止充电过程中允许均衡但均衡电流要限制得比充电电流小放电状态下只在轻载时均衡重载时关闭。禁止条件包括总电压超过过压保护点、单节电压超过 3.65V磷酸铁锂上限、温度越限、均衡连续运行超过设定时间。设置回差的目的是避免均衡控制频繁启停。如果没有回差压差在阈值附近抖动时芯片会反复启动和停止每次启动都会带来一次电感电流冲击长期看对器件寿命不利。4.2 状态机划分与迁移条件软件结构拆成几个状态待机、电压检查、均衡中、故障、故障锁存。状态转移逻辑不复杂但必须把所有异常路径都处理干净。typedef enum { ST_IDLE, ST_VOLTAGE_CHECK, ST_BALANCING, ST_FAULT, ST_FAULT_LATCH } sys_state_t; sys_state_t current_state ST_IDLE; void state_machine(void) { uint16_t v1 read_cell_voltage(MP2642_REG_VCELL1); uint16_t v2 read_cell_voltage(MP2642_REG_VCELL2); int16_t diff (int16_t)(v1 - v2); switch (current_state) { case ST_IDLE: if (voltage_valid(v1, v2)) { current_state ST_VOLTAGE_CHECK; } break; case ST_VOLTAGE_CHECK: if (abs(diff) BAL_ON_MV) { enable_balancer(); current_state ST_BALANCING; } else { current_state ST_IDLE; } break; case ST_BALANCING: if (fault_flag) { disable_balancer(); current_state ST_FAULT; } else if (abs(diff) BAL_OFF_MV) { disable_balancer(); current_state ST_IDLE; } break; case ST_FAULT: fault_flag_reset(); current_state ST_FAULT_LATCH; break; case ST_FAULT_LATCH: // 等待人工复位或断电重启后才可恢复 break; } }故障锁存状态是必须的。一旦发生过压、过温这类危险故障系统不能自己悄悄恢复正常否则故障源还在反复进入故障状态反而会让 MOSFET 和电感承受更大压力。维护人员通过按键或者上位机指令才能清除锁存这样更安全。4.3 故障保护与 I2C 看门狗芯片自带的 FAULT 引脚只能反映芯片内部的异常系统级的过压、欠压、过温还需要单片机结合 ADC 采样综合判断。最常见的是充电状态下的过压风险如果 B1 电压已经接近 3.6VB2 还在 3.4V这时开启均衡虽然能拉低 B1但如果充电电流远大于均衡电流B1 的电压依然会继续上升。因此充电时的策略是检测到任意单节电压超过 3.55V先把充电回路断开再做均衡而不是边充边搬。I2C 通信也可能失效。MP2642 万一内部总线卡住单片机必须能发现。我在主循环里加了一个“通信看门狗”如果连续 5 次读取寄存器都没有收到有效应答就判定通信异常关闭均衡并进入故障锁存。这个逻辑成本很低但能避免单片机因 I2C 卡死而失去对均衡器的控制。5. 实测定标与调试中踩过的坑5.1 测试平台与数据记录搭建了一套简易测试台两节磷酸铁锂电池实际容量 6Ah 左右先故意放电制造约 80mV 的压差然后连接均衡板静置状态下观察电压变化。测试过程中用万用表定期记录中间抽头两侧电压同时读单片机内部寄存器里的均衡状态。一组比较典型的数据时间(分钟)B1 电压(V)B2 电压(V)压差(mV)均衡状态03.3123.23082未启动13.3103.23575均衡中53.3053.24956均衡中153.2933.27023均衡中253.2873.2789均衡停止均衡电流大约 0.5A从 82mV 压差收敛到 10mV 以内花费了二十多分钟。对备用电源场景来说这个速度完全可以接受毕竟设备大多数时间都在静置并不赶时间。5.2 三个高频问题I2C 波形、SW 节点振铃、均衡电流偏小第一个遇到的坑是 I2C 通信时好时坏。用示波器看 SDA 波形上升沿很缓像是被电容拖住了。排查下来是上拉电阻取了 10kΩ总线电容又偏高导致边沿不达标。把上拉电阻换成 2.2kΩ并且把 I2C 连线缩短到 10cm 以内问题消失。第二个问题是开关节点 SW 的电压振铃。均衡电流切换到续流阶段时SW 节点会看到明显的高频阻尼振荡振铃峰值接近电池电压的两倍。处理方法是加了一个 RC 吸收电路电阻 10Ω、电容 1nF放在开关节点对地之间振铃明显收住。这也是电源设计里的老办法虽然会损耗一点效率但换来的是更低的 EMI 风险。第三个问题比较隐蔽均衡电流比理论值小了不少。检查发现我用的电感额定电流其实标的是 1.5A 峰值但均衡电流波动峰值已经接近电感饱和临界点电感量下降导致电流上不去。换成饱和电流 2.5A 以上的电感后均衡电流恢复正常。选电感时不能只看平均电流还要看峰值电流和纹波电流叠加后的最大值。5.3 从“能均衡”到“可靠均衡”的改进记录最初版本只在压差超过阈值时启动均衡压差回来就停止。实测过程中发现两个问题一是电池从放电状态进入静置后电压会有一个缓慢的回弹过程如果立刻做均衡判断很容易被这个动态过程误导二是均衡停止后电池电压仍然会缓慢变化可能出现刚停止又满足启动条件的情况。改进措施是引入“稳定等待”逻辑进入静置状态后先等待 5 分钟连续读取三次电压每次间隔 1 秒确认压差方向稳定后再决定是否开启均衡。停止均衡时也一样确认压差连续 30 秒低于关闭阈值才真正关断。这样虽然少了一些均衡时间但避免了无效启停和误动作系统整体稳定性明显提升。另外还加了一条“均衡超时保护”无论压差是否恢复到目标范围单次均衡最多持续 60 分钟到点必须停止并重新评估。这是为了防止某些极端情况下均衡一直无法收敛芯片长时间满载工作带来发热风险。事后复盘这条超时保护在后期测试中确实多次派上用场至少三次避免了故障状态下的持续搬运。最后分享一个我调试这套均衡系统时的习惯永远不要让均衡器在单片机完全失控的情况下工作。每次修改软件后先跑一遍故障注入人为模拟过压、温度异常、I2C 断开确认系统都能在几百毫秒内关闭均衡并进入锁存状态再去做长期均衡测试。电池系统的可靠性往往不是来自均衡效率而是来自边界条件下的自我保护能力。