做 BMS 相关开发的朋友,对“串联电池不均衡”这六个字估计都有切身体会。我去年推进一个野外通信设备的备用电源项目时,电池组就是最简单的两串结构:两节磷酸铁锂电芯,标称 6.4V,容量 10Ah。本来以为两串电池电压直接测、故障直接判,很简单,结果跑了几十个循环之后,单节电芯压差能拉到 400mV 以上,充电末端有一节先满、另一节还差一大截,系统被迫限流甚至停机。后来把电池拆下来逐节测量,才发现不均衡带来的连锁问题几乎让整块电源板的前端保护设计全部白做。
这个项目最终落在以 MP2642GR-Z 均衡芯片为核心、PIC18F87J11 单片机做上层控制的主动均衡方案上。整篇文章就是这套系统的完整设计复盘,包括器件选型逻辑、采样驱动电路、均衡策略、固件代码,以及调试中踩过的具体坑。如果你正在做 2S 储能或者备用电源,又不想用一颗全集成 BMS 芯片把逻辑全部锁死,这套“均衡芯片 + 通用 MCU”的组合会很对胃口。
1. 项目背景:一台被单节过压逼出来的均衡改造
先说这个备用电源的具体场景。设备放在野外,主供电来自太阳能板,电池组作为阴雨天和夜间的后备能量来源。电池组是两串磷酸铁锂,标称 6.4V,实际工作电压范围大概在 5.0V 到 7.2V。负载峰值电流不高,大约 2A 到 3A,平时多数时间处于浮充或者小电流放电状态。
这种工况最容易暴露串联电池不均衡的问题。浮充状态下,电压较高的电芯会一直承受偏高的电压,加速正极材料结构老化和电解液分解;电压较低的那节则长期处于“吃不饱”状态,容量不断衰减。两者互相叠加,日积月累就是恶性循环。我们项目里那组电池大约循环了 60 次左右,充电末端电压差就从出厂时的 10mV 涨到了 300mV 以上,保护板因为单节过压频繁切断充电,系统可用容量差不多打了七折。
我一开始的应对方案很简单粗暴:每次充满之后,手动用电阻对高电压那节电芯放电,把电压拉平。但这在量产产品里完全不可行,于是老老实实把均衡电路做进系统。当时手里正好有 MP2642GR-Z 样片,它的定位就是串联电池主动均衡控制,内部集成了功率开关和驱动逻辑,外部只要很少的器件就能搭建电荷转移回路。控制端我选了 PIC18F87J11,这枚 8 位单片机在项目里承担电压采集、状态判断、均衡时序控制、故障保护以及对外通信,外设资源足够,开发难度也可控。
这套方案的关键思路是:均衡芯片负责“搬运电荷”这个力气活,MCU 负责“什么时候搬、搬多少”这个脑力活。相比全集成 BMS 芯片,这种分离式设计给了算法足够的自由度,我可以根据磷酸铁锂的充放电特性反复调整均衡策略,不用被芯片内部固定的逻辑框死。
2. 方案选型:为什么是均衡芯片加通用 MCU
2.1 均衡拓扑三选一
两串电池均衡,常规做法有三种:电阻被动均衡、飞渡电容主动均衡、电感主动均衡。电阻均衡最简单,高电压那节电芯通过电阻放电,把多余能量变成热量散掉。但它的效率是负数,均衡电流也做不大,1A 以上的被动均衡在散热上就很难处理。飞渡电容均衡用开关阵列把电容轮流接入两节电芯,结构简单,但电荷转移效率低,均衡速度慢,适合电流要求不高的场合。
电感均衡则是通过升降压变换把电荷从高电压电芯搬到低电压电芯,能量几乎不损失,均衡电流可以做到几安培,是最适合储能和备用电源的方案。MP2642GR-Z 走的就是这条路线。它内部集成了一组功率开关和对应的驱动电路,外部配一个功率电感和采样电阻,就构成了一个完整的双向升降压均衡器。芯片本身负责开关管的时序控制、电流检测和部分保护,MCU 只负责决策和监控,分工非常干净。
2.2 MP2642GR-Z 在系统里扮演什么角色
从应用角度理解 MP2642GR-Z,可以把它看成一个受控的电荷搬运模块。它有两个功率端口,分别接第一节电芯的正极和两节电芯的串联中点,还有一个公共端接电池组负极。芯片内部根据控制信号决定功率流向:要么把电荷从第一节电芯抽出来灌进第二节,要么反过来把第二节电芯的能量送回第一节。
实际电路里,芯片外部那颗电感是能量中转站。以“从 Cell1 向 Cell2 转移电荷”为例,第一阶段,内部开关把 Cell1 接到电感两端,电感电流线性上升,完成储能;第二阶段,开关切换,电感电流通过另一组开关续流到 Cell2,电荷就完成了搬运。芯片内部带电流采样放大器,均衡电流的大小可以通过外部采样电阻设定,MCU 读取电流反馈值后还可以做闭环调节。这个特性对磷酸铁锂这种平台电压区特别窄的电芯很重要,因为电压差小,均衡电流天然就小,需要靠控制策略来保证均衡效果。
2.3 PIC18F87J11 的角色定位
PIC18F87J11 在系统里是绝对的控制核心。这枚单片机有足够多的 ADC 通道,可以覆盖两节电芯电压、电池组总电压、采样电阻两端电压、NTC 温度等多路模拟量采集;UART 和 SPI 接口则用来和上位机或显示模块通信。我用它实现了整个均衡策略的状态机,包括充电状态、放电状态、静态均衡状态、故障保护状态之间的切换。
选择这颗单片机还有一个实际原因:工作温度范围宽,长期野外运行可靠性有保障。备用电源往往放在机柜、铁皮箱甚至直接挂在户外杆塔上,夏天的内部温度可以到 60 度以上,冬天的低温也可能到零下,MCU 在这个环境下的稳定性比性能数字更重要。
2.4 系统信号流与接口定义
整套系统的信号走向可以用一张表说清楚:
| 信号方向 | 起点 | 终点 | 接口/通道 | 用途 |
|---|---|---|---|---|
| 模拟输入 | Cell1 正极 | PIC18F87J11 ADC | AN0 | 第一节电芯电压采样 |
| 模拟输入 | Cell1 负极/串联中点 | PIC18F87J11 ADC | AN1 | 第二节电芯电压采样参考 |
| 模拟输入 | 采样电阻两端 | PIC18F87J11 ADC | AN2 | 均衡电流反馈 |
| 模拟输入 | 电池组外壳/散热片 NTC | PIC18F87J11 ADC | AN3 | 温度监测 |
| 数字输出 | PIC18F87J11 | MP2642GR-Z 使能引脚 | GPIO | 均衡功能开关 |
| 数字输出 | PIC18F87J11 | MP2642GR-Z 方向引脚 | GPIO | 电荷转移方向 |
| 数字输出 | PIC18F87J11 | 均衡 PWM 输出 | CCP1 | 均衡电流大小调节 |
| 数字输出 | PIC18F87J11 | 指示灯/LED | GPIO | 状态指示 |
| 双向 | PIC18F87J11 | 上位机 | UART | 状态上报与参数配置 |
这样的接口划分保留了最大的调试灵活性。前期验证阶段,我会直接在调试器里改 PWM 占空比来观察均衡电流变化;量产阶段,还可以保留串口指令通道,通过上位机远程调整均衡阈值,不需要改动硬件。
3. 硬件电路设计要点
3.1 电压采样链路与精度预算
均衡控制的前提是电压测量必须准确。两串电芯的电压采样,第一反应是用电阻分压直接进 ADC,但这里面有个问题:PIC18F87J11 的 ADC 参考电压是 3.3V,而满充状态下单节电芯电压最高 3.65V,已经超出参考范围,必须先把电压按比例缩小再采集。
我用的是精密电阻分压加射极跟随器的结构。分压比例取 2:1,也就是 ADC 输入电压等于实际电压的一半,这样满充 3.65V 对应 ADC 输入 1.825V,留出了足够的头部空间。分压电阻用 0.1% 精度的金属膜电阻,温度系数选 25ppm/°C 或者更好的规格。射极跟随器用的是轨到轨输出运算放大器,输入阻抗极高,可以避免 ADC 采样瞬间从分压网络抽取电流导致的分压点电压跌落。
这里有一个很容易被忽略的细节:分压电阻的阻值不能选太大,否则运放输入偏置电流会在分压电阻上产生额外的压降误差。我实测过,如果用 1MΩ 级别的分压电阻,普通运放几十纳安的输入偏置电流就能带来 20mV 到 30mV 的误差,这对均衡控制来说是不可接受的。最终选择 10kΩ:10kΩ 的组合,再将运放输入偏置电流控制在纳安级别,整体采样误差可以压到 ±5mV 以内。
3.2 均衡功率级与驱动接口
MP2642GR-Z 的功率部分由内部开关和外部电感组成。电感选型是这里最关键的一步。电感值决定纹波电流和峰值电流能力:电感太小,开关管峰值电流过大,容易触发芯片内部过流保护;电感太大,电流上升慢,均衡速度受影响。
针对这个项目,均衡目标电流设定为 1.5A,开关频率按芯片 PWM 输入基准定为 500kHz。由公式 L = (Vin × D) / (f × ΔI) 估算,Vin 取电芯电压 3.3V,D 取 0.5,ΔI 取纹波电流 0.3A,算出来大约是 11μH。我选了 10μH 的功率电感,额定饱和电流 3A 以上,直流电阻控制在 50mΩ 以内。实测 1.5A 均衡电流下,电感表面温升在 15 度左右,完全在可接受范围。
采样电阻放在芯片的电流检测引脚之间,阻值决定电流反馈系数。数据手册给的参考范围是 5mΩ 到 20mΩ,我选了 10mΩ,这样 1.5A 电流对应的反馈电压是 15mV,既在芯片检测精度范围内,又不会因为阻值过大消耗太多功率。采样电阻必须用四端开尔文接法,采样线直接接到电阻两端,不能经过 PCB 走线,否则走线电阻会直接把反馈信号吃掉。
3.3 温度采样与电流反馈
温度采样用 10kΩ NTC 热敏电阻贴在电池组表面,配合一个 10kΩ 精密电阻组成分压电路进 ADC。NTC 的 B 值取 3380,采样电压通过查表换算成温度。这块电路没啥花活,但要注意 NTC 和分压电阻的供电一定要用干净的电平,不能从开关节点附近取,否则 ADC 读数噪声会非常大。我最初就是从 3.3V 稳压输出取的电,但因为 PCB 布局上稳压输出离功率电感太近,导致温度读数在均衡开启时跳动了差不多 3 度,后来把供电走线重新绕开才解决。
电流反馈除了给 MCU 做闭环控制,还有一个额外用途:判断均衡是否真的在工作。程序里会持续比较设定电流和实际电流,如果两者偏差持续超过 20%,就认为均衡回路异常,立刻关闭均衡并上报故障。这比单纯检测电压是否拉平更可靠,因为电压变化本身很慢,电流反馈的响应要快得多。
4. 固件设计与均衡策略实现
4.1 软件状态机设计
固件整体按状态机组织,状态定义如下:
typedef enum { SYS_INIT, // 上电初始化,自检 SYS_IDLE, // 待机,不均衡 SYS_CHARGING, // 充电中,均衡常开 SYS_BALANCING, // 静态均衡模式 SYS_FAULT // 故障锁定 } sys_state_t;上电后先进入 SYS_INIT,完成 ADC 初始化和自检,确认两节电芯电压都在安全范围内。然后进入 SYS_IDLE,此时只做电压监测,不启动均衡。一旦检测到充电电流,系统进入 SYS_CHARGING,均衡功能全程打开。如果系统处于浮充状态且无充电电流,则进入 SYS_BALANCING 模式进行静态均衡。任何时候触发保护条件,状态机立即转入 SYS_FAULT 并锁存,需要断电重新上电才能恢复。
这套状态机的好处是把“充电均衡”和“静态均衡”分开处理。充电时电芯极化内阻大,电压差并不完全代表 SOC 差,均衡策略需要更灵敏;静态时电压接近开路电压,对 SOC 差的表征更准确,但为了避免过均衡,需要加回滞和定时限制。
4.2 均衡算法:什么时候加、什么时候停
均衡算法的核心逻辑并不复杂:计算两节电芯电压差,超过阈值就启动均衡,低于回滞阈值就停止。真正的讲究在于阈值的选取和动态调整。
对于磷酸铁锂电芯,电压平台区特别平,3.30V 和 3.35V 之间的电压差可能对应 20% 以上的 SOC 差。所以不能照搬三元锂的均衡策略。我把均衡启动阈值定在 30mV,回滞 10mV。也就是说,电压差大于 30mV 启动均衡,等于或小于 10mV 停止。30mV 这个数值是经验值,既能保证不至于因为噪声频繁启停,又能覆盖磷酸铁锂电池在平台区的 SOC 偏差。
辅助判断条件有三个。第一,均衡只允许在电芯电压高于 3.0V 时进行,低于这个值说明电池已接近放空,此时均衡意义不大且可能加剧过放。第二,均衡必须持续运行至少 30 秒才能停止,防止电压因为负载突变瞬间拉平导致误判。第三,静态均衡模式下,单次均衡时间不超过 2 小时,防止过均衡把本来电压低的电芯反向抬高。
算法里还加了一个动态调节:如果电压差连续三个采集周期都在增大,说明电池自放电差异较大,需要把均衡电流调大一档;如果电压差连续稳定变小,就把电流回调到维持水平。这个功能依赖 PWM 调节均衡电流的能力,也是选这颗芯片时考虑过的点。
4.3 核心代码片段
ADC 采样采用连续三次采样取平均的方式,每次间隔 10ms,有效滤除工频干扰。核心电压采集逻辑如下:
uint16_t read_cell_voltage_mv(uint8_t ch) { uint32_t sum = 0; uint16_t i; for (i = 0; i < 8; i++) { ADC_SetChannel(ch); ADC_StartConversion(); while (!ADC_IsConversionDone()); sum += ADC_GetConversionResult(); __delay_ms(2); } sum = (sum + 4) / 8; // 8次平均 // 12位ADC,参考3.3V,分压比2:1 // mv = adc * 3300 / 4096 * 2 uint32_t mv = (sum * 3300UL * 2UL + 2048UL) / 4096UL; return (uint16_t)mv; }均衡控制主逻辑在主循环里调用,节拍为 500ms:
int16_t delta_mv = cell1_mv - cell2_mv; // 有符号 uint16_t abs_delta = (delta_mv > 0) ? delta_mv : -delta_mv; if (abs_delta > BALANCE_START_MV) { if (delta_mv > 0) { // Cell1 电压高,方向=向Cell2转移 BAL_DIR_PIN = 0; } else { // Cell2 电压高,方向=向Cell1转移 BAL_DIR_PIN = 1; } BAL_EN_PIN = 1; // 使能均衡 BAL_PWM_DUTY = 60; // 初始占空比60% balance_timer = 0; } else if (abs_delta <= BALANCE_STOP_MV) { BAL_EN_PIN = 0; // 停止均衡 BAL_PWM_DUTY = 0; }PWM 占空比调节通过闭环方式实现。每 500ms 读取一次电流反馈值,与目标电流比较,用简单的增量式 PI 调节器修正占空比。
int16_t current_error = target_current - actual_current; integral += current_error; if (integral > 100) integral = 100; if (integral < -100) integral = -100; int32_t duty = 50 + current_error + integral * 0.2; if (duty < 10) duty = 10; if (duty > 90) duty = 90;这个闭环调节在电感参数偏差、电芯内阻变化的情况下依然能保持稳定的均衡电流,实测效果比固定占空比好很多。
4.4 保护逻辑与异常处理
保护逻辑是均衡系统的最后一道防线。我实现了四重保护:单节过压保护、欠压保护、过温保护、均衡回路异常保护。
单节过压保护阈值为 3.65V,持续 500ms 触发,触发后关闭均衡并断开充电回路。欠压保护阈值为 2.5V,触发后关闭均衡,同时让系统进入低功耗待机。过温保护分两档:55 度降额运行,均衡电流减半;65 度完全关闭均衡。
均衡回路异常保护是我花最多时间调试的一个点。最初只通过电压变化判断均衡是否有效,但电压变化时间尺度太长,往往要几分钟才能看出问题。后来加入了电流反馈判断,一旦检测到“使能均衡但电流反馈为零”或“电流反馈超过设定值 20%”持续 1 秒,立即关闭均衡。这个逻辑救了我好几次,帮我快速发现了几次电感虚焊和采样电阻焊接不良的问题。
5. PCB 布局与调试实录
5.1 布局细节:功率地、模拟地与采样走线
这套系统的 PCB 布局,最关键的是把功率回路和模拟采样回路分开。均衡功率电流达到 1.5A,开关频率 500kHz,如果采样走线贴近功率回路,ADC 读数会带上明显的开关尖峰噪声。我的布局原则是:功率电感、开关管、采样电阻这些构成一个最小功率环,面积越小越好;ADC 采样走线走独立的模拟地,从采样点单独拉线到运放输入,不在中途与其他地网络汇合。
采样电阻的四端接法必须严格执行。采样线从电阻两端分别引出,走差分线对到运放,和功率电流的走线完全分开。我见过不少工程师图省事,直接在高电流走线上引出采样点,结果纹波电压高达几千伏,完全没法用。
MP2642GR-Z 的 PWM 输入引脚和使能引脚上各加了一个 100Ω 串联电阻,一方面限制 MCU 引脚驱动时的边沿速率,减少对外辐射;另一方面在芯片意外损坏时保护 MCU 的 GPIO 引脚。这个设计在后面一次误接电源的事故里真的保护了单片机,芯片烧了,但 MCU 完好无损,重新换颗芯片就能跑。
5.2 实测波形与调试问题
第一次给整块板子上电时,均衡电流只有预期的四分之一。用示波器测电感开关节点波形,发现占空比明显不对,检查固件发现 PWM 初始化时把定时器周期寄存器写错了,导致输出频率是预期的两倍,电感在较高的频率下损耗增大,电流自然也上不去。修正寄存器配置后,波形恢复正常。
另一个典型问题是均衡开启瞬间系统电压出现跌落。原因是启动时 PWM 占空比给得太大,瞬时电流超过电芯能承受的范围。解决方式是把启动占空比从 25% 起步,每 100ms 增加 5%,用一个软启动斜坡把电流慢慢拉上去。调整后,均衡启动对系统电压的扰动从 150mV 降到 20mV 以内。
还遇到过 ADC 读数周期性跳变的情况。排查了很久,最后发现是 NTC 采样线的供电受到 PWM 开关噪声干扰。因为这些 NTC 分压电阻直接接到了 3.3V 稳压输出,而稳压输出的 PCB 走线又和功率电感共用了很长一段,开关噪声通过公共阻抗耦合进了采样链路。解决方法是把模拟部分的 3.3V 供电单独引一条线,并在靠近 MCU 端加一颗 10μF 电容和磁珠做滤波。
6. 常见问题排查与实测数据
6.1 快速排查速查表
| 现象 | 可能原因 | 排查与处理 |
|---|---|---|
| 均衡电流为零,芯片无动作 | 使能引脚未拉高 / PWM 未输出 | 用示波器查使能电平和 PWM 波形 |
| 均衡电流只有设定值一半 | 电感值偏大或饱和电流不足 | 用 LCR 表实测电感量,检查是否饱和 |
| 均衡电流波动大 | 电流反馈采样受开关噪声干扰 | 检查采样电阻四端接法和走线布局 |
| ADC 电压读数周期性跳变 | 模拟供电受开关噪声影响 | 将模拟电源单独走线并加磁珠滤波 |
| 均衡开启瞬间系统电压跌落 | 启动占空比过大 / 软启动缺失 | 增加 PWM 软启动斜坡 |
| 电压差长时间不收敛 | 均衡阈值设置过小或电芯自放电差异过大 | 适当调高阈值,检查电芯健康状态 |
| 均衡芯片发烫异常 | 电感选型不当或开关频率设置错误 | 检查电感 DCR、饱和电流和开关频率 |
6.2 实测均衡效果
以一组已经拉开 300mV 电压差的两节磷酸铁锂电芯做测试,目标均衡电流 1.5A,启动阈值 30mV。均衡过程前 30 分钟,电压差从 300mV 快速降到 80mV,之后进入平台区,电压差下降速度明显放缓。整个均衡持续了约 1 小时 40 分钟,电压差稳定在 11mV,达到停止条件。均衡期间电芯表面温度最高 42 度,电感表面温度约 55 度,整体温升在可接受范围。
静态均衡模式下,系统浮充三天后两组电芯的电压差一直稳定在 15mV 以内,没有出现反复跳变。相比改造前跑 60 个循环就拉开 300mV 的情况,均衡系统介入后,电池组在这个备用电源应用里的循环寿命和可用容量都有明显提升。
6.3 把方案扩展到更多串联电池的套路
这套“均衡芯片 + MCU”的方案天然支持模块化扩展。如果需要做四串、六串甚至更多串联的电池组,可以考虑以两串为一个均衡模块,通过 MCU 的多个 PWM 通道分别控制各模块,或者用多片 MCU 通过 UART 组网,由上位主控统一调度。芯片的数据手册一般都会给出扩展级联的参考电路,按照模块化思路堆叠即可。需要注意的地方是均衡模块之间的地电位不同,通信必须做隔离或者电平转换,不能直接把不同电池组的控制信号连在一起。
7. 最后的经验之谈
整套系统从设计到量产验证,前后花了两轮迭代。第一轮问题主要集中在硬件布局和采样干扰上,第二轮集中在算法调试上。如果让我重新做一次,有几个决策会直接沿用:用主动均衡而不是被动均衡,这个选择在长期充放电循环里节省的容量损失非常可观;用 MCU 做上层控制而不是全交给均衡芯片,这让后期调整策略的成本低了很多;在均衡回路中加入电流反馈,这个设计让异常定位速度快了一个数量级。
再分享一个小技巧:均衡阈值和回滞参数不要写死在代码里,而是存到单片机的数据 EEPROM 里,通过串口指令随时修改。因为电芯的老化程度、温度环境不同,最优参数会变化。量产之后如果发现某些批次电池特性有差异,直接远程调整参数就好,不需要重新烧录固件。这一步在开发阶段省下来的时间不多,但在维护阶段是真正的大救星。