ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

2S电池组BMS被动均衡:STM32L151ZD与MP2642GR-Z方案解析

2S电池组BMS被动均衡:STM32L151ZD与MP2642GR-Z方案解析

备用电源真正出问题的时候,通常不是电池突然“坏了”,而是整个电池组被某一节“拖后腿”的电芯一点点拖垮的。最近我把一套针对两串串联电池的均衡样板做了完整验证,主控选用 STM32L151ZD,均衡执行由 MP2642GR-Z 完成,面向的就是储能和备用电源里最常见的 2S 电池组。这篇记录会从选型思路、硬件职责划分、固件状态机、实测参数到调试中踩过的坑都捋一遍,适合正在做 2 至 4 串 BMS 的软硬件工程师,也适合想把串联电池管理真正做扎实的入门开发者。

1. 串联电池的“短板效应”:为什么这个项目一定要做均衡

1.1 串联回路里电流相同,容量却各自为政

串联电池组有一个天然矛盾:流过每一节电芯的电流完全一样,但每节电芯自己能做到的容量却不一样。制造时的极片厚度偏差、电解液浸润程度、自放电率的细微差异、安装位置温度不同、老化速度不同,都会让“同一批电芯”在半年后变成“完全不同的电芯”。

我见过一套相当典型的备用电源,标称是 2S 磷酸铁锂,使用大半年后出现“充电很快就满、放电很快就没”的现象。拆开后实测,一节电芯电压 3.45V,另一节只有 3.0V。电池并没有坏,只是两节电芯的差异被一次次充放电循环放大了。这就是一个最直观的比喻:整组电池的可用容量,永远由最差的那一节决定,就像流水线上速度最慢的工位决定了整条线的产出。

1.2 不均衡会自我放大,而且越拖越严重

如果放任这种差异继续发展,会进入一个典型的正反馈循环。充电时,容量较小的电芯先充满,却因为串联关系不得不继续被充电,于是被推向过压区;放电时,容量较小的电芯又先放空,整组负载被迫停止,另一节电芯明明还有电却放不出来。

更麻烦的是,过充和过放对电芯的损耗不是线性的。那节“短板电芯”每次循环都处在滥用边界上,容量衰减速度远快于其他电芯,于是它的短板程度越来越深,下一轮循环里整组容量又进一步缩水。等到差距大到一定程度,短板电芯内部可能已经出现析锂、胀气等不可逆损伤,这时就不是“少放出多少容量”的问题,而是安全风险的问题了。

这也是为什么我认为,储能和备用电源系统里的均衡不能当成可选项。备用电源的特点就是长期浮充、偶尔深度放电、大部分时间静置,这种工况恰恰最容易让自放电差异累积成电压差,如果不做均衡干预,电池寿命可能连设计值的一半都跑不到。

1.3 均衡的定位:抑制差异,而非追求完全一致

需要先明确一点:均衡的目标从来不是“把两节电芯电压做到小数点后三位完全一样”,那是既没必要也做不到的。均衡要解决的是“木桶效应”,是通过把高电压电芯的多余电荷释放掉,或者把能量搬运到低电压电芯里,把压差压缩到安全区间,防止某一节电芯反复触碰到充电截止电压或放电截止电压。

对 2S 这样的小系统来说,被动均衡已经足够。被动均衡的思路很直白:在电压偏高的电芯两端并联一条放电支路,通过电阻把它多余的能量以热量形式消耗掉。相比主动均衡需要的电感、电容和能量搬运拓扑,被动均衡电路简单、可靠性高、成本低,适合备用电源这种对体积和 BOM 成本敏感的场景。这个项目里,MP2642GR-Z 负责的就是这条放电支路的通断、限流和保护,而 STM32L151ZD 负责判断“什么时候该把这条支路打开、开多久、什么时候该关”。

2. 均衡执行层与决策层分离:MP2642GR-Z 和 STM32L151ZD 的职责切分

2.1 为什么不用纯 MOS 管方案

最原始的被动均衡电路很“简单粗暴”:一颗功率 MOS 加一颗功率电阻,MCU 的 GPIO 直接控制 MOS 开关。我在最早的项目里也是这么干的,但后续维护非常难受。

