ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

两串锂电池被动均衡实战:MP2642GR-Z与STM32L152ZD硬件设计与固件策略

两串锂电池被动均衡实战:MP2642GR-Z与STM32L152ZD硬件设计与固件策略

1. 为什么串联电池组的均衡不是"可选功能"而是"生存刚需"

两节锂电池串联,标称电压7.4V,满电8.4V,放到6.0V截止——这是很多便携储能设备、备用电源模块、小型UPS里最常见的架构。看起来简单,但真正做过电池管理的人都知道,串联结构里最要命的从来不是总电压够不够,而是两颗电芯在几百次充放电循环之后还能不能"步调一致"。

我先说一个实测数据。两节同批次、同容量、出厂内阻差异在3%以内的18650电芯,经过300次0.5C充放电循环后,端电压差可以拉开到80mV以上;如果其中一颗散热条件稍差,差异能超过150mV。这个数字放在单节电池上无所谓,但串联结构里,充电时截止条件由总电压或最高单体电压决定,放电时截止条件由最低单体电压决定。结果就是:容量小的那颗永远先到上限、先到下限,容量大的那颗永远"吃不饱也放不干净"。循环下去,差距越拉越大,整组可用容量可能只剩单节的70%甚至更低。

这就是为什么被动均衡电路几乎是串联电池包的标配。而MP2642GR-Z这颗芯片,就是专门干这个事的——它是一颗面向2串电池组的均衡管理IC,集成度高、外围简单,配合STM32L152ZD这类低功耗MCU,可以搭出一套成本可控、逻辑清晰的均衡系统。

这篇文章面向的是正在做储能BMS、备用电源管理板、或者便携设备电池包的硬件和嵌入式工程师。我会从芯片选型逻辑、硬件设计细节、STM32控制策略、均衡算法实现、实测踩坑五个维度,把"两串电池均衡"这件事从头到尾讲透。不管你是第一次接触电池均衡,还是已经做过几版板子想优化,都能从中找到可以直接抄作业的东西。

2. MP2642GR-Z的引脚逻辑与外围电路设计要点

2.1 这颗芯片到底解决了什么问题

MP2642GR-Z是一颗2串电池均衡前端,核心功能可以拆成三块:单体电压采集、均衡电流通路控制、过压/欠压保护信号输出。它不像BQ系列那样集成完整的电量计和通信协议栈,而是把"均衡"这件事做得很纯粹——你给它两节电池,它帮你监测每节的电压,当MCU判断需要均衡时,它负责把均衡电阻接入对应电芯两端。

这种"前端+MCU"的分工模式,好处是灵活。均衡阈值、均衡时长、均衡策略全部由STM32L152ZD的固件决定,硬件只负责执行和采集。坏处是你得自己写逻辑,没有现成的库可以调。但对于做储能和备用电源的团队来说,这反而是优势——策略可以按自己的电池特性定制,不用被芯片厂商的固定逻辑绑死。

2.2 关键引脚的功能拆解

MP2642GR-Z的引脚不多,但每一个都直接影响系统可靠性。我按实际布线时的关注优先级来说:

VC1、VC2、VC3是电压采集引脚,分别接电池组负极(B-)、两节电池中间点(B1)、电池组正极(B2)。这三个引脚决定了芯片对每节电芯电压的读取精度。实际布线时,VC2这个中间点采样线必须单独走一根线到电池连接器,绝对不能从均衡电阻的焊盘上"借"一个点。我见过一块板子为了省一根线,把VC2和均衡电阻的中间节点共用,结果均衡一开启,采样电压就被均衡电流在走线电阻上的压降污染,读数偏差超过50mV,均衡逻辑直接跑飞。

CB1、CB2是均衡控制输出,分别对应第一节和第二节电芯的均衡开关。芯片内部是开漏结构,外部需要接均衡电阻到对应电芯的正极。均衡电阻的选型后面单独讲。

VIN是芯片供电,通常直接从电池组正极取电。注意MP2642GR-Z的耐压范围,两串满电8.4V在它的工作区间内,但如果你做的是热插拔场景,插拔瞬间的浪涌可能冲到10V以上,建议在VIN前面加一颗TVS和一个小容量陶瓷电容做缓冲。

GND必须和电池组负极B-单点连接,不要和MCU的GND在多个点乱接,否则均衡电流会在地平面上产生压差,影响采样精度。

2.3 均衡电阻的计算与选型

