资讯动态

两串锂电池BMS被动均衡实战:电池前端芯片与单片机协作方案

发布时间:2026/10/16 1:17:01 来源:尧图企业网站定制
最近在给一套储能备用电源做BMS方案时我把均衡部分反复折腾了好几天最终确定的路线是用MP2642GR-Z这颗电池前端管理芯片配合PIC18LF46K22这颗低功耗单片机针对两节串联电池单元做被动均衡。这套组合做下来的效果比较稳也积累了不少一手教训干脆写一篇像样的项目笔记给做储能、备用电源或者模块化锂电池BMS的工程师做个参考。需要先说清楚的是很多刚入行的朋友总觉得只有十几串大电池才需要认真做均衡两串电池没啥好折腾的。但备用电源恰恰是最需要均衡的场景之一因为它长期挂在浮充或者待命状态电芯自放电率不一致的问题会被时间慢慢放大。两串虽然简单但它是整套BMS的最小可行单元把这个单元的均衡逻辑、阈值、保护做透了后面扩展到更多串就是复制粘贴的事。这篇笔记就按“为什么做、怎么做、出问题了怎么查”来写。1. 为什么两个串联电池单元也需要认真做均衡1.1 串联电芯不一致的“短板效应”先聊一个基本事实任何两节锂电池哪怕同一批次出厂内阻、容量、自放电率也不可能完全一致。制造公差只是起点工作温度不同、充放电深度不同、老化速度不同都会让差异越拉越大。串联回路里电流处处相等但每节电芯的实际电压变化却不一样。容量偏低的那节电芯会在充电时先到截止电压系统为了保护它只能停止整个电池组的充电放电时又是它先跌到欠压门槛整个电池组被强制断电。结果就是电池组的总容量跟着最弱的那节走这就是常说的“木桶效应”。备用电源场景更特殊电池大部分时间不是满负荷工作而是浮充待命。浮充电压长期压在电池组上自放电率高的电芯会持续被小电流补电自放电率低的电芯则长期处于过充边缘。几个月下来原本出厂只差10~20mV的两节电芯压差可以涨到50mV以上甚至更夸张。储能系统对这个更敏感。储能电池是大规模串并联组合每两串就是一个模块的基本单元模块内部不均衡系统级均衡根本无从谈起。所以别觉得两串电池小它恰恰是整个储能系统可靠性的起点。1.2 被动均衡为什么更适合储能备用电源均衡方案无非两大类主动均衡和被动均衡。主动均衡的原理是用电感或电容把能量从高电压电芯搬运到低电压电芯能量利用率高但电路复杂、成本高、控制逻辑多还需要额外的功率器件和磁性元件。对两串这种单元规模来说主动均衡有点杀鸡用牛刀的味道摊薄下来性价比很低。被动均衡也叫耗散均衡思路简单粗暴把电压偏高那节电芯的能量通过电阻放掉一部分让它的电压降下来等两节电压接近了就停。能量是浪费了但换来的是电路极其简单、控制极其可靠、故障点极少。备用电源系统恰恰不在乎那点耗散能量。系统大部分时间处于待命状态均衡电路只在小功率级别工作几十分钟甚至几小时耗散几十毫安的电流对整体电能损耗可以忽略不计。真正重要的反而是稳定和可预测所以被动均衡是这种场景最务实的方案。1.3 为什么把采样、保护交给MP2642GR-Z把策略交给PIC18LF46K22两串电池均衡的核心问题有两个一是怎么精确知道两节电芯各自的电压二是怎么控制均衡通路的开关。直接拿单片机的ADC去采电芯电压很诱人省一颗料但我劝你不要这么干。两节串联电芯的共模电压很高CELL2的电压是相对CELL1浮动的普通ADC根本处理不了这个共模问题。而且电芯内阻很小采样线上的纹波和噪声很容易把电压读数带偏。专业电池前端芯片内部有精密基准、斩波放大器和数字滤波毫伏级的精度是单片机内部ADC很难长期稳定的。MP2642GR-Z这类的电池前端管理芯片把高压采样、基准、保护逻辑都封装好了通过I2C接口就能读到两节电芯的电压也能控制均衡开关。这样高压模拟部分不用我操心低压数字部分罪简单。PIC18LF46K22在这里做的是策略大脑读电压、算压差、决策是否开启均衡、记录均衡时长、上报状态。它有足够多的IO口接NTC、状态灯、通信接口低功耗表现也好特别适合这种大部分时间都在待命的系统。两者分工是芯片管好“物理层”单片机管好“策略层”。2. 系统硬件框架与关键设计2.1 整体架构一句话看懂整套系统用一句话描述就是MP2642GR-Z跨接在两节串联电芯两端内部ADC采样CELL1和CELL2电压通过I2C把数据送给PIC18LF46K22PIC根据压差决定把均衡电阻接入高电压那节电芯同时负责温度采样、充放电控制、状态上报。MP2642GR-Z的均衡路径可以走内部均衡管也可以按数据手册接外部均衡电阻。内部均衡适合小电流场景如果均衡电流需要做得比较大比如几十毫安甚至上百毫安外部电阻更灵活。我在设计里选的是外部均衡电阻方案原因很简单散热好控制电阻值能自己定方便在不同容量电芯之间移植设计。PIC这边主要管三件事I2C总线、NTC温度采集、以及充放电MOS管的控制信号。备用电源还需要一个UART或者RS485口把状态上报给上位机我预留了一个UART口均衡动作和电压数据都能往外发。2.2 MP2642GR-Z周边电路要点MP2642GR-Z的供电直接取电池组电压内部有稳压电路不需要额外给它一路独立电源。这点在备用电源里很省事系统就算完全断电只要电池还有电前端芯片就能工作。I2C引脚需要上拉电阻我选了4.7kΩ配100pF电容做滤波。上拉电阻太小会增加功耗太大又拉不高总线速率4.7k在100kHz标准模式下够用400kHz快模式也勉强能走。后面加了100pF电容是给总线滤高频噪声的这个电容加不加差异很明显不加的话在电芯大电流切换瞬间I2C波形上会出现毛刺。CELL1和CELL2的采样输入线上我在靠近芯片引脚的地方串联了1kΩ电阻并联100nF电容组成一阶RC滤波。采样线直接从电芯极耳引出不要在功率线上取这是关键。功率线上有大电流用开尔文接法采样线和功率线分开才能避免公共阻抗把负载压降带进采样值。NTC电阻接在PIC的ADC引脚上用10kΩ的NTC配合10kΩ上拉分压。温度传感器紧贴电芯表面这样均衡开启时电芯温升能快速被捕捉到。2.3 均衡电阻怎么选阻值、功耗与温升计算均衡电阻是这套方案里最容易被忽视的元件很多人随手焊一个0603封装的贴片电阻上去结果一开均衡就冒烟。选均衡电阻要从三个维度算阻值决定均衡电流、功率决定散热需求、温度系数决定稳定性。电芯电压范围按磷酸铁锂来算工作区间大概3.0V到3.65V。均衡电阻两端的电压约等于被均衡电芯的电压均衡电流就是电压除以电阻。我列一张表方便直接查均衡电阻3.2V时电流3.65V时电流3.65V时电阻功耗100Ω32mA36.5mA133mW51Ω62.7mA71.6mA261mW33Ω97mA110.6mA404mW我这个项目里电芯容量是10Ah目标是均衡电流50~70mA所以选了51Ω。功耗接近0.3W实际选型用两颗1206封装电阻并联每颗分担一半电流和功耗表面温升控制在可接受范围内。封装不能只看标称功率1206电阻标称能承受0.25W到0.5W但如果紧挨着热敏元件或者PCB散热不好实际能力要打折。我的经验是工作功耗不要超过封装标称功率的70%长期可靠性才有保证。均衡电阻的温漂也要看普通厚膜电阻温漂在100ppm/℃级别均衡电流随温度漂移百分之几问题不大。但不要图便宜用线绕感性电阻高频开关动作时感抗会影响均衡电流波形。2.4 PIC18LF46K22接线与电源设计PIC的供电我用了一颗低功耗LDO从电池组降压到3.3V。LDO静态功耗要选微安级的因为备用电源待机状态下整板电流最好控制在几百微安以内。PIC进入睡眠模式后整板功耗大头就是LDO和均衡待机电路选型时把这些都算进去。晶振我没有外接直接用PIC内部振荡器。I2C通信对时钟精度要求不高内部振荡器足够。省掉晶振还能少两个引脚占用PCB布线也省事。如果是做需要精确时间戳的应用再考虑外部晶振。I2C和UART引脚用的是PIC的MSSP模块和EUSART模块硬件I2C比模拟I2C稳得多占CPU也少。GPIO里预留两个按键输入一个用来手动开启强制均衡一个用来复位调试的时候这两个功能救了我好多次。充放电MOS管控制信号那里要注意电平匹配。如果MOS管是逻辑电平型3.3V的GPIO可以直接推如果是普通电平的MOS栅极驱动电压不够必须加驱动三极管或者栅极驱动芯片。这个搞错的话最典型的现象就是MOS管导通压降很大发热严重。3. 均衡原理与核心参数设计3.1 被动均衡到底在“均”什么被动均衡的目标不是让两节电芯电压完全一样而是让它们在系统可接受的范围内接近。电压一致本身不是目的目的是让电芯的工作窗口对齐尽可能把容量用满。打个比方两节电芯像两个水桶容量一大一小。串联使用时水是从两个桶里一起往外舀的小桶先见底系统就停了。被动均衡不改变桶的大小它只把大桶里多余的水倒掉一些让两个桶的水位同时见底整体能用的水反而多了。理解了这一点就知道均衡只能在电压偏高那节上做文章。MP2642GR-Z控制均衡开关本质就是把高电压那节电芯的能量通过电阻放掉让它电压下降而不是把低电压那节抬起来。这是被动均衡的物理本质别搞混。均衡的时域特性也很重要。开启均衡后电压不会瞬间跌下来电芯的极化效应和化学扩散需要时间。所以判断均衡有没有效果要看几十秒甚至几分钟尺度的趋势而不是看瞬间读数。3.2 均衡开启/关闭阈值怎么定阈值设计是整个系统的灵魂。设得太小均衡频繁启停MOS管和继电器受不了电芯也被反复折腾设得太大压差被放任到危险区间均衡失去了意义。我常用的参考值是启动阈值20mV停止阈值10mV迟滞10mV。也就是说两节电压差超过20mV才开启均衡等压差回落到10mV以下才关闭。这个迟滞带能避免均衡开关在阈值附近反复抖动。更大容量的电芯可以把启动阈值放宽到30mV因为大电芯内阻小动态压差本来就比较明显阈值太小会把正常的负载压降误判成失配。小容量电芯可以把阈值收紧到15mV但要注意采样噪声至少保证阈值大于噪声峰值的三倍。均衡保护特性和充放电状态要联动。充电过程中电芯电压整体偏高不宜长时间均衡否则一边充一边放白白浪费能量且发热。静置状态最适合均衡没有外部能量干扰电压变化完全反映电芯本身状态。所以我在策略里做了状态判断只有系统处于静置或轻载待机时才允许进入均衡流程。3.3 MP2642GR-Z的寄存器操作逻辑MP2642GR-Z通过I2C暴露一组寄存器逻辑上分为电压数据寄存器、均衡控制寄存器、状态寄存器、保护寄存器几类具体地址和位定义要以对应的数据手册为准不同批次寄存器布局可能有差异。读电压的逻辑是把两节电芯电压各自拆成高字节和低字节组合成一个16位数值再乘以数据手册给出的分辨率系数换算成毫伏。换算公式一般在寄存器说明里有不同芯片的系数不同。写均衡控制字的时候一般用两个bit分别控制CELL1和CELL2的均衡开关。只开启高电压那节别同时开两节否则两节都在放电压差几乎不变白白发热。只有一种情况会两路都开整组电池需要深度静置维护让每节都稍微降一点电压。在读状态寄存器时要注意区分保护触发和普通告警。过压保护触发后会锁存需要写清标志位才能解除普通告警则随条件消失自动恢复。这些细节在调试时很容易被忽略导致误以为芯片坏了。I2C通信地址通常是7位手册里会标明也可能有引脚配置让硬件地址可选。如果有多个这样的芯片级联比如两串模块并联可以通过地址引脚区分。3.4 均衡过程的安全保护均衡过程本身是安全的但失控的均衡就是灾难。MP2642GR-Z自带硬件保护是最后一道防线PIC端软件还要再包一层。过热保护是第一优先级。我设定电芯表面温度超过45℃时无条件关闭均衡并上报。均衡电阻所在区域的PCB温度也放了一个NTC因为电阻贴片太近的时候电阻先过热电芯温度还没反应过来两个测温点级联才有完整的保护。时间保护也必须有。均衡不是无限期开启的我在软件里设了单次均衡最长时间默认120分钟。到了时间不管压差有没有达标都先停重新采样再评估。防止出现采样异常导致均衡一直开着的死循环。电压保护用MP2642的状态寄存器做双重确认开均衡前读一次电压确认没有过压告警均衡过程中每隔固定周期再读一次如果出现任何保护标志立即关均衡。软件里的保护判断都放在主循环里用状态机保证任何路径退出时都能关均衡。4. PIC18LF46K22端软件实现4.1 初始化流程PIC的上电初始化按固定顺序来顺序错了后面很难查。我的初始化流程是关看门狗和中断、设置振荡器、初始化GPIO、初始化I2C主机模式、初始化UART、初始化定时器、读一次MP2642的状态寄存器确认通信正常。初始化时读一次从机状态很重要。如果I2C总线接反了、芯片供电没起来这里就能发现而不是等到主循环里才报故障。我把这一步叫“握手检测”相当于开机自检。GPIO初始化要特别注意均衡控制相关引脚的默认状态。如果MP2642的均衡控制完全走I2C寄存器PIC这边不需要额外的GPIO但如果还接了独立的硬件使能脚该脚必须默认拉到关闭状态防止上电瞬间误触发均衡。内部振荡器如果精度要求不高用默认配置就行。如果UART后面要跑比较高的波特率建议用PLL把系统时钟提上去不然波特率误差会累积。这个项目波特率9600内部振荡器足够。4.2 I2C读写封装I2C操作封装成两个基础函数读寄存器和写寄存器。所有上层逻辑都基于这两个函数不直接碰MSSP寄存器这样后期换MCU平台时改动最小。读寄存器采用组合传输格式先发从机地址写位、寄存器地址然后重启总线发从机地址读位连续读两个字节。中间每一步都要检查ACK遇到NACK立即终止并返回错误码。一个高频坑从机地址的7位形式和8位形式经常混。I2C总线上发的是左移一位后的地址7位地址0x18实际发送的是0x30写或0x31读。代码注释里我同时标注两种形式避免三个月后自己看代码都懵。I2C速率在调试阶段先降到50kHz等波形确认没问题再升到100kHz或400kHz。降速能排除一大类时序问题很多所谓“总线卡死”其实就是速度太快导致边沿太差。4.3 均衡状态机实现均衡逻辑我用一个状态机来管状态转移清晰也方便将来扩展更多串电池。状态定义如下状态说明进入条件IDLE空闲不均衡初始化完成、均衡达标或超时MEASURE采样电压判断是否需要均衡定时唤醒或外部触发BALANCING开启指定电芯均衡压差超过启动阈值FAULT故障锁存只上报不动作过温、过压、通信失败等主循环流程是系统处于静置状态时进入MEASURE读两节电压计算压差如果大于启动阈值且没有保护标志进入BALANCING并记录开始时间。均衡过程中每30秒采样一次持续监测电压变化和保护标志。压差降到停止阈值以下或者时间超过最大时长退出回IDLE。需要注意状态切换时先写均衡控制寄存器关闭均衡再修改状态变量顺序不能反。代码里如果先改状态再关均衡一旦在状态切换瞬间有中断进来可能带着均衡开着跑到别的状态去。核心代码骨架大概是这样typedef enum { BMS_IDLE 0, BMS_MEASURE, BMS_BALANCING, BMS_FAULT } bms_state_t; void bms_task(void) { switch (state) { case BMS_IDLE: if (is_system_idle()) { state BMS_MEASURE; } break; case BMS_MEASURE: read_cell_voltage(CELL1, v1); read_cell_voltage(CELL2, v2); dv abs(v1 - v2); if (dv BAL_START_THRESHOLD_MV !is_protection_active()) { bal_target (v1 v2) ? CELL1 : CELL2; set_balancing(bal_target, ON); bal_start_time get_tick(); state BMS_BALANCING; } else { state BMS_IDLE; } break; case BMS_BALANCING: if (is_protection_active()) { set_balancing(CELL_NONE, OFF); state BMS_FAULT; } else if (dv BAL_STOP_THRESHOLD_MV) { set_balancing(CELL_NONE, OFF); state BMS_IDLE; } else if ((get_tick() - bal_start_time) BAL_MAX_TIME_TICK) { set_balancing(CELL_NONE, OFF); state BMS_IDLE; } break; case BMS_FAULT: if (!is_protection_active()) { state BMS_IDLE; } break; } }4.4 低功耗与待机策略备用电源的待机功耗是硬指标。电池组40Ah、系统待机电流1mA看似不多但一个月下来就是0.72Ah接近2%的容量被白白耗掉。均衡系统本身待机功耗必须压到最低。PIC18LF46K22的优势就体现出来了。睡眠模式下电流可以做到微安级用内部定时器周期唤醒唤醒后做一次采样、一次判断、一次均衡控制操作然后继续睡。唤醒周期我设的1秒对均衡应用完全够用因为电压变化是慢变量1秒采一次已经非常奢侈了。MP2642那边也有低功耗思路。均衡不工作时I2C总线空闲前端芯片内部大部分模块可以处于低功耗状态。要注意的是I2C总线上拉电阻的电流长期挂高电平会有微小的漏电流上拉电阻选大一点能省功耗。PIC在Sleep前必须把I2C总线释放干净从机状态清掉、总线上拉保持、MSSP模块复位。唤醒后第一步重新初始化MSSP再做一次总线恢复防止睡眠期间总线被干扰拉死。5. 现场调试中的问题与排查实录5.1 均衡开了但压差不降这个现象看起来最迷惑I2C写均衡控制寄存器成功了回读也确认均衡打开了但压差就是纹丝不动甚至不降反升。我排查的第一步是量均衡电阻两端电压。如果均衡电阻上有压差说明电流路径是通的如果两端电压等于电芯电压但没电流要么电阻虚焊要么线路板铜箔断裂。用热像仪或者手摸电阻看发热最直接均衡开启时电阻应该微温。如果电阻确实发热但压差不降要怀疑采样位置。之前提到开尔文接法如果MP2642的采样线接到均衡电阻的下游而不是电芯极耳上均衡电流在采样线阻抗上产生的压降会抵消一部分均衡效果甚至让读数反向。还有一个容易被忽略的情况均衡电流太小典型值只有十几毫安面对10Ah电芯电压下降速率只有每小时几毫伏。这时候不是均衡无效而是观察时间太短。拿数据手册上的容量和均衡电流估算一下就知道要等多久才能看到明显变化。5.2 I2C通信被拉死I2C卡死是最常见的通信问题典型现象是SDA一直被拉低SCL还在正常翻转单片机端一直收不到ACK。我遇到过一次是上电时序问题MP2642还没完成内部初始化PIC就发起了I2C通信芯片没准备好所以NAK但PIC的I2C状态机没处理干净把总线锁住了。解决办法是在PIC上电后延时100ms再开始通信给前端芯片留足启动时间。另一个坑是从机地址搞错。MP2642的7位地址如果手册标的是0x18发送时要左移一位变成0x30。我把地址写错成0x18直接发总线上回应完全随缘时好时坏。后来把地址定义做成宏读写各一个再也没出过这类问题。总线恢复序列也值得写进代码遇到超时错误时把SCL拉高拉低切换9个时钟周期让可能处于异常状态的从机复位然后再发一个STOP条件释放总线。这个序列在调试初期救了我很多次。5.3 电压读数跳变电压跳变超过10mV会让均衡策略崩溃阈值判断失真刚刚还均衡得好好的突然判定压差超标就关掉了。排查发现跳变主要来自采样线上的噪声。备用电源的充电机在恒压阶段会有脉冲纹波纹波电流流过采样线公共阻抗时就会在ADC输入端形成电压毛刺。对策是加RC滤波把RC截止频率压到几十赫兹毛刺就消掉大半。软件上我做了中值滤波连续采5次取中间值。中值滤波比平均值滤波更抗脉冲干扰也不会像平均滤波那样把真实电压拖慢太多。这个处理对均衡判断非常关键。还有一个细节均衡开启瞬间电芯电压会有小幅阶跃这是因为均衡电流让电芯内部产生极化。读数跳变后别急着判断等几十秒再采样让电芯状态稳定下来。5.4 均衡电阻发热均衡电阻发热不是故障但过热就是事故。我实测100mA均衡电流流过51Ω电阻连续工作30分钟后0603封装的电阻表面温度超过100℃直接烫手。这个问题本质是封装功率选小了。正确的做法是按我之前那张表算功耗然后留足降额。设计定型后我又做了一版热测试室温25℃、均衡电流70mA、连续工作2小时电阻表面温度稳定在55℃左右PCB对应区域也不超过50℃这个温度对长期运行是安全的。发热还有一个连带危害均衡电阻贴着电芯热量会传导到电芯表面。磷酸铁锂的工作温度上限一般是60℃如果均衡和充电同时进行电芯本身也会发热两者叠加就可能超温。所以均衡开启条件里我强制要求电芯温度低于40℃才允许启动。5.5 浮充状态下误均衡备用电源挂在浮充机上时电压纹波和充电机的噪声会让压差判断失真出现频繁启停均衡的现象。均衡刚开启几十秒压差就“达到”停止阈值关掉之后几秒又“超过”启动阈值反复循环。这个问题根源在于采样时机不对。浮充状态下的电压包含直流分量加纹波分量纹波会让瞬时压差忽大忽小。解决办法是把判断窗口拉长连续3次采样每次都满足开启条件才真正进入均衡同样连续3次满足关闭条件才退出。另一个办法是等充电机进入静置期再判断。备用电源的充电策略通常有恒压阶段和休眠阶段休眠阶段纹波小电压更接近电芯真实状态。如果系统能拿到充电机的状态信号就等休眠阶段再做均衡效果最好。6. 实测数据与工程经验总结6.1 一组实测数据这套系统在模拟备用电源环境里跑了几轮测试挑一组有代表性的数据放出来参考。测试条件两节磷酸铁锂10Ah电芯初始电压分别是3.312V和3.268V压差44mV电芯温度26℃。系统处于静置状态均衡电阻51Ω理论均衡电流约65mA。开启均衡后前20分钟压差只降了4mV我一度怀疑均衡没工作。但从第30分钟开始电压差下降速度加快80分钟后压差降到15mV120分钟后降到9mV达到停止阈值均衡自动关闭。停止均衡后24小时再测压差回弹到13mV。这是电芯极化恢复导致的正常现象不是均衡失效。我又手动开了一轮40分钟的均衡最终稳定在8mV以内。这个数据说明两件事一是均衡确实有效二是电芯极化会让压差在均衡停止后有少量回弹所以在阈值设计时要把回弹余量算进去别把停止阈值设得太极限。6.2 三个值得长期坚持的工程习惯第一个习惯是给均衡状态加日志。我用UART把每次均衡开启时间、目标电芯、压差变化打印出来开发阶段看日志比看灯友好太多了。后来我在产品里也保留了一个调试尾针出问题能现场抓数据。第二个习惯是阈值参数不要写死在宏定义里吹牛放进EEPROM或者Flash参数区这样量产调试时可以改参数不用重新烧程序。我吃了一次亏第一批样机焊接后发现电芯批次内阻偏大20mV阈值太灵敏只能重新烧片浪费了一天时间。第三个习惯是每个均衡周期的开始时清零均衡时间累计值记录最大单次均衡时长。这样能统计电芯老化的趋势如果压差越来越大、均衡时间越来越长说明电芯健康度在下降系统可以提前告警而不是等到故障发生才处理。这套MP2642GR-Z加PIC18LF46K22的组合我用下来的整体感受是模拟前端芯片把最麻烦的高压采样和保护兜住了单片机只负责决策和通信分工清晰调试效率高。两串电池的均衡虽然规模不大但它涉及到的采样精度、迟滞设计、安全保护、低功耗和调试手段跟几十串大系统的逻辑是完全相通的。把这套做扎实了后面往上扩展心里会有底得多。

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

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

免费获取报价 →
↑