首先是被测电芯的共模电压问题。2S 电池组里,想要均衡上面那节电芯,MOS 的栅极驱动电压必须高于该电芯的电压,普通的 3.3V GPIO 根本直驱不了高边 NMOS,需要加电荷泵或驱动变压器;而低边均衡又只能放掉最低那节电芯的能量,实用性受限。其次是均衡电流的稳定性。外部功率电阻的温度系数很一般,电芯发热后均衡电流会漂,设计者还得自己算电阻功率、算散热、算 MOS 的 Rds(on) 温升,任何一个环节估算不到位,调试阶段就会露出马脚。

集成均衡芯片的做法把这一堆脏活扛了下来。以 MP2642GR-Z 这类带均衡管理功能的电源管理 IC 来说,它内部集成了均衡功率级和限流控制逻辑,MCU 只需给出使能信号和控制信号,剩下的“怎么稳定限流、怎么处理功率管驱动、怎么反馈状态”都在芯片内部完成。当然,具体到这颗芯片的引脚定义、限流设定电阻的计算方式、状态反馈寄存器,一定以官方数据手册里的典型应用电路为准,我这里重点讲设计分工和系统逻辑,不在寄存器级别展开。

2.2 MP2642GR-Z 在系统里的实际工作内容

MP2642GR-Z 在这个项目里的角色可以概括为“均衡执行单元”。当 STM32L151ZD 判断出某一节电芯电压偏高、需要释放多余电荷时,MCU 发出使能信号,MP2642GR-Z 内部就建立起一条并联在该电芯两端的放电通路,把电芯的多余能量以恒定电流的形式消耗在外部限流电阻上。

它带来的一个直接好处是,把“功率回路”和“控制回路”从物理上分开了。功率部分由芯片和外部电阻承担,MCU 的引脚只负责弱信号控制,不需要直接切换大电流。这样板子上的布局逻辑就非常清晰:均衡功率回路走粗短线,采样和控制走细线,两者不必纠缠在一起,后面调试定位问题也方便得多。

我建议在选择均衡电流目标值时,先查数据手册里限流设定电阻的计算方法,再结合散热条件确定目标电流。以我们这套样板为例,最初把均衡电流设定在 0.2A 验证逻辑,确认状态机跑通后才逐步调整到 0.5A 级别。这样既不会一上来就烧电阻,也能循序渐进地把电流相关参数整定出来。

2.3 STM32L151ZD 负责的决策任务

STM32L151ZD 在这个系统里承担三件事:测量、判决、执行调度。测量包括两节电芯的电压和板载温度;判决是基于“压差是否超过阈值”“温度是否在允许范围”“当前是否处于静置状态”等条件决定要不要开启均衡;执行调度则是用状态机管理均衡的开启、关闭、冷却和故障处理。

选这颗 MCU 的理由很实际。备用电源系统大部分时间处于待机状态,系统功耗是硬指标,STM32L151 作为超低功耗 MCU,在待机、停机模式下的电流可以做到微安级,对电池供电的备用电源来说非常关键。内部 12 位 ADC 对均衡所需的电压采集精度够用,UART、I2C 等通信外设也齐全,后续要接显示屏、上位机或者把状态上报到网关都有接口。作为 144 脚的高引脚数型号,L151ZD 的 IO 资源在这个项目里相当宽裕,以后扩展均衡通道也留有余量。

2.4 决策与执行分离带来的调试优势

这套架构最大的好处在于:任一侧出问题,都能快速隔离。均衡没动作,先看 MCU 有没有把使能信号送出来;信号正常但均衡电流不对,问题就在 MP2642GR-Z 的功率级或外部限流电阻;电流正常但电压还是拿不准,就往采样链路上查。

从硬件布局角度看,决策层和执行层的分离也有实际好处。MCU 可以用独立的参考地平面,采样线路可以避开功率回路;均衡芯片和功率电阻则布置在散热条件更好的位置,两者之间只有控制线和电流回路。我在画板时把均衡功率回路放在板边,把 MCU 和采样网络放在内侧,实测对 ADC 噪声有明显帮助。

