1. 从两个串联电芯的电压差说起:为什么被动均衡在储能场景里依然能打
储能和备用电源系统里,两串电芯的电压不一致是个绕不开的问题。你拿万用表一测,可能一节3.7V,另一节3.5V,看起来只差0.2V,但放到整组充放电循环里,容量小的那节会先到过充保护点,容量大的那节还没吃饱,整组可用容量就被短板效应拖死了。时间一长,落后那节还会加速老化,整组电池的循环寿命直接打七折。
解决这个问题的思路分两派:被动均衡和主动均衡。主动均衡用变压器或者电容把电量从高电压电芯搬到低电压电芯,效率高、发热小,但电路复杂、成本高,一堆MOS管和驱动电路堆上去,PCB面积和BOM成本都压不住。被动均衡就简单粗暴——给电压高的那节并一个电阻,把多余的电量以热量形式放掉,等两节电压拉平了再继续充。效率是低了点,但胜在可靠、便宜、控制逻辑简单,特别适合两串这种小规模电池组。
我这次做的方案,核心就是用MP2642GR-Z这颗模拟前端芯片配合PIC18F85K90单片机,搭一套两串电芯的被动均衡系统。MP2642GR-Z负责高精度采集每节电芯的电压,PIC18F85K90负责跑均衡策略、控制均衡开关、管理充放电状态。整套方案的目标很明确:在备用电源这种长期浮充、偶尔放电的场景里,用最低的成本把两节电芯的电压差控制在±20mV以内,保证整组电池能撑过设计寿命。
为什么选这两颗芯片?先说MP2642GR-Z。它是一颗专门针对多串电池管理的模拟前端,内置高精度ADC,电压采集精度能到±0.5%以内,对于两串应用来说,它的通道数有富余,但精度和集成度比用分立运放搭差分采样电路强太多了。分立方案你要考虑电阻匹配、温漂、共模抑制,调起来头大。MP2642GR-Z直接通过I2C或者SPI把电压值读出来,省事。再说PIC18F85K90,这颗8位单片机在工业控制领域用了很多年,抗干扰能力强,内置CAN控制器和LIN收发器,对于备用电源系统里常见的通信需求很友好。它的I/O口驱动能力也够,直接驱动均衡MOS管或者继电器没问题。
这套组合的定位很清晰:不是给电动汽车那种大电流主动均衡用的,而是给通信基站备用电源、UPS小电池组、太阳能储能小系统这类场景用的。这些场景的共同特点是:电池组串数少、均衡电流要求不高(几十毫安到几百毫安)、对成本敏感、对可靠性要求高。被动均衡在这类场景里不是妥协,而是最优解。
提示:被动均衡的均衡电流一般取电池容量的1%到3%。比如两节2000mAh的电芯,均衡电流设在20mA到60mA之间比较合适。电流太小均衡时间太长,电流太大电阻发热严重,PCB布局要留够散热铜皮。
2. MP2642GR-Z的电压采集通道配置与PIC18F85K90的接口设计
2.1 MP2642GR-Z的采样原理和寄存器配置
MP2642GR-Z内部有一个多路复用的ADC架构,每个电芯的电压通过外部电阻分压或者直接接入采样引脚。对于两串应用,电芯正极分别接到芯片的CELL1和CELL2引脚,芯片内部通过差分采样得到每节电芯的端电压。这里有个细节要注意:MP2642GR-Z的采样输入端有内部开关电容网络,外部需要加RC滤波,截止频率建议设在1kHz左右,用来滤掉开关噪声和工频干扰。
配置寄存器的时候,采样速率和分辨率要权衡。MP2642GR-Z支持多种采样模式,我一般用连续采样模式,每100ms读一次电压值。这个速率对于均衡控制来说足够了,因为电芯电压的变化是缓慢的,没必要追求高速采样。分辨率方面,芯片内部是14位ADC,但实际有效位数受噪声影响,实测下来12位有效精度是稳的。换算成电压,3.7V量程下分辨率大约是0.9mV,完全满足±20mV的均衡目标。
寄存器配置的关键步骤:
- 上电后先写配置寄存器,设置采样通道为CELL1和CELL2交替采样。
- 设置ADC转换时间为默认值,不要随意缩短,否则精度会下降。
- 使能内部参考电压,禁用外部参考,减少外部元件。
- 配置报警阈值寄存器,当某节电芯电压超过4.25V或者低于2.8V时触发中断。
这里有个坑:MP2642GR-Z的I2C地址是固定的,如果系统里还有其他I2C设备,要确保地址不冲突。我遇到过因为地址冲突导致读出来的电压值全是0xFF的情况,排查了半天才发现是另一个传感器占了同一个地址。
2.2 PIC18F85K90的I2C通信与中断处理
PIC18F85K90作为主控,通过I2C总线读取MP2642GR-Z的电压数据。PIC18F85K90的MSSP模块支持I2C主从模式,配置成主模式后,时钟频率设在100kHz比较稳妥。虽然MP2642GR-Z支持400kHz,但备用电源系统里PCB走线可能比较长,100kHz的抗干扰余量更大。
中断处理是这套系统的关键。MP2642GR-Z的报警中断引脚接到PIC18F85K90的外部中断INT0上,当电芯电压越限时,单片机立即进入中断服务程序,读取状态寄存器判断是哪节电芯出了问题,然后执行相应的保护动作。比如某节电芯过压,就立即打开对应的均衡开关,同时如果电压超过4.3V,还要切断充电回路。
I2C读取的代码逻辑大概是这样:
// 读取MP2642GR-Z的CELL1电压寄存器 uint16_t read_cell1_voltage(void) { uint8_t buf[2]; i2c_start(); i2c_write(MP2642_ADDR << 1); // 写地址 i2c_write(CELL1_VOLTAGE_REG); // 寄存器地址 i2c_restart(); i2c_write((MP2642_ADDR << 1) | 1); // 读地址 buf[0] = i2c_read_ack(); buf[1] = i2c_read_nack(); i2c_stop(); return (buf[0] << 8) | buf[1]; }读回来的原始值需要换算成实际电压。MP2642GR-Z的电压换算公式在数据手册里有,一般是V = raw * Vref / 16384,Vref是内部参考电压,典型值2.048V。但实际用的时候,因为分压电阻有误差,最好用高精度万用表实测几组数据,做一次线性拟合,把增益和偏移校准一下。我实测下来,校准后的精度能到±3mV以内。
2.3 均衡开关的驱动电路设计
均衡开关我用的是N沟道MOS管,型号选的是低导通电阻的逻辑电平MOS,比如AO3400这类。PIC18F85K90的I/O口输出高电平是3.3V或者5V(取决于供电),直接驱动MOS管栅极没问题。但要注意,MOS管源极接在电芯正极上,栅极驱动电压是相对于源极的,所以不能用单片机I/O直接驱动高边开关。
我的做法是用一个NPN三极管做电平转换,单片机I/O控制三极管基极,三极管集电极接MOS管栅极,发射极接地。这样当单片机输出高电平时,三极管导通,MOS管栅极被拉低,MOS管关断;单片机输出低电平时,三极管截止,栅极通过上拉电阻接到电芯正极,MOS管导通。这个电路简单可靠,成本也就几分钱。
均衡电阻的选择要算功率。假设均衡电流设50mA,电芯电压4.2V,电阻值就是4.2V / 50mA = 84Ω,取标准值82Ω。电阻功率是4.2V * 50mA = 0.21W,选0805封装的0.125W电阻不够,要选1206封装的0.25W或者两个0805并联。我一般会留一倍余量,用两个1206电阻并联,每个承担0.1W左右,温升控制在20°C以内。
注意:均衡电阻要靠近MOS管放置,走线尽量短而粗,减少寄生电感。如果PCB空间允许,在电阻下面铺一块铜皮帮助散热,但铜皮不要连接到其他网络,避免短路。
3. 均衡策略的代码实现:从电压比较到状态机
3.1 电压比较的阈值和迟滞设计
均衡策略的核心逻辑很简单:如果CELL1电压比CELL2高超过阈值,就打开CELL1的均衡开关;反之打开CELL2的。但实际写代码的时候,不能简单用if (v1 > v2 + 20mV)来判断,因为电压采样有噪声,如果两节电压差刚好在阈值附近波动,均衡开关会频繁开关,MOS管和电阻反复承受冲击,寿命会受影响。
解决办法是加迟滞。我设了两个阈值:启动阈值和停止阈值。启动阈值是20mV,停止阈值是5mV。也就是说,当电压差超过20mV时启动均衡,当电压差降到5mV以下时停止均衡。中间这段区间保持当前状态不变。这样就能避免频繁开关。
代码里用一个状态变量记录当前均衡状态:
typedef enum { BALANCE_IDLE, BALANCE_CELL1, BALANCE_CELL2 } balance_state_t; balance_state_t balance_state = BALANCE_IDLE; void balance_task(void) { uint16_t v1 = read_cell1_voltage(); uint16_t v2 = read_cell2_voltage(); int16_t diff = (int16_t)v1 - (int16_t)v2; switch (balance_state) { case BALANCE_IDLE: if (diff > 20) { balance_state = BALANCE_CELL1; set_balance_switch(1, ON); } else if (diff < -20) { balance_state = BALANCE_CELL2; set_balance_switch(2, ON); } break; case BALANCE_CELL1: if (diff < 5) { balance_state = BALANCE_IDLE; set_balance_switch(1, OFF); } break; case BALANCE_CELL2: if (diff > -5) { balance_state = BALANCE_IDLE; set_balance_switch(2, OFF); } break; } }这个状态机每100ms跑一次,逻辑清晰,不容易出bug。实测下来,两节电芯的电压差能稳定控制在10mV以内,效果比预期好。
3.2 充电和放电阶段的均衡策略差异
均衡不是任何时候都能做的。充电阶段,电芯电压在上升,这时候做均衡效果最好,因为高电压那节被电阻放电,低电压那节继续充电,两者会逐渐靠拢。放电阶段,电芯电压在下降,均衡的意义不大,因为放电时电压差主要受内阻和容量差异影响,被动均衡那点电流根本追不上放电电流。
所以我的策略是:只在充电阶段和浮充阶段开启均衡,放电阶段关闭均衡。判断充电状态的方法很简单,检测充电电流或者充电器状态引脚。如果系统里有充电管理芯片,直接读它的状态寄存器就行。如果没有,可以用一个采样电阻加运放检测充电电流,电流大于50mA就认为是充电状态。
浮充阶段也要开均衡。备用电源系统大部分时间处于浮充状态,电芯电压稳定在3.6V到3.7V之间,这时候做均衡最安全,因为电流小,发热少。我一般会在浮充阶段把均衡电流设小一点,比如20mA,慢慢把电压拉平。
3.3 温度保护和故障处理
均衡电阻发热是不可避免的,所以温度保护必须有。我在均衡电阻附近贴了一个NTC热敏电阻,接到PIC18F85K90的ADC通道上。当电阻温度超过85°C时,强制关闭均衡开关,等温度降到60°C以下再恢复。这个迟滞也是为了防止频繁开关。
故障处理方面,主要监控三种情况:
- 电芯过压:电压超过4.25V,立即关闭充电回路,打开对应电芯的均衡开关。
- 电芯欠压:电压低于2.8V,关闭放电回路,禁止均衡。
- 电压采样异常:如果读回来的电压值超过5V或者为0,说明采样电路故障,关闭所有均衡开关,点亮故障指示灯。
这些保护逻辑都放在中断服务程序里,响应时间在毫秒级,足够快。
提示:NTC热敏电阻的阻值选择要和分压电阻匹配。比如用10kΩ的NTC,分压电阻也用10kΩ,这样在25°C时ADC读到的电压是VCC的一半,分辨率最高。温度计算公式用Steinhart-Hart方程,代码里用查表法或者简化公式都行。
4. 实测中遇到的坑和解决方案
4.1 电压采样跳变导致均衡误触发
第一批板子焊好之后,调试的时候发现均衡开关偶尔会自己打开,但用万用表测两节电芯电压明明是一样的。用示波器抓MP2642GR-Z的采样引脚,发现电压波形上有尖峰,幅度大概50mV,持续时间很短。这些尖峰被ADC采到之后,算出来的电压差就超过了20mV阈值,触发了均衡。
排查过程:先怀疑是电源噪声,在VCC和GND之间加了100uF和0.1uF电容,尖峰还在。后来把示波器探头接到采样电阻两端,发现尖峰和充电MOS管的开关动作同步。原来是充电MOS管开关时,电流突变在寄生电感上产生了电压尖峰,通过采样电阻耦合到了ADC输入端。
解决方案:在MP2642GR-Z的每个采样输入端加RC滤波,电阻100Ω,电容1uF,截止频率约1.6kHz。同时在充电MOS管两端加RC吸收电路,电阻10Ω,电容1nF,抑制开关尖峰。改完之后,采样波形干净了,均衡误触发的问题解决。
这个坑给我的教训是:电池管理系统里,采样电路的抗干扰设计比精度更重要。精度再高,噪声一大,全是白搭。
4.2 I2C通信在电池电压较低时失败
备用电源系统在放电末期,电池电压会降到3.0V左右。这时候发现PIC18F85K90读MP2642GR-Z的数据偶尔会失败,I2C总线上的波形幅度明显变小。用示波器看,SCL和SDA的高电平只有2.5V左右,低于PIC18F85K90的VIH阈值。
原因是MP2642GR-Z的I2C引脚是开漏输出,上拉电阻接到VCC。当电池电压下降时,VCC也跟着下降,上拉电阻提供的电平就不够了。解决方案是把上拉电阻从10kΩ减小到4.7kΩ,同时把VCC改用LDO稳压到3.3V,这样即使电池电压降到3.0V,LDO输出还是稳定的3.3V,I2C通信不受影响。
这个坑提醒我:电池供电的系统里,通信接口的电平要单独考虑,不能直接依赖电池电压。
4.3 均衡电阻温升过高导致PCB变色
最早选的均衡电阻是0805封装,0.125W,均衡电流设了80mA。老化测试跑了两个小时,发现PCB上均衡电阻周围的阻焊层变黄了,用热成像仪一测,电阻表面温度到了120°C。虽然电阻没坏,但长期这个温度,PCB的可靠性会下降。
重新计算:80mA * 4.2V = 0.336W,0805电阻的额定功率是0.125W,超了将近三倍。当时选型的时候只考虑了阻值,没算功率。换成两个1206封装的0.25W电阻并联,每个承担0.168W,温升降到40°C左右,问题解决。
后来我养成了一个习惯:每次选均衡电阻,先算功率,再留一倍余量,最后看封装。宁可多花几毛钱用大封装,也不要让电阻工作在极限状态。
4.4 单片机复位导致均衡状态丢失
PIC18F85K90在强干扰环境下偶尔会复位,复位之后均衡状态变量被清零,均衡开关全部关闭。如果这时候两节电芯电压差很大,就需要重新判断再打开均衡,中间有几秒钟的空白期。虽然不影响安全,但均衡效率降低了。
解决方案:把均衡状态保存到EEPROM里,复位后先读EEPROM恢复状态。同时加一个看门狗,防止程序跑飞。PIC18F85K90内置EEPROM,读写次数足够,不用担心寿命。写EEPROM的时候要注意,不要在均衡开关动作的瞬间写,避免电源波动导致写失败。我一般是在状态稳定后延时100ms再写。
5. 关键参数计算与元件选型清单
5.1 均衡电流和电阻的匹配计算
均衡电流的选取要综合考虑电芯容量、均衡时间和发热。公式很简单:
I_balance = V_cell / R_balance
其中V_cell是电芯电压,R_balance是均衡电阻。但反过来,已知想要的均衡电流,电阻值就是:
R_balance = V_cell / I_balance
功率计算:
P_balance = V_cell * I_balance
以2000mAh电芯为例,均衡电流取1%容量,即20mA。电芯电压按4.2V算,电阻值R = 4.2V / 20mA = 210Ω,取标准值200Ω。功率P = 4.2V * 20mA = 0.084W,选0805封装的0.125W电阻就够了,温升大概15°C。
如果电芯容量是5000mAh,均衡电流取50mA,电阻值R = 4.2V / 50mA = 84Ω,取82Ω。功率P = 4.2V * 50mA = 0.21W,要选1206封装的0.25W电阻,或者两个0805并联。
均衡时间估算:假设两节电芯容量差100mAh,均衡电流50mA,理论上需要2小时才能把容量差补回来。但实际均衡过程中,电压差会逐渐减小,均衡电流也会变化,所以时间会更长。对于备用电源这种长期浮充的场景,时间不是问题,慢慢均衡就行。
5.2 关键元件选型表
| 元件 | 型号/参数 | 数量 | 备注 |
|---|---|---|---|
| 模拟前端 | MP2642GR-Z | 1 | 两串电池管理,I2C接口 |
| 主控单片机 | PIC18F85K90 | 1 | 内置CAN/LIN,工业级 |
| 均衡MOS管 | AO3400 | 2 | 逻辑电平,Vgs(th)低 |
| 均衡电阻 | 82Ω 1206 0.25W | 4 | 两个并联为一组,共两组 |
| 电平转换三极管 | MMBT3904 | 2 | NPN,SOT-23封装 |
| 采样滤波电阻 | 100Ω 0603 | 4 | 每个采样通道两个 |
| 采样滤波电容 | 1uF 0603 | 4 | X7R材质 |
| I2C上拉电阻 | 4.7kΩ 0603 | 2 | 接到3.3V LDO输出 |
| NTC热敏电阻 | 10kΩ B=3950 | 1 | 贴在均衡电阻附近 |
| LDO | 3.3V 100mA | 1 | 给单片机和AFE供电 |
这个清单里的元件都是常见型号,容易采购,成本控制在10元以内。对于备用电源这种成本敏感的应用,这个BOM很有竞争力。
5.3 PCB布局的注意事项
PCB布局对采样精度和均衡效果影响很大。我总结了几条经验:
- MP2642GR-Z的采样输入走线要远离充电MOS管和电感,最好用地线隔离。如果空间允许,采样走线走在内层,上下铺地。
- 均衡电阻和MOS管放在板子边缘,方便散热。电阻下面不要铺铜,避免热量传到其他元件。
- I2C走线要等长,SCL和SDA尽量靠近,减少环路面积。
- 单片机的晶振要靠近芯片,负载电容接地要短。
- 电池连接器的正负极走线要粗,至少2mm宽,减少压降。
我第一版PCB没注意采样走线的隔离,结果噪声很大。第二版把采样走线改到内层,噪声立刻降了一半。这个教训值得记下来。
6. 这套方案还能怎么扩展
两串均衡只是起点,这套架构稍微改改就能支持更多串数。MP2642GR-Z本身支持多串,只要把电芯依次接到CELL3、CELL4等引脚,软件里增加对应的采样和均衡逻辑就行。PIC18F85K90的I/O口足够驱动8串以内的均衡开关,再多就要加I/O扩展芯片。
通信方面,PIC18F85K90内置CAN控制器,可以直接接入备用电源系统的CAN总线,把每节电芯的电压、温度、均衡状态上报给上位机。上位机可以记录历史数据,分析电芯一致性趋势,提前发现老化问题。这个功能在基站备用电源里很实用,运维人员不用到现场就能知道电池健康状态。
低功耗优化也是可以做的方向。备用电源系统大部分时间处于待机状态,单片机可以进入休眠模式,每隔几秒唤醒一次做采样和均衡判断。MP2642GR-Z也支持低功耗模式,通过I2C命令控制。实测下来,休眠模式下整机功耗可以降到1mA以下,对于长期浮充的系统来说,能省不少电。
最后说一个我在实际项目中体会最深的点:被动均衡的可靠性,很大程度上取决于你对最坏情况的考虑。比如均衡电阻短路了怎么办?MOS管击穿了怎么办?这些故障在实验室里不会出现,但在现场运行几年之后,什么都有可能发生。我的做法是在均衡回路上串一个自恢复保险丝,额定电流选均衡电流的两倍。这样即使MOS管击穿,保险丝也会断开,不会把电芯放空。这个保险丝成本不到一毛钱,但能避免整组电池报废,很值。