前阵子做了一套 2 串锂电的均衡控制方案,用的是 MP2642GR-Z 做采样和均衡通道,PIC24FV16KA304 做策略控制和低功耗管理。“两节电池均衡”听起来是个小项目,但真正放到储能柜、备用电源这种需要长期待命的场景里,要处理的细节一点都不少:静置判定、极化恢复、滞环控制、温度保护,每一项做不好都会让均衡变成“越均越乱”。这篇文章就把这套方案的软硬件设计、参数计算、状态机实现和调试中踩过的坑,完整梳理一遍,给做储能 BMS 或备用电源的同行一个可参考的模板。
1. 开始之前:电池均衡到底解决什么问题
1.1 串联电池的“木桶效应”
很多刚开始接触电池系统的朋友会有一个直觉:两节串联的电池,充电时就按相同电流充,电压应该差不多,为什么非要加均衡?现实里这个直觉完全不成立。即使是同一批次、同一产线的电芯,容量、内阻、自放电率都存在分散性。举例来说,标称 2000mAh 的两节电芯,实际可能会有 1950mAh 和 2050mAh 的差异。
这个问题在串联系统里会被“木桶效应”无限放大。充电时,容量小的电芯先到 4.2V 满电电压;如果系统继续充电,这节电芯就会进入过充区域,轻则加速衰减,重则带来安全隐患。放电时也一样,容量小的先到截止电压,系统为了保护它只能提前停止放电,于是容量大的那节还剩下不少能量,白白浪费。整个串联电池的可用容量,实际上由最差的那节电芯决定。
均衡的核心目标,不是把电芯变得一模一样,而是让每一节电芯都工作在安全、高效的电压区间内,不因个体差异导致某一节被“拖累”。在这个项目里,MP2642GR-Z 负责监测每一节电芯的实时电压,PIC24FV16KA304 则根据这些电压数据,决定是否对电压偏高的一侧进行放电处理。
1.2 均衡不是充电器:被动均衡的原理
常见的均衡方案分为主动均衡和被动均衡。主动均衡通过电感、电容或 DC/DC 变换器,把高能量电芯的电荷转移到低能量电芯,效率高但成本也高,电路复杂,适合大容量动力电池组。被动均衡则简单得多:给电压偏高的电芯并联一个放电电阻,把多余的能量以热量形式耗散掉。
这套方案走的是被动均衡路线。MP2642GR-Z 内部集成了均衡控制通道,可以理解为一个小开关,MCU 控制开关导通后,电压高的电芯就会通过外部限流电阻放电,直到它和另一节电芯的电压差缩小到可接受范围。
用两个水桶来比喻这个过程:两个桶水位不一致,主动均衡是拿个小泵从高的桶往低的桶抽水,被动均衡则是直接把高桶的龙头打开放掉一些水,让两个桶都维持一个安全水位。对于 2 串、小容量的储能和备电场景,被动均衡的成本和可靠性优势非常明显,几十毫安的放电电流已经足够解决绝大多数静态不均衡问题。
1.3 两串场景为什么也不能省略均衡
有些做备电的同行会问:两串而已,容量也不大,能不能把均衡省略掉?我的建议是不到万不得已不要去省。
备用电源和储能系统有一个显著特征:电池大部分时间处于浮充或静置状态,很少做完整的充放电循环。这种工况下,电芯自放电率的差异会慢慢累积成明显的电压差。一开始可能只有 5mV,放几个月变成 20mV,一年后可能到 50mV 以上。不做均衡,就意味着每次浮充都会有一节电芯被过充,另一节长期欠充,整个电池组的寿命会被大幅度压缩。
另外,从系统可靠性角度看,均衡功能本身也是一种故障检测手段。通过定期采样每节电芯电压并计算压差,MCU 可以提前发现异常电芯。这套方案采集到的电压数据不仅仅是给均衡用的,也可以上报给上位机做健康度评估,相当于多了一层诊断能力。所以不要因为只有两串就砍掉均衡,把均衡模块当成基础配置,长期运营的收益远大于这点硬件成本。
2. 芯片分工与选型逻辑
2.1 MP2642GR-Z 在系统里的角色
MP2642GR-Z 这颗芯片在我的项目里定位是“模拟前端”,也就是 AFE(Analog Front End)。它主要承担三类任务:多通道电压采样、均衡通道控制、以及与 MCU 的通信。
先说电压采样。两串电池需要采集单体电压 V1、V2,以及串联总压 VBAT。如果直接用 MCU 的 ADC 去采,会面临共模电压、地弹噪声、采样保持时间不足等一系列问题。MP2642GR-Z 这类专用前端芯片内部有精密的采样通道和 ADC,能够稳定地把电芯电压转换成数字量。我在实测中主要关注它的采样一致性,同一节电芯在不同温度、不同供电电压下多次读取,结果都能保持在几毫伏以内,这个精度对均衡判定来说足够了。
再说均衡通道。芯片内部把均衡开关和驱动电路集成好了,MCU 只需要通过数字接口写入寄存器,就可以控制均衡支路的导通和断开,不需要额外去驱动外部 MOS。这个特性对简化硬件设计帮助很大,尤其是在 PCB 面积受限的小型备电模块上。
需要注意的是,不同批次或不同版本手册的功能细节可能会有差异。我这里的寄存器命名和地址都是占位示例,做实际项目时一定要以对应型号的最新 Datasheet 为准。
2.2 PIC24FV16KA304 的定位
PIC24FV16KA304 是一颗 16 位低功耗 MCU,3.3V 供电,Flash 和 RAM 都不大,但外设配置很合适:有硬件 ADC、多个定时器、I2C/SPI/UART 通信接口,还带超低功耗的休眠模式。
在均衡系统里,PIC 并不需要做复杂的运算,它的核心价值在于“低功耗”和“可靠的策略控制”。储能和备用电源场景中,系统绝大多数时间处于待机状态,MCU 不能一直全速运行。设计时让 MCU 进入周期唤醒模式:每 30 秒醒来一次,读取 MP2642GR-Z 的电压数据,做均衡逻辑判断,然后再次进入睡眠。在这种工作方式下,整个控制板本身的消耗电流可以压到非常低,不会对电池组造成明显负担。
用这颗 MCU 还有一个实际原因:它的 ADC、定时器、通信外设都支持在低功耗模式下灵活配置,代码写起来比某些超低功耗专用 MCU 更顺手,调试工具链也成熟。如果项目后续要扩展成 4 串、8 串,只要换对应的 AFE,MCU 端代码框架基本不用动。
2.3 为什么需要“专芯专用”
可能有人会说:两节电池用电阻分压+MCU ADC+三极管放电不也能实现吗?是的,能实现,但我做了多次对比后,还是建议用专业 AFE。
MCU 的 ADC 精度一般在 10 到 12 位,满量程 3.3V 时,12 位分辨率大约是 0.8mV,看起来够用。但实际采样时,电池负极和 MCU GND 之间如果因放电电流产生地弹,ADC 参考电压会被污染,读数会跳。另外,放电支路和控制逻辑混在一起,调试时很难区分是电气问题还是代码问题。
专用的 AFE 芯片把采样通道、滤波、均衡开关都封装好了,PCB 布局更规整。更重要的是,它通常还集成了一些硬件保护功能,比如过压、欠压检测标志位,MCU 可以快速读取这些状态,提升系统的响应速度。对于要通过行业认证的储能产品来说,使用成熟的 AFE 方案在可靠性和可追溯性上都有优势。分立方案适合快速原型验证,但量产项目我选择专用芯片。
3. 硬件设计与参数计算
3.1 最小系统搭建
整个硬件可以分成三段:电池采样段、均衡放电段、控制单元段。
电池采样段需要注意采样线必须直接接到电芯的极耳或采样点上,不能与功率充放电走线共用铜皮。两节串联电池的中间节点是关键,一定要从电池连接器处单独拉一根采样线到 AFE,避免大电流路径上的压降影响电压读数。AFE 的每个电压采样输入端加一个 RC 滤波,常用取值是串联 1kΩ 电阻、并联 100nF 电容,能滤掉大部分开关噪声。
均衡放电段由芯片的均衡引脚、限流电阻以及 PCB 铜皮组成。均衡电流不需要做很大,50mA 级别足够,电阻功率按实际消耗至少留一倍余量。这个放电回路的位置尽量远离采样线,避免放电时地平面上的噪声串入采样。
控制单元段是由 LDO 将电池电压降至 3.3V,给 MP2642GR-Z 和 PIC24FV16KA304 供电。由于系统要长期待机,LDO 的静态功耗一定要小,我建议选 Iq 在 2µA 以下的型号。MCU 的 I2C 或 SPI 接口与 AFE 连接,另外保留一个 UART 口用于调试输出和上位机通信。
3.2 均衡电阻的阻值和功率怎么定
均衡电阻是这套硬件里最需要算清楚的一个元件。假设电芯电压 3.7V,均衡目标电流 50mA,芯片内部均衡开关导通电阻按 20mΩ 计算,那么限流电阻上的压降约为 3.7V。
根据欧姆定律:
R = V / I = 3.7V / 0.05A = 74Ω
取标准电阻值 75Ω。实际调试中如果觉得发热太大,也可以把目标电流降为 35mA,重新计算为 105Ω,取 100Ω。
电阻功耗按公式 P = I² × R 计算,50mA 电流下 75Ω 电阻功耗约为 0.19W。PCB 上常用的 0805 封装额定功率只有 0.125W,明显不够;1206 封装一般是 0.25W,勉强可用;如果板子空间允许,我更推荐 2512 封装或绕线电阻,确保长期工作表面温度不会过高。
还有一个容易忽略的点:均衡电阻的焊盘和走线本身也有热阻,如果 PCB 铜箔面积太小,热量散不出去,电阻表面温度可能超过规定值。设计时最好在电阻两端铺一块接地铜箔协助散热,但没有必要刻意做太厚的铜,因为被动均衡本身间歇工作,连续导通时间一般不会太长。
3.3 采样链路的布局细节
项目第一次打样时,我犯过一个典型的布局错误:把均衡电阻放在了 AFE 采样引脚旁边。均衡一开启,热气流直接加热了采样电容,导致电压读数漂移了好几毫伏。后来把均衡电阻挪到 PCB 的另一侧,并在采样线上加了一级 1kΩ+100nF 的 RC,问题才消失。
采样链路还有一个重要原则:采样地和功率地要单点连接。AFE 的地引脚和 MCU 的地引脚接到同一个星形接地点,再统一回到电池负极。这样做可以避免均衡放电电流在地平面上产生压差,被 ADC 误采进去。实际布板时还要注意采样线之间的间距,两根采样线最好走平行差分形式,并在末端加电容。
如果系统里还有其他开关电源模块,比如 LDO 或 DC/DC,采样线要尽量远离它们的电感区域。开关电源的磁场干扰会通过空间耦合进采样线,引起周期性纹波。这个在实验室测试时可能不明显,装进金属机箱后反而会因为反射和共振变得更严重。
4. 软件实现:状态机驱动均衡
4.1 均衡策略的整体流程
均衡软件的核心是一个有限状态机,不建议在中断里直接做均衡判断,而是把 ADC 采样结果放到主循环或低优先级任务里处理。我的设计包含以下状态:
- EQ_IDLE:系统待机,周期性采样;压差超过启动阈值才进入下一步。
- EQ_HOLD:静置计时状态,目的是等电芯的极化电压恢复。
- EQ_BALANCING:开启均衡通道,对高电压电芯放电。
- EQ_RECOVER:均衡一段时间后暂停,重新测量真实压差。
为什么要加 EQ_HOLD?这是我自己踩坑总结出来的。锂电池在充电结束或短时间大电流放电后,电芯表面会有极化电压。极化电压和真实开路电压之差可能达到 20mV 甚至更大。如果刚充电完就立刻判断均衡,很容易把极化误判为真实不均衡,结果就是刚充完电就开启均衡,白白放掉一部分能量。
正确的流程是:先确认系统没有明显充放电电流,然后进入静置状态,静置时间建议 5 到 10 分钟。静置结束后再一次采样,用新的电压差去判断是否需要均衡。
均衡也不能一直开着不检测。我采用“均衡 30 秒 + 暂停 2 秒”的周期模式:每均衡 30 秒,关闭均衡通道 2 秒,等电压回升稳定后再读取一次电压。这样做一方面避免电阻持续发热,另一方面可以有效区分“均衡有效”和“电极极化”。
4.2 核心代码实现
下面给出一段核心代码,演示状态机切换和均衡判定的实现逻辑。这里的 AFE 寄存器地址和 I2C 读写函数为示例写法,实际使用时按 MP2642GR-Z 手册替换。
typedef enum { EQ_IDLE = 0, EQ_HOLD, EQ_BALANCING, EQ_RECOVER } eq_state_t; #define EQ_START_THRESHOLD_MV 10 #define EQ_STOP_THRESHOLD_MV 3 #define EQ_HOLD_TIME_MS 600000 // 10 minutes hold time #define EQ_BALANCE_TIME_MS 30000 // 30s balancing #define EQ_PAUSE_TIME_MS 2000 // 2s pause for voltage settle static eq_state_t eq_state = EQ_IDLE; static uint32_t eq_timer = 0; // Read cell voltage from AFE, unit: mV uint16_t read_cell_voltage(uint8_t cell_id) { // 1. Write register address via I2C/SPI // 2. Read raw ADC value // 3. Apply calibration factor // 4. Return value in millivolts } void eq_control_task(void) { static uint16_t v1, v2, diff; static uint8_t history[SAMPLE_COUNT]; uint16_t filtered_diff; uint8_t i; switch (eq_state) { case EQ_IDLE: v1 = read_cell_voltage(1); v2 = read_cell_voltage(2); if (v1 > v2) { diff = v1 - v2; } else { diff = v2 - v1; } // simple 8-point moving average for (i = SAMPLE_COUNT - 1; i > 0; i--) { history[i] = history[i - 1]; } history[0] = (diff > 0xFF) ? 0xFF : (uint8_t)diff; filtered_diff = average(history); // need hold time to eliminate polarization voltage if (filtered_diff >= EQ_START_THRESHOLD_MV) { eq_state = EQ_HOLD; eq_timer = 0; } break; case EQ_HOLD: if (eq_timer >= EQ_HOLD_TIME_MS) { // re-sample after resting v1 = read_cell_voltage(1); v2 = read_cell_voltage(2); diff = (v1 > v2) ? (v1 - v2) : (v2 - v1); if (diff >= EQ_START_THRESHOLD_MV) { eq_state = EQ_BALANCING; eq_timer = 0; // set AFE balance enable bit afe_set_balance(1); } else { eq_state = EQ_IDLE; } } break; case EQ_BALANCING: if (eq_timer >= EQ_BALANCE_TIME_MS) { // pause balancing and wait for voltage recovery afe_set_balance(0); eq_state = EQ_RECOVER; eq_timer = 0; } break; case EQ_RECOVER: if (eq_timer >= EQ_PAUSE_TIME_MS) { v1 = read_cell_voltage(1); v2 = read_cell_voltage(2); diff = (v1 > v2) ? (v1 - v2) : (v2 - v1); if (diff >= EQ_STOP_THRESHOLD_MV) { // still unbalanced, continue balancing eq_state = EQ_BALANCING; eq_timer = 0; afe_set_balance(1); } else { // balanced, exit afe_set_balance(0); eq_state = EQ_IDLE; } } break; } }这段代码在功能上是完整的,但有几个地方要根据实际需求调整。首先是历史滤波数组的类型,如果压差超过 255mV,直接截断会丢失信息,所以我在代码里做了饱和处理,或者你也可以直接把数组类型改成 uint16_t。其次是 AFE 的均衡使能操作,需要有一个 afe_set_balance 函数,实质就是写一个寄存器位。
主循环中调用 eq_control_task 的周期建议是 100ms。定时器溢出标志用 SysTick 或者 Timer1 来处理,不推荐用 delay 方式阻塞整个主循环,因为均衡过程中 MCU 还要响应上位机查询和温度采样。
4.3 参数整定思路
几个关键参数怎么定,我给出实际项目中的参考值,以及背后的计算逻辑。
启动阈值 10mV:这个值来源于电芯出厂压差规格。大多数厂家允许同一批次电芯在相同 SOC 下的压差在 5mV 以内,再叠加长时间自放电差异,10mV 是一个可靠信号,不会频繁误触发。
停止阈值 3mV:如果追求绝对一致,想把压差压到 0,在被动均衡下几乎做不到。因为电芯电压会随温度微小波动,测量本身也有噪声,3mV 是一个合理的滞环下限。假如停止阈值设得比 3mV 更小,均衡通道就会反复开断,每次开启前还要等 2 秒电压稳定,整个系统会显得很“焦虑”。
均衡周期 30 秒:这个和均衡电阻的散热能力有关。75Ω 电阻在 50mA 下功耗约 0.19W,如果连续工作 30 分钟,表面温度会上升 30K 以上。采用 30 秒导通、2 秒暂停的节奏,可以让电阻在热容量内工作,既保证平均均衡速度,又避免局部过热。如果环境温度高,可以把单次均衡时间降到 20 秒。
均衡电流的选择还需要考虑电芯容量。假设压差 35mV,对应容量差约 100mAh(不同电芯化学体系差异很大,这里只能给经验估算),用 50mA 放电需要约 2 小时才能补齐。因此均衡是一个“慢工出细活”的过程,不要指望几分钟内完成。备电系统对均衡速度并不敏感,反而对稳定性和安全性要求更高。
5. 实测问题与调试心得
5.1 均衡标志置位但电流为零
项目调试阶段遇到最诡异的问题:代码显示均衡通道已打开,AFE 寄存器回读也确实为 1,但用万用表量均衡电阻两端,压降为 0,电流为零。
排查过程是按这三个顺序做的:
第一步,排除软件问题。用调试器单步执行,确认 afe_set_balance 函数成功写入并且回读一致。既然寄存器没问题,说明命令已经发到 AFE 内部。
第二步,测硬件引脚。示波器量 AFE 均衡引脚,发现确实输出了高电平,说明芯片内部 MOS 已经导通。问题只能出现在均衡引脚到电阻之间的外部路径,或者是电阻本身。
第三步,检查焊接。用热风枪吹下电阻,发现焊盘上有细微的锡珠短路,电阻一端通过锡珠直接连到地,电流走了近路,根本没有流过电阻本体。重新焊接后恢复正常。
这个案例说明一个问题:均衡通道的 MOSFET 在芯片内部,外部只留了一个开漏/推挽引脚。芯片是不是真的导通了,不能只看寄存器标志,一定要测量引脚电平或者电阻电流。建议在均衡支路串一个 0.1Ω 采样电阻,用 ADC 实时监测均衡电流,这样不仅能确认硬件是否工作,还能在策略里增加电流闭环保护。
5.2 充电刚结束的“假压差”
第一次野外实测时,备用电源从市电切换到电池放电,运行了半小时后恢复市电充电。充电结束约 1 分钟,系统报告压差 40mV,自动进入了均衡。但奇怪的是,均衡了两个小时,压差没有明显下降,而且数据在 20mV 到 40mV 之间来回跳。
后来分析原因:电芯极化。电池在充电时,锂离子从正极迁移到负极,电池表面电压会高于真实开路电压。充电刚结束那段时间,离子浓度梯度尚未恢复,表面电压虚高。尤其是内阻偏大的电芯,这个虚高更明显。系统在极化未消退时开启均衡,等于把一个“假高电压”当成真实不平衡,白放了不少电。
解决方法是加一个电流判据:均衡启动前,必须确认系统充放电电流小于 100mA,并且进入 EQ_HOLD 状态保持 10 分钟。如果系统本身有霍尔电流传感器,直接把电流信号接入 MCU 的 ADC;如果没有,也要通过 AFE 的电流采样通道或外部分流电阻获得电流数据。没有电流判据,静置时间再长也不能保证消除极化。
5.3 极端温度下的策略边界
备用电源可能部署在户外机柜里,夏天温度能到 45°C,冬天可能到 -10°C。均衡策略必须考虑温度边界。
温度高时,均衡电阻发热会进一步加剧环境温升。我在设计里放了两路温度检测:一路 NTC 贴在均衡电阻附近的 PCB 上,另一路贴在电芯表面。每次均衡前读这两路温度,取最大值。超过 50°C 立即停止均衡,等温度回落到 40°C 以下再恢复。
温度低时,电芯内阻变大,电压差的一部分其实是内阻差引起的,均衡的物理意义不大。更关键的是,低温下锂离子扩散变慢,大电流放电容易造成析锂。虽然均衡电流只有 50mA,但在 -10°C 环境下也不建议工作。我在策略里加了上限:低于 0°C 禁止启动均衡,低于 5°C 时把均衡占空比减半,比如原来 30 秒开、2 秒关,改成 15 秒开、2 秒关,降低持续发热和极化风险。
还有一点容易被忽略:均衡电阻加热后会烘烤附近的电芯,导致电芯表面温度升高,反过来影响电压采样。如果 NTC 放得太靠近均衡电阻,它会读到很高的温度,触发保护。所以温度传感器的摆放位置要实测确认,不要在原理图阶段就拍脑袋定。
5.4 实测数据记录
最后放一组项目验收时的实测数据,用来直观说明均衡效果。测试条件:两节 3.7V / 2000mAh 电芯,25°C 环境温度,均衡电流设定 50mA。
第一组数据是静置状态下的正常均衡。初始压差 38mV,启动均衡后,前 20 分钟压差下降到 17mV,随后下降速度变慢,2 小时 10 分钟后压差稳定在 4mV。停止均衡后放置 24 小时,压差回弹到 6mV,属于正常范围。
第二组数据是充电后的极化场景。充电结束后立刻测量,压差显示 70mV,其中约 30mV 是极化电压。静置 10 分钟后,真实压差降到 45mV,再开始均衡,4 小时后压差降到 9mV。中途均衡电阻温度达到 52°C,保护逻辑触发,暂停了 10 分钟,温度回落后继续。
第三组数据是长期静置对比。一组不做均衡的电池放置 30 天,压差从 8mV 慢慢增大到 23mV;另一组有均衡功能的电池放置 30 天,压差始终被控制在 5mV 以内。这个数据说明均衡在长期备电场景中的价值:它不是解决当下问题,而是防止不一致性慢慢累积。
| 测试场景 | 初始压差 | 均衡时间 | 结束压差 | 备注 |
|---|---|---|---|---|
| 静置均衡 | 38mV | 2h10m | 4mV | 温度正常,无保护触发 |
| 极化后均衡 | 45mV | 4h | 9mV | 中途温度 52°C,暂停一次 |
| 长期静置对比 | 8mV → 23mV | 30天 | 有均衡保持 5mV | 说明累积效应被抑制 |
调试完成后,我的一个体会是:均衡不是越快越好,也不是压差越小越好。刚开始我把启动阈值设成 3mV,结果系统频繁开启均衡,电芯被反复小电流放电,反而因为每次都引入极化,让压差判断越来越不准。后来把阈值拉开,用 10mV 启动、3mV 停止,系统瞬间安静下来,均衡效果反而更稳定。这套 MP2642GR-Z 加 PIC24FV16KA304 的方案,硬件层面已经很成熟,真正决定成败的,是你在状态机里写给均衡的那份耐心。