对比维度纯分立 MOS + 电阻方案均衡 IC + MCU 方案
高边电芯均衡需要电荷泵或驱动变压器芯片内部解决驱动
均衡电流稳定性受电阻温漂影响明显芯片内部限流,稳定性好
设计工作量MOS 选型、驱动设计、热设计全靠自己按手册选型,工作量小
故障定位涉及环节多,难快速定位决策、执行清晰分层
元器件数量多少

3. 电压采集与均衡判决:固件状态机的具体实现思路

3.1 电压采集不是“读一下 ADC 就行”

很多人第一次做 BMS 固件时会以为,电压采集就是把 ADC 通道打开,跑一下 HAL 库函数读个值出来。实际做下来会发现,采样点取在哪里、分压电阻精度够不够、什么时候采样,直接决定均衡判决靠不靠谱。

2S 电池组的采集方式,我采用的是“总电压 + 中点电压”方案。两节电芯串联后的总正端对总负端就是总电压,中点对总负端就是下节电芯电压,两者相减得到上节电芯电压。之所以不直接把差分电压送到 MCU,是为了控制共模范围和简化前端设计。通过高阻分压网络,把总电压和中点电压都映射到 ADC 输入范围内,然后各自经过 RC 滤波进入 ADC 通道。

电压换算的核心公式不复杂:

V_total = ADC_total_code × Vref / 4095 × 分压系数

V_cell2 = ADC_mid_code × Vref / 4095 × 分压系数

V_cell1 = V_total - V_cell2

以参考电压 3.3V、12 位 ADC 计算,每个 LSB 对应大约 0.8mV,再乘上分压系数后,整个采样链路对电池电压的分辨率能到 1.6mV 左右。对于 20mV 量级的均衡阈值来说,这个分辨率完全够用。真正的误差来源反而在分压电阻精度和基准电压漂移上,这会在后面调试环节详细展开。

3.2 均衡判决里的滞回控制,防止反复震荡

均衡控制里最容易出现的问题就是“反复开关”。如果逻辑写成“压差大于阈值就开,小于阈值就关”,实际效果会非常灾难:均衡一开,压差立刻变小,然后关掉;关掉后极化电压恢复,压差又变大,于是又打开。系统会在几分钟内来回震荡,继电器和功率管跟着遭殃,电池也没有得到真正的均衡。

解决办法是加滞回区间。比如设置启动阈值为 20mV,停止阈值为 10mV;当压差超过 20mV 时开启均衡,当压差降到 10mV 以下时才关闭。中间那个 10mV 的区间就是“死区”,它让均衡动作不会因为微小的电压波动而频繁切换。滞回区间越大,动作越稳定,但也不能太大,否则压差会在 10 到 20mV 之间一直悬着不处理。实际整定下来,我这边的经验是启动阈值设为停止阈值的两倍左右,既能抑制震荡,又能保证足够的均衡深度。

3.3 固件状态机的划分与转换

整个均衡控制逻辑用一个简单的状态机管理。状态分为 IDLE(空闲)、MEASURE(采样)、DECIDE(判决)、BALANCE(均衡)、COOLDOWN(冷却)、FAULT(故障)。

IDLE 状态下 MCU 处于低功耗,按设定的周期醒来进入 MEASURE,完成两节电芯电压和温度采样后进入 DECIDE。DECIDE 是唯一做决策的环节,它根据压差、温度、当前运行状态判断是否开启均衡,然后转向 BALANCE 或回到 IDLE。BALANCE 状态下均衡持续执行,但不会无限执行,而是设定一个时间片,比如 30 秒到 60 秒后进入 COOLDOWN。COOLDOWN 的意思是:均衡回路关闭,等待电压极化恢复,同时让 ADC 采样的条件稳定下来,然后再回到 MEASURE 做新一轮判断。

这个“均衡—冷却—再测量”的循环非常重要。它既给了均衡电流散热的时间,也避免了在均衡通断瞬间采到电芯的瞬态电压,从源头上减少误判。核心伪代码大致是这样的:

