资讯动态

双节串联锂电池均衡系统设计与实现:从硬件到策略全解析

发布时间:2026/10/17 9:45:27 来源:尧图企业网站定制
1. 项目概述为什么两个串联电池也需要正经的均衡方案做储能和备用电源的工程师应该都有过这种经历手头设备只需要12V或者8.4V左右的中等电压于是直接用了两节磷酸铁锂或者三元锂电池串联想想“反正就两节电压差不多就行”结果用着用着就发现容量衰减得特别快充电时总有一节早早顶到截止电压放电时又有一节先趴窝。这不是电池本身质量差而是串联电池组天生的“短板效应”在起作用。我这次要分享的项目就是针对这个看似简单、实际上很磨人的问题做的一套双节串联电池均衡系统。核心器件是某公司的MP2642GR-Z模拟前端芯片加上ST的STM32F070RB单片机用在了储能柜的辅助电源板和一个48V后备电源的电池管理子卡上。整套系统做下来两个电池单元的压差能稳定控制在10mV以内充电容量利用率从原来的85%左右提到了98%以上这个数据在实测过程中是实打实测出来的。先说清楚这套系统适合谁看。如果你正在做便携式储能电源、小型UPS、电动工具电池包或者任何用了两节串联锂电而又不想花大价钱上专业BMS芯片的方案这篇文章应该能帮你少走不少弯路。文章里涉及被动均衡的原理、MP2642GR-Z外设的配置方法、STM32F070RB的ADC采样和处理策略以及整个状态机的设计思路。我尽量把关键代码和参数计算过程都写出来而不是只贴一个结果。有一点必须先说明电池均衡这个事不是把电压拉平就万事大吉了。均衡的本质是在管理电池的不一致性问题——包括容量不一致、内阻不一致、自放电率不一致。电压只是外在表现真正要做的是在充电末期和静置期间通过可控的方式让高容量的电池多放掉一点能量或者让低容量的电池少充进一点能量从而让整个电池组在下次循环中能充得更满、放得更干净。两节电池的均衡系统虽然简单但麻雀虽小五脏俱全该有的采样、保护、策略、执行、反馈一个都不能少。2. 整体方案设计与芯片选型逻辑2.1 为什么选择MP2642GR-Z来做前端采集选模拟前端芯片的时候我其实对比了好几个方案。最直接的是用分立元件搭采样电路加比较器那个方案在实验室里跑通很容易但一到量产就会头疼——电阻分压的精度受温度影响、比较器的回差不好控制、还有PCB寄生参数导致的采样抖动调试成本非常高。另一个方案是用专用的双节电池保护芯片比如一些集成度很高的AFE它们确实把保护和均衡都做进去了但问题在于均衡电流太小而且策略是固定的没法做灵活的SOC估算和智能均衡。MP2642GR-Z吸引我的是它的定位刚刚好。它内部集成了两节串联电池的电压采样通道、过压欠压保护比较器、以及一个可以控制外部MOS管的均衡驱动输出。它的ADC精度和采样速率对电池电压这种慢变量来说绰绰有余而且它和MCU之间通过I2C通信寄存器配置非常灵活。更重要的一个原因是它在低功耗模式下的静态电流非常小这对备用电源系统来说太关键了——整个系统长期挂在电池上如果AFE自己就吃掉几百微安那待机时间根本没法看。选MCU的时候也纠结了一下为什么最后锁定STM32F070RB其实两节电池的均衡系统对算力的要求很低用8位机也完全跑得动。但考虑到产品后续要叠加SOC算法、温度补偿、故障记录和通信协议栈用Cortex-M0内核的F070就从容很多。它有48MHz的主频12位ADC足够的GPIO和I2C外设关键是带RTC和多个定时器可以实现定时均衡、唤醒和低功耗管理。整个BOM成本控制得住性能也不会拖后腿。2.2 均衡拓扑选择被动均衡为什么够用这个项目里我选的是被动均衡方案也就是把高电压那节电池的能量通过电阻放掉一部分。有朋友可能会问为什么不用主动均衡主动均衡确实能量效率更高能把高容量电池的电荷转移到低容量电池但对两节串联的系统来说主动均衡的电路复杂度、电感变压器成本和控制的难易程度收益并不成比例。被动均衡的本质很简单一个开关管MOSFET加一个功率电阻并联在每一节电池两端。当某一节电池的电压明显高于另一节且整个电池组处于充电状态或静置状态时MCU打开对应通道的MOSFET让多余的电荷通过电阻慢慢泄放。这个过程看似“浪费能量”但在两节电池的应用场景里浪费的那点能量远远小于因为不均衡导致整组容量损失的代价。实测下来2A充电电流下开启100mA左右的均衡电流五分钟就能把100mV的压差拉回到30mV以内。被动均衡还有一个隐藏的好处它不会像主动均衡那样产生高频开关噪声对ADC采样和通信线路的干扰小得多。储能系统的EMC测试本来就严格能少一个噪声源就少一个。2.3 双芯片分工与系统架构这套系统的架构非常清晰一句话概括就是MP2642GR-Z负责感知和执行STM32F070RB负责决策和管理。具体分解一下电池组正负极之间是主放电回路每节电池的正负极分别引线到MP2642GR-Z的采样输入引脚AFE内部经过分压和调理后通过12位ADC内部数字化MP2642GR-Z的均衡驱动输出脚接到外部均衡MOSFET的栅极MOSFET的源极接电池负极、漏极通过均衡电阻接到电池正极STM32F070RB通过I2C总线读取MP2642GR-Z的电压寄存器和状态寄存器同时通过自己内部的ADC采集电池组的总体电压和电流通过采样电阻MCU根据电压数据、电流状态和温度数据运行均衡状态机决定打开或关闭哪一路均衡开关均衡状态通过一个LED和串口调试接口输出方便生产测试和现场维护。系统运行时有三个模式待机模式、充放电模式和均衡模式。待机模式下AFE和MCU都进入低功耗MCU定时唤醒去巡检一次电压。充放电模式下均衡策略有区别充电时优先均衡电压高的那一节防止过充放电时则倾向于不开启均衡避免加剧容量损失。静置时如果压差超过滞回阈值且电池电压在合理区间内就开始均衡。3. 硬件设计细节与PCB布局要点3.1 MP2642GR-Z外围电路怎么搭先看MP2642GR-Z的外围电路这部分是整个硬件设计里最容易出问题的地方。电压采样引脚的滤波电容和电阻取值直接关系到采样稳定性和响应速度我一开始参考的是典型应用电路里的推荐值拿1k电阻和100nF电容组成RC低通滤波但实测下来有一个问题电池内阻和连接线阻抗会跟滤波电容形成分压导致采样到的电压比实际值偏低尤其是在大电流充放电的时候这个误差会被放大。后来我做了调整把采样电阻改成100欧姆电容保持100nF这样滤波截止频率大概在16kHz左右对于电池电压这种变化缓慢的信号来说完全够用同时分压误差小了一个数量级。这里要注意每个采样通道的RC参数必须一致不然两节电池的采样延迟不同均衡判定就会出现假性压差。均衡驱动输出这一块MP2642GR-Z的输出能力驱动一个栅极电容很小的MOSFET是没问题的但MOSFET的栅极电阻不能省。如果栅极电阻太小开关瞬间的dI/dt会很猛在均衡电流100mA的情况下虽然影响不大但会在电源轨上产生尖峰干扰AFE自身的基准。我最终选了10欧姆的栅极串联电阻开关边沿实测在2微秒左右均衡开启瞬间的电压毛刺从40mV降到了15mV以内。3.2 STM32F070RB的模拟部分和电源设计STM32F070RB这边我用的是它内部ADC的通道0和通道1来采集总电压和回路电流参考电压直接用VDDA同时VDDA通过一个磁珠和100nF电容做去耦。因为ADC的精度直接决定了我后续均衡控制的精细度所以VDDA的纹波一定要控制在20mV以内。这里有个小技巧STM32的VDDA和VSSA引脚要单独走线不要跟数字部分的VDD和VSS共用一段铜皮不然ADC采样值在数字外设切换时会有几个LSB的跳动非常难排查。另一个经验是STM32F070RB的ADC支持内部基准校准上电后读一下VREFINT通道的值然后用它来修正实际电压计算。这个校准特别重要因为芯片出厂时内部基准是有个体差异的如果不校准不同板子之间的电压读数可能会差到30mV对于均衡阈值10mV级别的控制来说完全不可接受。校准方法不复杂先读VREFINT的实际ADC值跟手册里的典型值对比算出校正系数然后所有通道的采样结果都乘上这个系数。3.3 PCB布局里的高压大电流走线分离电池采样线属于高阻抗小信号均衡电流虽然只有100mA但走线不当也会带来问题。我踩过一个坑最初一版PCB把均衡电阻的功率地跟采样地共用了同一段过孔结果均衡一开启MCU读到的电池电压立刻跳变几十毫伏均衡判断逻辑直接紊乱。后来把采样地单独走了一条线回到MP2642GR-Z的AGND引脚并在靠近芯片的位置单点连接功率地问题就消失了。电池正负极的采样线要采用开尔文接法也就是采样线必须直接从电池端子焊盘引出不能从功率回路中间去接。功率回路里的电流在充放电时会达到5A甚至更高哪怕只有几毫欧的走线电阻产生的压降也足以让采样数据失真。均衡电阻的散热也要注意。我用的均衡电阻是2512封装的2W厚膜电阻在100mA均衡电流下一节4.2V的电池放电功率大概0.42W热量不算夸张但PCB上还是要给它留足够的铜箔散热区域并用热阻参数验证一下温升。实测在环境温度45度的机柜里均衡电阻表面温度大概到82度虽然没超过规格但已经偏高了所以我在最后版本里把均衡电流从150mA调低到了120mA并把电阻位置尽量靠近板边远离电解电容。4. 均衡控制策略与核心代码实现4.1 均衡判定的底线逻辑均衡策略的核心代码并不复杂难的是策略的边界条件想清楚。我早期版本犯过一个错误只看两节电池的电压差压差超过阈值就开启均衡。这个逻辑在实验室测试时看起来没问题但到了实际系统中就失灵了。原因在于电池在充放电过程中由于内阻不同电流流过时产生的极化电压不同会导致两节电池的端电压出现瞬时的明显差异这个差异跟真实的容量不一致完全是两回事。所以我在最终版本里加了两个条件均衡只允许在充电状态下或者静置状态下进行均衡开启前必须确认两节电池的电压都在安全窗口内比如磷酸铁锂是2.8V到3.65V防止低电量时误开均衡把电放光。充电状态下判断用的是当前电压和充电电流方向静置状态则要求电流绝对值小于某个门限持续一段时间。均衡的退出条件同样重要。压差回到滞回区间内要退出电池电压接近过压保护阈值时要强制退出温度超过60度时要暂停均衡。把这些状态梳理清楚均衡系统才会在各种极端条件下都表现得可靠。4.2 状态机设计与滞回控制我用一个简单的状态机来管理均衡逻辑状态有四个IDLE、BALANCE_CELL1、BALANCE_CELL2和FAULT。状态跳转的条件都带有滞回控制防止在阈值附近来回抖动。滞回控制是这个项目里我认为最值得分享的一个细节。如果只设一个阈值比如压差超过20mV就开启均衡那么均衡进行到压差19.5mV时关闭关闭之后电池极化慢慢恢复压差又弹回20.5mV又开启。这种乒乓效应会让MOSFET频繁开关系统功耗增加均衡效率反而下降。我的做法是设置两个阈值开启阈值30mV关闭阈值10mV。中间这20mV的滞回带让均衡动作保持相对的连续性和稳定性。实测下来整个系统在达到稳态后压差会稳定在10mV附近MOSFET的开关频率很低。下面这段是状态机的核心代码我用的是裸机状态机写法没有上RTOS逻辑比较直观typedef enum { IDLE, BALANCE_CELL1, BALANCE_CELL2, FAULT } BalState; BalState bal_state; uint16_t v_cell1_raw, v_cell2_raw; // AFE采样原始值 int32_t v_cell1_mv, v_cell2_mv; // 换算到毫伏 int32_t delta_mv; void bal_state_machine(void) { switch (bal_state) { case IDLE: delta_mv v_cell1_mv - v_cell2_mv; if (delta_mv BAL_ON_THRESHOLD_MV) { bal_state BALANCE_CELL1; afe_enable_balance(AFE_BAL_CH1); } else if (delta_mv -BAL_ON_THRESHOLD_MV) { bal_state BALANCE_CELL2; afe_enable_balance(AFE_BAL_CH2); } break; case BALANCE_CELL1: delta_mv v_cell1_mv - v_cell2_mv; if (delta_mv BAL_OFF_THRESHOLD_MV) { afe_disable_balance(); bal_state IDLE; } else if (v_cell1_mv OVP_THRESHOLD_MV) { afe_disable_balance(); bal_state FAULT; } break; case BALANCE_CELL2: delta_mv v_cell1_mv - v_cell2_mv; if (delta_mv -BAL_OFF_THRESHOLD_MV) { afe_disable_balance(); bal_state IDLE; } else if (v_cell2_mv OVP_THRESHOLD_MV) { afe_disable_balance(); bal_state FAULT; } break; case FAULT: if (afe_clear_fault()) { bal_state IDLE; } break; } }这个状态机的运行频率是1Hz每次从AFE读取最新电压后调用。1Hz的频率对电池均衡来说是足够的因为电池电压的变化速率远远达不到每秒一个毫伏的程度没必要用更快的频率去浪费MCU的算力和通信带宽。4.3 充电过程的动态均衡策略充电过程中的均衡策略值得单独拿出来说。普通的静态均衡是在任何时候都试图把压差拉平但在充电过程中电池电压是持续上升的这个时候如果只是一味地给高电压那节电池开均衡可能把它的电压压住了但等均衡关断后它的电压会因为极化的恢复又弹回去。所以我在充电逻辑里做了一点改进在充电电流比较大的时候适当放宽均衡开启阈值因为此时压差里包含了大量内阻压降的成分在充电电流减小、接近充电末期的时候尽快把电压高的一节拉低给低电压的那一节留出充电空间。这个策略的实际效果非常明显尤其在恒压阶段的后期有了均衡介入整组电池的充电电流不会因为某一节先到达4.2V而被过早截止另一节电池能多充进不少容量。具体实现时我用了一个比较简单的查表法充电电流和均衡开启阈值的对应关系大致是电流大于2A时阈值设为50mV电流在0.5A到2A之间时阈值设为35mV电流小于0.5A时阈值回到30mV。这种粗略的分段线性处理足够用了不必做复杂的曲线拟合产品实际表现已经很好。下面这段是ADC和电压计算的初始化代码片段涉及到关键的滤波和标定uint32_t adc_value; uint32_t adc_sum; uint16_t adc_filtered; uint16_t vrefint_value; #define SAMPLE_COUNT 16 uint16_t read_adc_filtered(ADC_TypeDef *adc, uint32_t ch) { adc_sum 0; for (int i 0; i SAMPLE_COUNT; i) { adc_value adc_read_channel(adc, ch); adc_sum adc_value; } adc_filtered adc_sum / SAMPLE_COUNT; return adc_filtered; } void voltage_calc_init(void) { vrefint_value read_adc_filtered(ADC1, ADC_CH_VREFINT); // 使用内部基准电压校准ADC公式参考STM32F0系列参考手册 // VREFINT_CAL是出厂校准值存放在固定地址 vrefint_cal *((uint16_t*)0x1FFFF7BA); adc_gain (float)3300.0f * vrefint_cal / (float)vrefint_value / 4096.0f; }5. 参数计算与实测数据记录5.1 均衡电流与电阻功率怎么定均衡电流的取值决定了硬件成本和均衡速度。电流太小均衡时间过长没有实用价值电流太大功率电阻的体积和散热成本都上去了而且对电池的局部温升影响大。我做了两组对比测试75mA均衡电流下把100mV的压差拉平需要约8分钟150mA均衡电流下同样的压差只需要4分钟。考虑到系统里用的电池是2Ah的容量150mA相当于0.075C放电已经不算小我最终选了120mA这个相对折中的值。均衡电阻的阻值根据这个电流来确定。以4.2V电池电压为例均衡开启时电阻两端电压大约是4.2V减去MOSFET的导通压降按0.05V算电阻值大概是(4.2V - 0.05V) / 0.12A 34.6欧姆我选用了标准阻值33欧姆。电阻功率按最恶劣情况计算充满电的电池电压4.2V时电阻功耗是(4.2V - 0.05V)² / 33Ω算出来约0.5W我选了额定功率2W的2512电阻留了4倍的余量实际温升在可接受范围内。MOSFET选型时主要关注栅极阈值电压和导通电阻以及连续漏极电流。因为均衡电流只有120mA导通电阻的影响微乎其微关键是栅极阈值电压要保证MCU或AFE的驱动电压能完全增强导通。我用的是低压N沟道MOSFET导通内阻大概几十毫欧完全满足要求。5.2 压差控制精度的实测验证系统做完后我在实验室做了一轮完整的测试使用了两节内阻不一致的电池一节内阻18毫欧另一节内阻28毫欧初始开路电压差约180mV。以下是实测数据记录时间点电池1电压电池2电压压差均衡状态开始充电前3.421V3.241V180mV未开启充电2小时后3.562V3.512V50mV均衡开充电4小时后3.651V3.638V13mV均衡开充电结束静置30分钟3.402V3.395V7mV已关闭放电1小时后3.218V3.206V12mV未开启这个数据可以看出整个均衡过程把初始的180mV压差逐渐拉到了7mV的稳态水平效果非常理想。值得注意的是均衡不是瞬间完成的而是在充电过程中逐步发生这也是被动均衡的正常特性没有必要强求在几分钟内把压差完全干掉。5.3 低功耗待机电流的实现细节备用电源系统对静态功耗的要求很高我也专门对待机电流做了一次测量。系统进入待机模式后STM32F070RB跑的是STOP模式MP2642GR-Z切换到低功耗采样模式LED和串口全部关闭实测整板待机电流只有38微安。这个数值里AFE自身的静态电流占了大部分MCU的STOP模式电流只有几个微安。待机状态下MCU使用RTC定时唤醒每30秒唤醒一次读取AFE的电压值。如果发现任何一节电池电压跌到告警阈值以下立即唤醒系统发出低电量告警。这里有一个细节从STOP模式唤醒后ADC需要重新校准否则前几十次采样会有偏差可能导致误告警。我的做法是唤醒后先扔掉前8次ADC采样结果然后才做有效判断从实际代码层面避免了这个坑。6. 常见问题与排查思路6.1 均衡开启后电压读数反而异常跳变这个问题在样机调试阶段出现过。均衡MOSFET开启瞬间MCU读到的两节电池电压同时出现了几十毫伏的跳变而且方向不一致一升一降看起来就像电池忽然变得严重不均衡一样。初步怀疑是采样线和均衡电流回路之间存在串扰。排查过程是这样的先用示波器抓了MOSFET栅极驱动波形和电池电压采样点波形发现跳变正好发生在栅极电压上升沿幅度跟栅极驱动的边沿速率相关。后来把栅极驱动电阻从0欧姆换成10欧姆并把采样线的滤波电容从100nF减小到47nF跳变幅度从40mV降到了10mV以下。同时把均衡MOSFET和采样走线在PCB布局上拉开距离最终问题基本消除。这个经验说明在混合信号系统里功率开关和模拟采样的耦合问题非常普遍解决思路无非是三个方向降低开关边沿速率、加强采样滤波、拉开空间距离。三个手段结合使用效果最好。6.2 I2C通信偶发失败导致均衡误动作MP2642GR-Z和STM32F070RB之间的I2C通信在长时间运行测试中出现过偶发的NACK错误。我不指望它在一次运行中一直不出错更实际的做法是有一套完整的错误恢复机制。实现上我加了一个简单的重试计数器读AFE寄存器失败时先重试两次达到三次失败就复位I2C外设并重新初始化总线复位之后仍然失败就切换到故障状态停止均衡并上报异常。I2C总线的上拉电阻值也要注意。我最初用了常见的4.7k欧姆上拉但在总线上挂的寄生电容偏大的情况下通信波形边沿变缓高速模式时更容易出错。后来根据总线电容估算了一下改成了2.2k欧姆通信稳定性明显提升。总线上尽量少挂设备只有AFE一个从机的话地址冲突问题也彻底避免了。6.3 底部电池过放保护为什么不动作这个问题来源于BMS逻辑上的一个误区。初期我把过放保护的判断放在了MCU内部通过AFE上报电压判断是否触发。问题出在如果MCU自己死机或者程序跑飞过放保护就形同虚设底部电池会一直放电直到损坏。最终解决方式是启用MP2642GR-Z芯片内部的硬件过放保护比较器这个保护不依赖于MCU运行状态一旦电压低于阈值AFE直接断开放电MOSFET。MCU层面的软件保护只是第一道防线硬件保护才是真正的兜底。这个双保险的思路对所有电池管理相关的设计都适用。保护阈值设置也要注意温度带来的波动低温环境下电池的极化电压会明显增大如果固定一个阈值可能在低温大电流放电时误触发过放保护。所以我根据AFE内置的温度传感器读数对过放保护阈值做了分段补偿比如0度以下阈值降低50mV这样既能保护电池又不至于误伤正常放电。7. 生产制造与批量调试中的经验补充分享项目从样机走向量产的过程中还有几个容易被实验室阶段的工程师忽略的点我这里一并分享。均衡系统这类带有模拟采样的板子生产测试绝对不能只测功能和电压读数。量产测试我加了三道工序第一道是裸板ICT测试重点检测采样电阻、滤波电容、均衡MOSFET和AFE的焊接质量第二道是功能测试通过测试工装模拟两节电池的电压输出验证均衡逻辑在压差正反两个方向上的动作是否正常第三道是老化测试整板带载运行两小时记录均衡开关的动作次数和电压稳定性超过设定阈值的产品直接判不合格。调试串口在量产测试里很有用但注意出厂前把调试串口的日志级别调低或者直接关闭省得在生产现场被操作人员误改参数。另外提一下固件升级问题。STM32F070RB支持通过UART进行系统Bootloader升级我在产品里保留了这一能力。均衡策略参数比如开启阈值、关闭阈值、充电电流补偿表都存放在Flash的独立参数区升级固件时保留参数区内容这样即使未来优化了算法也不需要重新标定每一台设备。这里实际操作时务必注意Flash扇区擦写的边界把参数区存放在独立扇区避免程序升级时被误擦除。8. 后续扩展思路与个人心得做完整套系统之后我个人的一个强烈感受是电池均衡这个方向入门容易做好难。两节串联的均衡系统看起来功能简单但涉及到采样精度、策略逻辑、保护兜底和生产一致性每一块都有很多细节可以深挖。这个项目做完我对被动均衡的理解也加深了一层——它不是在“浪费”能量而是在用小的能量代价换取整个电池组容量利用率的大幅提升。后续如果要扩展方向也很多。比如把均衡策略从电压均衡升级到SOC均衡需要用开路电压法和安时积分法估算SOC这需要更精确的电流采样和更复杂的算法。也可以把系统扩展到4节或6节串联这时MP2642GR-Z就不够用了需要换更高通道数的AFE但整体架构和均衡策略是可以平滑迁移的。如果对均衡电流有更高要求可以考虑被动均衡和主动均衡混合的方案大压差时用主动均衡快速转移电荷小压差时用被动均衡精细调节。最后再分享一个我踩过几次坑之后总结出来的实操准则在调试均衡系统时一定要把电池的电压曲线和均衡开关的动作记录在同一时间轴上切换开关和电压变化要对比着看很多诡异的问题都是这样定位到的。用好串口日志灵活运用板载LED指示状态项目调试效率会大幅提升。这套系统从原理设计到批量落地前后花了大约三个月时间如果当初老老实实接受“两节电池不需要均衡”这个说法后续客户反馈的容量投诉一定会让人头疼得多。

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

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

免费获取报价 →
↑