均衡电阻是这套系统里唯一"耗电"的元件,它的阻值直接决定均衡电流大小和发热量。计算公式很简单:

I_balance = V_cell / R_balance

假设单节电芯电压3.7V,你希望均衡电流在50mA左右,那么R_balance = 3.7V / 0.05A = 74Ω,取标准值75Ω。功耗P = I²R = 0.05² × 75 = 0.1875W,选0805封装勉强够,但长期工作建议上1206或者两颗0805并联,留足降额。

这里有个经验值:均衡电流一般取电池容量的1%到3%。比如你用的是2000mAh的电芯,均衡电流20mA到60mA都合理。太小了均衡效果慢,太大了发热严重且浪费能量。储能系统里如果对均衡速度要求高,可以取到5%,但必须做好电阻的散热铺铜。

还有一个容易被忽略的点:均衡电阻要接在电芯正极和CB引脚之间,而不是接在CB引脚和地之间。因为CB1对应的是第一节电芯(负极接B-),CB2对应第二节电芯(负极接B1)。接错了均衡电流会流错电芯,越均衡越不平衡。

2.4 采样滤波与抗干扰设计

电池均衡系统工作在开关噪声环境里,采样线上的高频干扰如果不处理,MCU读到的电压值会跳来跳去。我的做法是在VC1、VC2、VC3每个引脚到GND之间并一颗100nF的陶瓷电容,位置尽量靠近芯片引脚。同时在采样线串联一颗100Ω的电阻,和电容组成RC低通滤波,截止频率约16kHz,足够滤掉均衡开关产生的毛刺。

但注意,串联电阻会引入压降。芯片的采样输入阻抗通常在兆欧级别,100Ω串联电阻上的压降可以忽略不计。如果你选的电阻超过1kΩ,就要重新评估采样误差了。

3. STM32L152ZD在均衡系统里的角色定位与资源分配

3.1 为什么选L152ZD而不是更便宜的F103

STM32L152ZD是L1系列里的高配型号,Cortex-M3内核,带LCD控制器、12位ADC、多个定时器和丰富的低功耗模式。放在电池均衡系统里,它的核心价值不在算力,而在低功耗和模拟外设精度。

储能和备用电源设备很多时候是长期待机、偶尔工作的模式。L152ZD在Stop模式下典型电流不到1μA,RTC走时加上少量RAM保持,整机待机功耗可以压到微安级别。相比之下,F103的Stop模式在20μA左右,对于靠电池长期供电的备用电源来说,这个差距在几年维度上就是能不能多撑半年的区别。

另外L152ZD的ADC在低功耗模式下依然能保持不错的线性度,配合内部参考电压,单体电压采样精度可以做到±10mV以内,满足均衡判断的需求。

3.2 外设资源怎么分配

在这套系统里,STM32L152ZD需要干这几件事:

  • ADC多通道扫描:至少两路采集两节电芯电压,如果要做温度补偿,再加一路NTC采样。用DMA搬运ADC结果,避免CPU频繁中断。
  • GPIO输出:控制MP2642GR-Z的均衡使能引脚,或者直接控制均衡开关的使能逻辑。具体取决于你的硬件设计——如果MP2642GR-Z的CB引脚是开漏输出,MCU只需要给芯片一个"允许均衡"的信号,具体哪节均衡由芯片内部逻辑决定;如果你想让MCU完全掌控,也可以把CB引脚的控制权拿过来,用GPIO直接驱动外部MOS。
  • 定时器:一个低功耗定时器用来做均衡周期的时基,比如每100ms采样一次,每10s判断一次均衡需求。
  • UART或I2C:如果设备需要上报电池状态,留一个通信接口给上位机或主控。
  • 看门狗:电池管理系统死机是灾难性的,独立看门狗必须开。

3.3 低功耗模式下的采样策略

这是整个固件设计里最需要动脑子的地方。你不能让MCU一直跑在Run模式下做ADC采样,那样待机功耗下不来。我的做法是:

  1. MCU大部分时间在Stop模式,RTC定时唤醒,比如每500ms醒一次。
  2. 醒来后快速启动ADC,用DMA采集两节电芯电压和温度,整个过程控制在1ms以内。
  3. 判断是否需要均衡。如果电压差小于阈值(比如20mV),直接回Stop模式。
  4. 如果需要均衡,开启均衡通路,然后MCU可以继续回Stop模式,让硬件自己均衡,定时唤醒检查一次即可。
  5. 均衡过程中如果检测到单体电压低于欠压阈值,立即停止均衡并进入保护逻辑。

