【BMS-AFE-主动均衡芯片】
MP2645主动均衡芯片完全指南:硬件设计、通信协议与FreeRTOS驱动
一、引言
在锂电池管理系统(BMS)中,均衡是保证电芯一致性、延长电池寿命的核心功能。被动均衡靠电阻耗散多余能量,简单但效率低、发热大;主动均衡通过能量转移实现高效均衡,是大容量电池组的首选方案。
MP2645 是 MPS(芯源系统)推出的单芯片 5 串双向 Buck-Boost 主动均衡 IC,最大均衡电流 3.75A,效率最高 93%,最多 8 颗级联支持 33 串。本文从硬件设计、通信协议、软件驱动三个维度,完整讲解 MP2645 的工程落地。


二、MP2645 芯片概述
2.1 关键参数
| 参数 | MP2645 | MP2645A |
|---|---|---|
| 管理电芯 | 5 串(N1~N5) | 5 串 |
| 最大堆栈电压 | 40V | 40V |
| 最大均衡电流 | 3.75A | 3A |
| 均衡效率 | 最高 93% | 最高 93% |
| 级联能力 | 最多 8 颗,最大 33 串 | 最多 8 颗 |
| 电池类型 | 三元锂、磷酸铁锂、锂聚合物、超级电容 | 同左 |
| 封装 | QFN-19,4mm×4mm | QFN-19 |
| 供电来源 | 直接由电池组取电,无需外部辅助电源 | 同左 |
2.2 核心工作原理
MP2645 内部集成多组功率 MOS,外部仅需 1 颗功率电感,实现双向升降压能量转移:
高电压电芯 ──► 内部MOS ──► 电感储能 ──► 内部MOS ──► 低电压电芯
(能量暂存)
- 放电方向:高电压电芯 → 电感储能
- 充电方向:电感释放能量 → 低压电芯充电
- 支持充电、放电、静置三种工况下持续均衡
与分立电感式主动均衡对比:分立方案需要大量外部 MOS、驱动电路、多颗电感;MP2645 把功率管、PWM 环路、保护逻辑全部集成,BOM 大幅简化。
2.3 内置保护功能
- 电芯过压 OVP 保护
- 芯片过温关断
- 看门狗 WDT(MCU 失联后自动关闭均衡)
- 过流限制
- 堆栈电压过压保护
三、引脚定义与硬件设计
3.1 通信与控制引脚
| 引脚 | 方向 | 功能 |
|---|---|---|
| CTRL | 输入(DI) | 单线控制输入,低电平有效,MCU 发送脉冲命令 |
| STAT | 输出(DO,开漏) | 状态报告,低电平有效,多芯片线与 |
| UP | 输出 | 菊花链向上传递,转发 CTRL 信号给下一级 |
| DOWN | 输入 | 菊花链向下接收,接收上一级 UP 信号 |
| ADDR | 输入 | 硬件地址配置,电阻分压设置 0~7 |
3.2 功率引脚
| 引脚 | 功能 |
|---|---|
| N1~N5 | 电芯输入,直接接 5 串电芯两端 |
| SW-MX | 功率电感连接端,外部唯一功率磁性器件 |
| VCC | 内部 LDO 输出(3.6V),需 1μF 电容,不得外接负载 |
| AGND/PGND | 模拟地/功率地,PCB 上短接 |
3.3 典型外围电路
电芯1+ ──┬─────────────────────── N1
│
电芯1- ──┼── 电芯2+ ──┬────────── N2
│ │
... ...
│ │
电芯4- ──┼── 电芯5+ ──┬────────── N5
│ │
电芯5- ──┴────────────┴────────── AGND
SW-MX ── L(功率电感, 低DCR) ── 电芯公共节点
VCC ── 1μF ── AGND
CTRL ── 100Ω ── MCU_GPIO
STAT ── 4.7kΩ上拉3.3V ── MCU_GPIO
ADDR ── 电阻分压 ── AGND
硬件设计要点:
| 要点 | 说明 |
|---|---|
| 功率电感 | 饱和电流 > 3.75A,低 DCR,决定均衡电流和温升 |
| 电芯走线 | 尽量短,降低线阻(线阻直接降低实际均衡电流) |
| VCC 电容 | 1μF 陶瓷电容,走线最短,不得外接负载 |
| CTRL 滤波 | 串联 100Ω + 100pF 到 GND,抑制高压侧耦合噪声 |
| STAT 上拉 | 开漏输出,必须 4.7kΩ~10kΩ 上拉 3.3V |
| ADDR 精度 | 分压电阻 1%,地址不可重复 |
四、多芯片菊花链级联
4.1 硬件接线
MCU GPIO_OUT ────────────┬──── CTRL(#0)
├──── CTRL(#1)
└──── CTRL(#2) ... 所有CTRL并联
#0.UP ───────> #1.DOWN
#1.UP ───────> #2.DOWN
... (逐级串联,最高编号UP悬空)
全部 STAT 引脚并联 → 4.7kΩ上拉 → MCU GPIO_IN
4.2 级联工作逻辑
- 所有芯片的 CTRL 并联,MCU 广播脉冲命令
- UP/DOWN 逐级透传信号,确保堆栈内所有芯片都收到
- ADDR 硬件地址区分每颗芯片(0~7,不可重复)
- STAT 线与逻辑:任意一颗故障 → STAT 拉低 → MCU 全局检测
4.3 ADDR 地址配置
ADDR 引脚通过外部电阻分压设置 0~7 共 8 个地址:
- 地址 0:直接接 AGND
- 地址 1~7:电阻分压,参考 datasheet 阻值表
关键:地址是硬件电阻配置,不是软件写寄存器。多颗级联必须 0、1、2…依次分配,不可重复。
五、通信协议详解
5.1 不是 I2C/SPI/UART
MP2645 采用 MPS 私有的 One-Wire Stack Interface(单线堆叠脉冲计数协议),与标准协议有本质区别:
| 对比项 | MP2645 单线脉冲 | I2C | SPI | UART |
|---|---|---|---|---|
| 数据形式 | 脉冲个数代表命令 | 字节帧 | 字节帧 | 字节帧 |
| 硬件外设 | 无,纯 GPIO 模拟 | I2C 外设 | SPI 外设 | UART 外设 |
| 读回数据 | STAT 仅脉冲状态,无寄存器回读 | 可读寄存器 | 可读寄存器 | 可读数据 |
| 从机地址 | 硬件电阻 ADDR(0~7) | 软件 7bit 地址 | CS 片选 | 无地址 |
核心原理:MP2645 内部统计 CTRL 引脚上下降沿脉冲的数量来解析命令,不是用高低电平编码 bit 0/1。
5.2 完整通信时序

CTRL 电平
│
├──────┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌────────────
│ │ t_INIT(≈250μs) │ │ │ │ │ │ │ │ t_END │
│ └────────────────────┘ └─┘ └─┘ └─┘ └────────┘
│
│ [唤醒拉低] [等待初始化] [N个脉冲] [结束保持]
│
└──────────────────────────────────────────────────────► 时间
四个阶段:
| 阶段 | 动作 | 典型时长 | 说明 |
|---|---|---|---|
| ① 唤醒 | MCU 拉低 CTRL | ≥ 250μs | 唤醒总线上所有 MP2645 |
| ② 初始化 | CTRL 保持低 | 内部就绪 | 芯片准备计数 |
| ③ 脉冲序列 | MCU 输出 N 个脉冲 | 每脉冲约 100μs | 脉冲数 N = 地址+命令 |
| ④ 结束确认 | CTRL 保持低 | 100~200μs | 芯片锁存命令并执行 |
5.3 脉冲编码规则
命令由脉冲总数决定,典型编码框架(具体映射以 datasheet Command Table 为准):
脉冲数 N = 地址偏移 + 命令码
地址偏移 = addr × 8 + 8
示例:
- 广播复位:N = 1
- 看门狗喂狗:N = 2
- 地址0 关闭均衡:N = 8 + 0 = 8
- 地址0 开启电芯1均衡:N = 8 + 1 = 9
- 地址1 开启电芯1均衡:N = 16 + 1 = 17
5.4 地址匹配机制
- MCU 发送一帧脉冲,所有级联芯片同时计数
- 每颗芯片的硬件 ADDR 决定所属地址区间
- 只有脉冲数落在本芯片区间内的命令才被执行
- 其余芯片仅透传脉冲,不动作
- 广播命令(复位、喂狗)所有芯片同时响应
六、FreeRTOS 驱动实现
6.1 头文件 mp2645.h
#ifndef __MP2645_H
#define __MP2645_H
#include "stm32f4xx_hal.h"
#include "cmsis_os.h"
/* ========== 硬件引脚定义 ========== */
#define MP2645_CTRL_PORT GPIOA
#define MP2645_CTRL_PIN GPIO_PIN_0
#define MP2645_STAT_PORT GPIOA
#define MP2645_STAT_PIN GPIO_PIN_1
/* ========== 协议时序参数(以datasheet为准) ========== */
#define MP2645_T_INIT_US 250
#define MP2645_T_PULSE_HIGH_US 50
#define MP2645_T_PULSE_LOW_US 50
#define MP2645_T_END_US 150
#define MP2645_T_INTER_CMD_MS 2
/* ========== 命令编码(以datasheet Command Table为准) ========== */
#define MP2645_CMD_BROADCAST_RESET 1
#define MP2645_CMD_WATCHDOG_FEED 2
#define MP2645_CMD_BALANCE_OFF 0
#define MP2645_CMD_BALANCE_CELL1 1
#define MP2645_CMD_BALANCE_CELL2 2
#define MP2645_CMD_BALANCE_CELL3 3
#define MP2645_CMD_BALANCE_CELL4 4
#define MP2645_CMD_BALANCE_CELL5 5
#define MP2645_ADDR_OFFSET(addr) ((addr) * 8 + 8)
/* ========== 函数接口 ========== */
void MP2645_Init(void);
void MP2645_SendCommand(uint8_t addr, uint8_t cmd);
void MP2645_BroadcastReset(void);
void MP2645_FeedWatchdog(void);
uint8_t MP2645_ReadSTAT(void);
void MP2645_StartBalance(uint8_t addr, uint8_t cell);
void MP2645_StopBalance(uint8_t addr);
void MP2645_UpdateVoltage(uint8_t chip, uint8_t cell, uint16_t voltage_mv);
void MP2645_SetChipCount(uint8_t count);
void MP2645_Task(void const *argument);
#endif
6.2 驱动实现 mp2645.c
#include "mp2645.h"
/* ========== 微秒级延时(DWT周期计数器,精度最高) ========== */
static void delay_us(uint32_t us)
{
uint32_t start = DWT->CYCCNT;
uint32_t ticks = us * (SystemCoreClock / 1000000);
while ((DWT->CYCCNT - start) < ticks);
}
/* ========== CTRL引脚操作 ========== */
static inline void CTRL_High(void)
{
HAL_GPIO_WritePin(MP2645_CTRL_PORT, MP2645_CTRL_PIN, GPIO_PIN_SET);
}
static inline void CTRL_Low(void)
{
HAL_GPIO_WritePin(MP2645_CTRL_PORT, MP2645_CTRL_PIN, GPIO_PIN_RESET);
}
/* ========== 发送一个脉冲 ========== */
static void MP2645_SendPulse(void)
{
CTRL_High();
delay_us(MP2645_T_PULSE_HIGH_US);
CTRL_Low();
delay_us(MP2645_T_PULSE_LOW_US);
}
/* ========== 发送N个脉冲(核心函数) ========== */
static void MP2645_SendPulses(uint8_t count)
{
uint8_t i;
CTRL_Low(); /* ①唤醒拉低 */
delay_us(MP2645_T_INIT_US); /* ②初始化 */
for (i = 0; i < count; i++) { /* ③N个脉冲 */
MP2645_SendPulse();
}
delay_us(MP2645_T_END_US); /* ④结束保持 */
CTRL_High(); /* 释放总线 */
}
/* ========== 初始化 ========== */
void MP2645_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* CTRL:推挽输出 */
GPIO_InitStruct.Pin = MP2645_CTRL_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(MP2645_CTRL_PORT, &GPIO_InitStruct);
/* STAT:上拉输入 */
GPIO_InitStruct.Pin = MP2645_STAT_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(MP2645_STAT_PORT, &GPIO_InitStruct);
CTRL_High();
/* 初始化DWT */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
osDelay(10);
MP2645_BroadcastReset();
osDelay(10);
}
void MP2645_SendCommand(uint8_t addr, uint8_t cmd)
{
MP2645_SendPulses(MP2645_ADDR_OFFSET(addr) + cmd);
osDelay(MP2645_T_INTER_CMD_MS);
}
void MP2645_BroadcastReset(void)
{
MP2645_SendPulses(MP2645_CMD_BROADCAST_RESET);
osDelay(MP2645_T_INTER_CMD_MS);
}
void MP2645_FeedWatchdog(void)
{
MP2645_SendPulses(MP2645_CMD_WATCHDOG_FEED);
}
uint8_t MP2645_ReadSTAT(void)
{
return (HAL_GPIO_ReadPin(MP2645_STAT_PORT, MP2645_STAT_PIN)
== GPIO_PIN_RESET) ? 1 : 0;
}
void MP2645_StartBalance(uint8_t addr, uint8_t cell)
{
if (cell < 1 || cell > 5) return;
MP2645_SendCommand(addr, MP2645_CMD_BALANCE_CELL1 + (cell - 1));
}
void MP2645_StopBalance(uint8_t addr)
{
MP2645_SendCommand(addr, MP2645_CMD_BALANCE_OFF);
}
6.3 FreeRTOS 均衡控制任务
typedef struct {
uint8_t addr;
uint8_t target_cell; /* 1~5,0=不操作 */
uint16_t cell_voltage[5]; /* AFE采集电压(mV) */
} MP2645_Context_t;
static MP2645_Context_t g_mp2645_ctx[8];
static uint8_t g_chip_count = 1;
#define BALANCE_VOLTAGE_TH_MV 3400
#define BALANCE_DIFF_TH_MV 30
/* 均衡决策:由AFE电压数据驱动 */
static void MP2645_DecodeBalance(void)
{
uint8_t chip, cell;
uint16_t min_v, max_v;
for (chip = 0; chip < g_chip_count; chip++) {
min_v = 0xFFFF; max_v = 0;
for (cell = 0; cell < 5; cell++) {
if (g_mp2645_ctx[chip].cell_voltage[cell] > max_v)
max_v = g_mp2645_ctx[chip].cell_voltage[cell];
if (g_mp2645_ctx[chip].cell_voltage[cell] < min_v)
min_v = g_mp2645_ctx[chip].cell_voltage[cell];
}
if ((max_v - min_v) > BALANCE_DIFF_TH_MV && max_v > BALANCE_VOLTAGE_TH_MV) {
for (cell = 0; cell < 5; cell++) {
if (g_mp2645_ctx[chip].cell_voltage[cell] == max_v) {
g_mp2645_ctx[chip].target_cell = cell + 1;
break;
}
}
} else {
g_mp2645_ctx[chip].target_cell = 0;
}
}
}
void MP2645_Task(void const *argument)
{
uint8_t chip;
uint32_t wdt_counter = 0;
MP2645_Init();
while (1) {
/* 1. 看门狗喂狗(每2秒) */
if (++wdt_counter >= 20) {
MP2645_FeedWatchdog();
wdt_counter = 0;
}
/* 2. 读取STAT故障状态 */
if (MP2645_ReadSTAT()) {
/* 记录故障日志,可逐颗关闭定位故障芯片 */
}
/* 3. 均衡决策 */
MP2645_DecodeBalance();
/* 4. 执行均衡命令 */
for (chip = 0; chip < g_chip_count; chip++) {
if (g_mp2645_ctx[chip].target_cell > 0)
MP2645_StartBalance(chip, g_mp2645_ctx[chip].target_cell);
else
MP2645_StopBalance(chip);
osDelay(5);
}
osDelay(100); /* 任务周期100ms */
}
}
void MP2645_UpdateVoltage(uint8_t chip, uint8_t cell, uint16_t voltage_mv)
{
if (chip >= g_chip_count || cell >= 5) return;
g_mp2645_ctx[chip].cell_voltage[cell] = voltage_mv;
}
void MP2645_SetChipCount(uint8_t count)
{
g_chip_count = (count > 8) ? 8 : count;
}
6.4 任务创建
/* main.c 中 */
osThreadDef(MP2645Task, MP2645_Task, osPriorityNormal, 0, 256);
osThreadCreate(osThread(MP2645Task), NULL);
七、AFE + MP2645 联合系统

7.1 系统分工
| 模块 | 职责 |
|---|---|
| AFE 芯片 | 采集每节电芯电压、温度,上报 MCU |
| MCU | 根据 AFE 电压数据做均衡决策,下发脉冲命令给 MP2645 |
| MP2645 | 执行能量搬运,不做电压采集 |
7.2 完整数据流
AFE采集电芯电压 ──► MCU判断压差 ──► MCU GPIO模拟脉冲 ──► MP2645执行均衡
▲ │
└──────────── STAT故障状态 ◄────────────────────────────────┘
7.3 延时分工(关键)
| 延时类型 | 用途 | 函数 |
|---|---|---|
| 微秒级 | 脉冲宽度、初始化、结束保持 | delay_us()(DWT) |
| 毫秒级 | 命令间隔、任务周期、喂狗周期 | osDelay() |
脉冲时序在微秒级,osDelay() 是毫秒级,不能用于脉冲内部延时,必须用 DWT 或硬件定时器。
八、调试与常见问题
8.1 调试技巧
- 逻辑分析仪必接:CTRL 和 STAT 引脚接逻辑分析仪,观察脉冲数量和时序
- 先单颗调试:级联前先调通单颗,确认命令能执行
- 逐级增加:单颗 OK 后再加第二颗,验证 ADDR 和 UP/DOWN
- STAT 排查:STAT 持续拉低 → 逐颗关闭均衡定位故障
- Multisim 限制:无 MP2645 仿真模型,私有脉冲协议只能实物调试
8.2 常见问题排查
| 故障现象 | 排查方向 |
|---|---|
| 全部芯片无响应 | CTRL 时序不对;STAT 缺少上拉;看门狗超时;电平不匹配 |
| 部分芯片不工作 | ADDR 地址重复;UP/DOWN 接线错误;分压电阻错误 |
| STAT 持续拉低 | 芯片过温/过压;看门狗未喂狗;硬件短路 |
| 均衡电流偏小 | 电感饱和电流不足;电芯走线线阻大;电池电压偏低 |
| 通信偶发失败 | CTRL 无 RC 滤波;脉冲宽度偏窄;干扰导致计数错误 |
8.3 设计注意点
- 电感饱和电流必须 > 3.75A,避免磁饱和
- 电芯走线尽量短,线阻直接降低均衡电流
- UP/DOWN 信号线建议加 RC 滤波,提升抗干扰
- 多颗级联 ADDR 地址不能冲突
- 命令编码以 datasheet Command Table 为准,本文为可移植框架
九、总结
MP2645 是一颗高集成度的主动均衡解决方案,本文从软硬两个维度完整覆盖:
硬件层面:
- 5 串双向 Buck-Boost,单芯片 + 1 电感实现能量转移
- 最多 8 颗级联,CTRL 并联广播 + UP/DOWN 透传 + ADDR 寻址
- STAT 开漏线与,全局故障检测
软件层面:
- 私有单线脉冲计数协议,纯 GPIO 模拟,无硬件外设
- 时序四阶段:唤醒 → 初始化 → N脉冲 → 结束
- FreeRTOS 任务:均衡决策 + 看门狗喂狗 + 状态检测
- 微秒级用 DWT,毫秒级用 osDelay()
工程启示:
- MP2645 不采集电压,必须搭配 AFE 使用
- 命令编码和时序参数必须以 datasheet 为准
- 看门狗必须周期性喂,否则自动关均衡
- 逻辑分析仪是调试私有协议的必备工具
如果文章对你有帮助,欢迎点赞、收藏、关注!有问题欢迎评论区交流。
主要参考:
- MPS 官网 MP2645 产品页 https://www.monolithicpower.cn/cn/mp2645.html
- MPS技术论坛:MP2645A 主动均衡器发布 https://forum.monolithicpower.cn/t/topic/7741/1
- 电子工程专辑:MP2645 芯片解析 https://www.eet-china.com/mp/a494314.html
系列导航:
- BMS硬件设计:电池电压采样方案总览
- BMS硬件设计:温度检测电路详解
- BMS通信核心:AFE菊花链技术详解
- 锂电池主动均衡详解:能量转移的几种实现方式
- 本文:MP2645主动均衡芯片完全指南
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)