typedef enum { IDLE, MEASURE, DECIDE, BALANCE, COOLDOWN, FAULT } bms_state_t; void bms_task(void) { switch (state) { case IDLE: if (wakeup_flag) state = MEASURE; break; case MEASURE: sample_cell_voltages(); state = DECIDE; break; case DECIDE: delta_mv = cell1_mv - cell2_mv; if (delta_mv > BAL_START_MV && temp_ok) { balance_channel = (cell1_mv > cell2_mv) ? CH_CELL1 : CH_CELL2; balance_timer = 0; state = BALANCE; } else { state = IDLE; } break; case BALANCE: enable_balance(balance_channel); balance_timer++; if (balance_timer >= BAL_TIME_SLICES) state = COOLDOWN; if (delta_mv < BAL_STOP_MV) state = COOLDOWN; if (temp_high) state = FAULT; break; case COOLDOWN: disable_balance(); if (cooldown_timer >= COOLDOWN_TIME) state = MEASURE; break; case FAULT: disable_balance(); report_fault(); break; } }

3.4 均衡使能条件与保护联动

均衡不是任何时刻都能开启的。温度是最直接的限制条件,电池低于 0 度或高于 45 度时,电芯内部特性会变,此时给高电压电芯放电可能造成不可预期的结果,所以温度不满足就只告警不均衡。电压方面也有两个保护边界:均衡过程中如果被均衡的电芯电压掉到欠压保护线以下,说明它已经不是“偏高”而是“偏低”了,继续进行被动均衡只会加剧过放,此时应立即关断并上报。

另外,充电过程中的均衡需要谨慎。充电状态下,极化电压会导致电芯端电压虚高,以这种电压作为均衡判决依据容易误判。我这套样板的做法是:优先在静置或轻负载状态下执行均衡,充电状态只监测不做均衡判决。对于 2S 备用电源来说,设备待机时间远比充电时间长,静置均衡已经能覆盖绝大多数需要均衡的场景。

4. 均衡参数实测:阈值、滞回、时长的整定过程

4.1 均衡电流从 0.2A 起步,再逐步加大

均衡电流的选择要兼顾收敛速度和热设计。电流太小,压差收敛需要几个小时,用户体验差;电流太大,首先功率电阻发热严重,其次 PCB 铜箔和均衡芯片本身的应力也大。被动均衡的本质是把高电压电芯的能量通过电阻转成热量,以电芯电压 3.2V、均衡电流 0.5A 计算,功率约 1.6W。这个热量如果集中在一颗 0805 电阻上,温度马上会飙到很高,所以要选足够功率裕量的电阻,并且给电阻周围留出散热空间。

我的调试顺序是:先用 0.2A 验证环路逻辑,确认状态机能正确开启、停止、冷却,然后逐步调到 0.5A 做完整测试。整个过程没有跳过中间档位直接上大电流,理由很简单:被动均衡在电芯高电压时瞬间功率最大,如果外围器件散热能力不够,大电流模式下故障发生速度会很快,不利于排查。

4.2 一次完整的压差收敛记录

为了验证均衡逻辑,我用可调电源模拟出“故意不平衡”的状态,让两节电芯初始压差为 45mV,然后开启 0.5A 均衡,每隔一段时间记录压差变化。下面是一组有代表性的实测数据。

时间(min)压差(mV)状态
045均衡开启
1037均衡中
2030均衡中
3024均衡中
4518均衡中
6012压差低于停止阈值,均衡关闭

这组数据有两个值得注意的地方。第一,压差下降不是线性的,前 20 分钟下降速度快,后面越来越慢。原因是压差越小,被放电电芯相对反电动势的“推动力”越弱,收敛就越趋于平缓。第二,在 60 分钟时压差进入 10mV 滞回区,系统自动停止均衡,没有出现反复震荡。这说明状态机的判决逻辑和滞回参数的配合是符合预期的。

4.3 均衡阈值怎么定:不是越小越好

均衡启动阈值的设置有讲究。设得太小,比如 5mV,系统会频繁进入均衡流程,每次均衡都会消耗一定能量并增加功率器件的循环次数,而且 5mV 的压差可能只是电芯表面的极化波动,并不是真实的容量差,频繁处理反而是干扰。设得太大,比如 100mV,那均衡就完全失去预防作用,相当于等电芯已经明显不健康了才开始补救。