这套策略实测下来,均衡期间的整机平均电流在2mA左右(主要是均衡电阻的电流),非均衡待机电流可以做到15μA以下。

4. 均衡策略的固件实现:从阈值判断到状态机

4.1 什么时候该启动均衡

最简单的逻辑是"压差超过阈值就均衡",但实际做下来,这个逻辑需要加好几个限定条件,否则会频繁误动作。

我用的判断条件是这样的:

  • 两节电芯压差 > 30mV
  • 较高那节电芯电压 > 3.4V(避免在低电量时均衡,那时候电压曲线陡,压差可能是负载造成的假象)
  • 电池组不在充电状态,或者充电电流小于0.1C(充电时均衡会干扰充电截止判断)
  • 温度在5℃到45℃之间(低温均衡效率低,高温均衡有安全风险)

这几个条件同时满足,才启动均衡。实测下来,这样可以把误均衡的次数降到很低,同时保证真正需要均衡的时候不会漏掉。

4.2 均衡状态机的设计

我用一个简单的四状态机来管理均衡过程:

IDLE:空闲状态,定时采样,判断是否需要进入均衡。

BALANCING:均衡进行中。记录当前均衡的是哪一节,开启对应的均衡通路,启动一个均衡超时定时器(比如单次最长均衡30分钟)。

COOLDOWN:均衡暂停。每次均衡持续比如60秒后,暂停10秒,让电芯电压回稳,再重新采样判断。这个"脉冲式均衡"比连续均衡更安全,也更容易观察电压变化趋势。

FAULT:故障状态。如果检测到电压异常(比如某节电压突然掉到2.5V以下,或者温度超限),立即关闭所有均衡通路,置故障标志,等待人工复位或自动恢复条件满足。

状态之间的迁移条件全部由采样结果驱动,没有任何阻塞式延时,保证MCU随时可以响应异常。

4.3 电压采样的软件滤波

ADC读回来的原始值不能直接用。我的做法是:连续采16次,去掉最大和最小的各2个,剩下的12个取平均。这样做的成本很低,但能有效滤掉偶发的尖峰干扰。

另外,电芯电压在均衡开启和关闭的瞬间会有跳变——均衡电流在电芯内阻上产生压降,关闭瞬间电压会"弹"回来。所以采样时机很重要:在均衡关闭后至少等待500ms再采样,让电压稳定下来。这个等待时间根据电芯的极化特性来定,大容量电芯需要更长。

4.4 代码框架示例

下面是我在实际项目中用的一个简化版均衡控制循环,基于STM32 HAL库,跑在L152ZD上:

#define BALANCE_THRESHOLD_MV 30 #define BALANCE_MIN_CELL_MV 3400 #define BALANCE_MAX_TEMP 45 #define BALANCE_MIN_TEMP 5 #define BALANCE_ON_TIME_MS 60000 #define BALANCE_OFF_TIME_MS 10000 #define BALANCE_TIMEOUT_MS 1800000 typedef enum { BAL_IDLE, BAL_ACTIVE, BAL_COOLDOWN, BAL_FAULT } bal_state_t; static bal_state_t bal_state = BAL_IDLE; static uint32_t bal_timer = 0; static uint8_t bal_target = 0; // 0: none, 1: cell1, 2: cell2 void balance_task(void) { uint16_t v1 = adc_get_cell1_mv(); uint16_t v2 = adc_get_cell2_mv(); int16_t temp = ntc_get_temp(); int16_t diff = (int16_t)v1 - (int16_t)v2; uint16_t vmax = (v1 > v2) ? v1 : v2; switch (bal_state) { case BAL_IDLE: if (abs(diff) > BALANCE_THRESHOLD_MV && vmax > BALANCE_MIN_CELL_MV && temp > BALANCE_MIN_TEMP && temp < BALANCE_MAX_TEMP) { bal_target = (diff > 0) ? 1 : 2; balance_enable(bal_target); bal_timer = HAL_GetTick(); bal_state = BAL_ACTIVE; } break; case BAL_ACTIVE: if (HAL_GetTick() - bal_timer > BALANCE_ON_TIME_MS) { balance_disable(); bal_timer = HAL_GetTick(); bal_state = BAL_COOLDOWN; } if (v1 < 2500 || v2 < 2500 || temp > 60) { balance_disable(); bal_state = BAL_FAULT; } break; case BAL_COOLDOWN: if (HAL_GetTick() - bal_timer > BALANCE_OFF_TIME_MS) { bal_state = BAL_IDLE; } break; case BAL_FAULT: // 等待恢复条件 if (v1 > 3000 && v2 > 3000 && temp < 50) { bal_state = BAL_IDLE; } break; } }