对于磷酸铁锂 2S 系统,因为放电平台很平,电压差异很容易被极化电压掩盖,我的经验是把启动阈值整定在 20 到 50mV 之间,停止阈值取阈值的一半。如果是三元锂,平台特性不同,阈值可以适当放宽。更讲究一点的做法是结合电芯 SOC 曲线换算成“等效容量差”来定阈值,但对于 2S 备用电源这种小系统,按电压阈值处理已经足够实用。

4.4 均衡时间上限:防止“无限放电式”均衡

被动均衡一旦开启,高电压电芯的能量就被持续消耗。但均衡只是放掉“多余”的那部分电荷,如果某节电芯因为内阻大、端电压虚高而持续被均衡,它的真实 SOC 可能已经消耗过头,再继续放电就是过度放电了。所以必须给均衡时间设置上限。

我这边的策略是:单次均衡持续时间上限为 2 小时。如果 2 小时到了压差还没收敛,说明电芯本身的状态可能已经超出均衡能解决的范围,此时停止均衡并置一个“均衡超时”告警位,提示人工检查电池组。同时把均衡历史累计时长写入 EEPROM,方便后续维护人员判断电芯的健康趋势。有一次我发现某块电池每次静置后都需要长时间均衡,查了均衡历史记录才知道,这块电池的自放电异常早就已经有征兆了。

5. 样板调试中的五个典型坑与对应解法

5.1 ADC 基准源“看着稳,实际飘”

12 位 ADC 的理论分辨率很好,但实际读数会受参考电压影响。早期我直接用 MCU 的内部基准,室温下测试没太大问题,后来把板子放进高温箱,发现同一节电芯在不同温度下测出的电压能差出好几个毫伏。对于 20mV 的均衡阈值来说,这个漂移量足以造成误判。

解决方式有两种。硬件上,改用外部基准电压源,把参考电压稳定在 3.3V 或 2.5V;软件上,做两点校准,把 ADC 的增益误差和偏移误差在产线或首次上电时标定掉。对成本敏感的产品可以先做软件校准,如果温度范围很宽再考虑外部基准。我这边最终是外部基准加软件校准一起上,采样稳定性明显提升。

5.2 采样点被均衡回路“污染”

这是我在调试中踩过最深的一个坑。最初布线时,电压采样点直接从均衡电阻的一端引出,结果发现每次均衡一开启,采样到的电压就跳变一下,而且跳变方向和处理逻辑完全对不上。原因很直接:均衡电流经过采样点到电芯端子之间的铜箔时,铜箔电阻上产生了压降,等于把“电芯实际电压 + 布线压降”一起送进了 ADC。

解决这个问题必须用开尔文接法。采样线从电芯端子的根部单独引出,走线要细,和均衡功率回路完全分开,不要共线、不要平行长距离走线。改板之后,均衡通断对采样值的影响基本消失。如果调试时发现“采集值随均衡通断跳动”,优先查的就是这条采样线的走线路径。

5.3 均衡通断瞬间的 ADC 毛刺

均衡电流从 0 跳到 0.5A 的瞬间,电流环路会产生较大的 di/dt,通过地平面耦合进采样网络,造成 ADC 读到瞬时尖峰。我在状态机时间片设计里加入了“均衡开启后延时 20 到 50ms 再采样”的处理,同时硬件上在 ADC 输入端增加 RC 滤波,把毛刺衰减掉。不要小看这个细节,如果采样恰好发生在均衡切换瞬间,一次尖峰就可能触发错误的均衡判决。

5.4 温度传感器摆错位置导致的虚假过温

均衡电阻工作一段时间后温度会明显上升。如果 NTC 温度传感器离均衡电阻太近,系统会读到虚假的高温,触发过温保护,把均衡中断。开始我以为是均衡电流太激进,反复降电流仍然有这个问题,后来用热像仪一看,NTC 直接被电阻的辐射热烤着,读数比电池实际温度高出十几度。

正确做法是把温度传感器放在尽量反映电池本体温度的位置,避开均衡功率器件的热辐射路径。同时可以在软件里对温度采样做一定的低通滤波,避免单次瞬时高温读数直接触发故障。需要说明的是,这属于通用工程经验,具体摆放位置要根据实际板型做热验证。

5.5 低功耗唤醒后立即采样的假数据

备用电源场景下 MCU 大部分时间在低功耗模式,靠定时器周期性唤醒。这个模式有一个隐蔽问题:唤醒瞬间,MCU 内部基准、ADC 电路和外部供电轨都还没完全稳定,立即采样读到的电压可能偏差很大。正确的做法是唤醒后先延时几十毫秒,等参考电压建立稳定后再启动采样。这个问题在普通工频供电系统里不容易看到,一旦切到电池供电的低功耗场景就会冒出来。

针对这五个问题的排查思路,我整理了一个简表,方便快速对照。

现象根因方向对应解法
不同温度下同节电压读数漂移基准电压不稳外部基准 + 软件校准
均衡通断导致采集值跳变采样点与功率回路共用走线开尔文采样走线
切换瞬间读到尖峰地噪声耦合、滤波不足RC 滤波 + 采样延时
均衡被反复中断NTC 位置受热干扰调整温度传感器位置
唤醒后第一次采样异常电源和基准未建稳唤醒延时后再采样

6. 从两串样板走向多串系统的扩展预留

6.1 两串是最小闭环,也是最值得打牢的基础

很多人一上来就想做 16 串、20 串的 BMS,但在我看来,先把 2S 这套最小闭环做稳才是最高效的路径。两串系统里,所有核心问题都会出现:串联电芯共模电压、压差阈值整定、均衡通断控制、采样干扰、低功耗唤醒。这些问题在 2S 上想清楚,扩展到更多串只是“复制基础单元 + 增加通道管理”,而不需要在原理层面重新摸索。

我在设计这块样板时已经刻意做了扩展预留。STM32L151ZD 的引脚资源非常充裕,每一路均衡使能独立使用一个 GPIO,采样通道也可以扩展到更多模拟输入。MP2642GR-Z 这类均衡管理芯片在支持多串时,可以按每两串一个基础单元的方式来组合,MCU 侧的资源消耗不会因为通道数增加而成倍恶化。

6.2 扩展到多串时的注意点

通道数增加后,要注意三件事。首先是采样通道的轮询顺序和时序,均衡状态、非均衡状态下的采样时间点要统一规划,避免不同通道之间的时间差造成电压读数偏差。其次是共模电压范围,串数越高,被采样节点的电位越高,分压网络必须重新计算,保证在任何正常电压范围内 ADC 输入都不超限。最后是均衡策略的集中管理,多串系统里高、中、低节电芯之间会有更复杂的差异,简单“压差超过阈值就均衡”的逻辑不够用,需要按各节相对中位数的偏离程度来决定优先均衡哪一节。

6.3 状态上报与可观测性设计

做储能和备用电源系统,均衡状态必须能看得到。我在样板上预留了 UART 和 I2C 接口,上报内容包括两节电芯的实时电压、压差、当前均衡状态、累计均衡时长、温度以及故障码。有了这些数据,上位机可以画出一条压差收敛曲线,维护人员也能直观判断电池组是否健康。

均衡历史记录写入非易失存储这一点尤其推荐保留。有一次我查看一块返修电池,发现均衡累计时长明显高于其他电池,但实时电压看不出异常,正是这条历史记录帮助定位到了自放电异常的电芯。对备用电源这种“大部分时间没人盯着”的设备来说,历史数据比实时数据更有价值。

最后再分享一个调试阶段很实用的技巧:不要等真实电池慢慢失衡,直接用可调电源把两路输入“人为”设置成不同的电压,比如一路设定 3.60V、另一路设定 3.40V,然后观察状态机是否按预期开启均衡、压差是否收敛、滞回区间的动作是否稳定。这样一轮验证下来只需要几分钟,比装电池实跑大半天高效得多。均衡逻辑这种东西,光靠看代码很难看出问题,真正逼出 bug 的往往是刻意制造的不平衡。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进