这段代码的核心思路是:均衡不是一直开着的,而是"开60秒、关10秒"的脉冲模式。关闭的10秒用来让电芯电压回稳,然后重新判断。这样既避免了连续均衡导致的电压误判,也给电芯一个"喘息"的机会。

5. 实测中暴露的问题与排查过程

5.1 均衡开启后采样值反而更离谱

第一版板子调试时遇到一个怪现象:均衡没开的时候,两节电芯电压读数正常,压差25mV左右;一旦开启均衡,被均衡那节的电压读数直接掉了100mV,压差变成负的,逻辑判断完全乱套。

排查过程是这样的:先用万用表直接量电芯两端,确认实际电压没有变化,说明是采样问题。然后示波器抓VC2引脚的波形,发现均衡开启瞬间有一个明显的负向尖峰。顺着走线查,发现VC2的采样线有一段和均衡电阻的走线平行走了3cm,两者之间形成了容性耦合。均衡电流的开关动作通过这段寄生电容耦合到了采样线上。

解决办法有两个:一是把采样线改道,远离功率走线;二是在VC2引脚处加一颗1μF的电容到GND,增强抗干扰能力。我两个都做了,问题彻底消失。这个坑告诉我,电池采样线在PCB上必须当作敏感模拟信号来对待,不能随便走。

5.2 均衡电阻发热导致温度漂移

第二版板子把均衡电阻从0805换成了0603,想省空间。结果连续均衡10分钟后,电阻表面温度超过90℃,旁边的NTC温度传感器读数被带偏了8℃。因为温度判断逻辑里有一个"温度超过45℃停止均衡"的条件,结果系统误以为环境温度过高,频繁中断均衡。

后来把均衡电阻换回1206,并且在电阻下方铺了一块铜皮帮助散热,同时把NTC挪到离电阻至少15mm的位置。再测,连续均衡30分钟,电阻温度稳定在65℃左右,NTC读数偏差小于2℃。

这里的原则是:均衡电阻的功耗虽然不大,但集中在很小的封装里,热密度很高。选型时不要只看功率够不够,还要看散热条件。如果空间允许,用两颗电阻并联分担功耗,比用一颗大功率电阻更稳妥。

5.3 低功耗模式下ADC唤醒时间不够

L152ZD从Stop模式唤醒后,ADC需要一定的稳定时间才能开始有效转换。我一开始没注意这个,唤醒后立刻启动ADC,读到的前几次值全是垃圾,导致均衡判断偶尔误触发。

查手册发现,ADC从使能到第一次有效转换需要大约1μs的稳定时间,但内部参考电压的稳定时间更长,大概需要3ms。所以我在唤醒后加了一个3ms的延时,然后再启动ADC转换。这3ms的额外功耗微乎其微,但采样可靠性大幅提升。

5.4 均衡逻辑在充电时的干扰

充电过程中,充电电流在电芯内阻上产生压降,导致采样到的电压偏高。如果这时候开启均衡,均衡电流和充电电流叠加,采样值更加不准。我最初的逻辑没有区分充电和放电状态,结果充电时均衡频繁启停,效率很低。

后来加了一个充电检测:如果电池组总电压在持续上升,或者充电器有插入信号,就暂停均衡,等充电结束后再均衡。这个改动让均衡效率提升了将近一倍。

6. 从两串到多串:这套方案的扩展边界

6.1 两串架构的天然局限

MP2642GR-Z加STM32L152ZD这套方案,定位很明确:两串电池组的低成本均衡。它的优势是外围简单、固件可控、功耗低。但如果你要做4串、8串甚至更多,这套架构就不够用了——你需要多颗MP2642GR-Z级联,或者换用支持更多串数的前端芯片。

级联的方案不是不行,但每增加一颗芯片,就多一组采样线和均衡通路,PCB布局的复杂度直线上升。而且多颗芯片之间的地电位不同,采样参考点不一致,软件上要做额外的校准。我的建议是:两串用这套方案,四串以上直接上专用AFE,不要硬撑。

6.2 被动均衡 vs 主动均衡的取舍

这套方案做的是被动均衡——把电压高的电芯多余的能量通过电阻消耗掉。效率低,但成本低、可靠性高、电路简单。主动均衡是把能量从高电压电芯搬到低电压电芯,效率高,但需要电感、电容和复杂的开关网络,成本和故障率都上去了。

在储能和备用电源场景里,被动均衡在绝大多数情况下够用。因为这类设备的充放电倍率通常不高,电芯之间的差异主要来自制造一致性和老化速度,均衡电流不需要很大,几十毫安足够在每次充放电循环中把差异拉回来。主动均衡更适合大倍率、频繁充放电的场景,比如电动工具或电动车。

6.3 固件层面的可移植性设计

虽然这套方案是给两串设计的,但固件里的均衡状态机、采样滤波、故障保护逻辑,可以很容易地移植到更多串数的系统里。我的做法是把"电芯数量"和"均衡通道映射"做成配置参数,底层驱动抽象成统一的接口。这样以后换用支持4串的AFE,上层逻辑几乎不用改,只需要重新实现底层的采样和均衡控制函数。

具体来说,我会定义一个结构体来管理每个均衡通道:

typedef struct { uint8_t cell_index; uint16_t voltage_mv; uint8_t balancing; uint32_t balance_start_ms; } cell_balance_t; cell_balance_t cells[MAX_CELLS];

上层逻辑遍历这个数组,找出最高和最低电压的电芯,决定均衡哪一节。底层只需要提供cell_read_voltage()和cell_set_balance()两个函数。这样换硬件平台的时候,改动量最小。

7. 几个容易被忽略的工程细节

7.1 电池连接器的接触电阻

两串电池组的中间点连接器如果接触电阻偏大,均衡电流流过时会产生额外压降,导致采样到的中间点电压偏移。我实测过一个劣质连接器,接触电阻在20mΩ左右,50mA均衡电流下产生1mV压降,看起来不大,但如果连接器老化到100mΩ,压降就是5mV,已经接近均衡阈值的六分之一了。

所以连接器要选镀金触点、额定电流留足余量的型号。如果设备会经历振动,还要考虑连接器的防松设计。

7.2 均衡期间的EMI问题

均衡电流是直流,但开关的瞬间会产生高频分量。如果设备对EMI有要求,均衡走线要尽量短,必要时在均衡电阻两端并一颗小电容(比如100nF)来减缓开关边沿。但注意电容不能太大,否则均衡开关的功耗会增加。

7.3 长期存储后的首次上电

电池组长期存储后,两节电芯的自放电速率不同,压差可能很大。这时候如果直接开启均衡,大压差会导致大均衡电流(因为均衡电阻是固定的,压差大意味着高电压那节电芯的均衡电流略大,但差异不大)。真正的问题是:如果压差超过500mV,说明电芯可能已经损坏或者保护板有漏电,这时候不应该均衡,而应该报警。

我在固件里加了一个判断:如果压差超过300mV,直接进入FAULT状态,不尝试均衡,等待人工检查。这个阈值可以根据电芯特性调整,但原则是:均衡只能修正小差异,不能修复大问题。

7.4 均衡次数的统计与寿命评估

STM32L152ZD的Flash里可以存一些统计信息,比如累计均衡时间、均衡次数、历史最大压差。这些数据对于评估电池组健康状态很有价值。如果发现均衡越来越频繁,说明电芯一致性在恶化,可能需要提前更换。

我通常会在固件里留一个简单的日志区,每次均衡结束后更新统计数据。通过UART读出来,就能看到电池组的"健康曲线"。

8. 写在最后:这套方案适合谁,不适合谁

如果你在做的是两串锂电池的储能模块、备用电源、便携设备电池包,对成本敏感、对功耗有要求、希望均衡策略可以自己掌控,那MP2642GR-Z加STM32L152ZD这套组合是很务实的选择。硬件不复杂,固件也不难写,调试过程中注意采样线的抗干扰和均衡电阻的散热,基本不会踩大坑。

但如果你需要的是高精度电量计、复杂的保护逻辑、或者多串大电流均衡,这套方案就不合适了。该上专用AFE就上专用AFE,该用主动均衡就用主动均衡,不要为了省成本硬撑。

我个人在实际项目里的体会是:电池均衡系统的可靠性,八成取决于硬件设计,两成取决于固件逻辑。采样线走好了、均衡电阻选对了、地平面处理干净了,固件只要不犯低级错误,系统就能稳定跑。反过来,硬件有缺陷,固件再怎么补都补不回来。所以如果你正在画板子,多花点时间在布局布线上,比多写几百行代码划算得多。

RELATED READING

延伸阅读

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