项目概述
本项目设计并实现了一款 8 串锂电池管理系统 (BMS),支持 30A 持续放电、主动均衡、SOC/SOH 估算和 CAN 通信,适用于电动自行车、储能电源等应用。
技术指标
| 参数 | 规格 |
|---|---|
| 串数 | 8S (29.6V 标称) |
| 持续电流 | 30A |
| 峰值电流 | 60A (10s) |
| 均衡电流 | 100mA |
| 电压精度 | ±2mV |
| 电流精度 | ±1% |
| SOC 精度 | ±3% |
硬件设计
系统架构
信号流向:
- 电池组 → AFE:8 串电池电压采集
- AFE → MCU:I2C 数字接口
- 传感器 → MCU:ADC 模拟输入
- MCU → CAN/保护/电源:控制输出
关键器件选型
AFE 芯片: ISL94208
- 8 串电池监测
- 电压精度:±2mV
- 内置均衡开关
- I2C 接口
电流检测: INA240
- 双向电流检测
- 共模电压:80V
- 增益:20V/V
- 带宽:400kHz
MCU: STM32G071
- 主频:64MHz
- ADC: 12 位,2.5MSPS
- CAN: 1 路
- Flash: 128KB
MOSFET: AON7534
- Vds: 30V
- Id: 80A
- Rds(on): 8mΩ
- 封装:DFN5x6
电压采集电路
工作原理:
- 8 串电池通过分压电阻网络连接到 AFE
- 每节电池电压经过 RC 滤波(10kΩ + 100nF)
- ISL94208 内置 ADC 依次采样各串电压
- 通过 I2C 接口将数据发送给 MCU
关键参数:
- 分压电阻:10kΩ × 8
- RC 滤波:fc ≈ 160Hz
- 测量精度:±2mV
电流检测电路
工作原理:
- 电流流过分流电阻产生压降(60A × 0.5mΩ = 30mV)
- INA240 差分放大器增益 20 倍(输出 600mV)
- MCU ADC 采集输出电压
- 计算得到实际电流值
关键参数:
- 分流电阻:0.5mΩ / 5W
- INA240 增益:20V/V
- 电流分辨率:80mA
- 带宽:400kHz
SOC 估算算法
安时积分法
typedef struct {
float soc; // 当前 SOC (0-100%)
float capacity; // 电池容量 (Ah)
float charge_total; // 累计充电量 (Ah)
float discharge_total; // 累计放电量 (Ah)
uint32_t last_update; // 上次更新时间 (ms)
} SOC_TypeDef;
void soc_coulomb_count(SOC_TypeDef *soc, float current) {
uint32_t now = HAL_GetTick();
float dt = (now - soc->last_update) / 3600000.0f; // 小时
if (current > 0) {
// 充电
soc->charge_total += current * dt;
soc->soc = (soc->capacity - soc->discharge_total + soc->charge_total)
/ soc->capacity * 100.0f;
} else {
// 放电
soc->discharge_total -= current * dt;
soc->soc = (soc->capacity - soc->discharge_total + soc->charge_total)
/ soc->capacity * 100.0f;
}
// 限幅
soc->soc = constrain(soc->soc, 0, 100);
soc->last_update = now;
}
OCV-SOC 查表法
// LCO 电池 OCV-SOC 曲线 (25°C)
const float ocv_table[101] = {
// SOC 0-10%
3.00, 3.20, 3.30, 3.40, 3.50, 3.55, 3.60, 3.65, 3.68, 3.70,
// SOC 10-20%
3.72, 3.74, 3.76, 3.78, 3.80, 3.82, 3.84, 3.86, 3.88, 3.90,
// ... (省略中间部分)
// SOC 90-100%
4.15, 4.16, 4.17, 4.18, 4.19, 4.20, 4.21, 4.22, 4.23, 4.24, 4.25
};
float soc_from_ocv(float ocv) {
// 二分查找
int low = 0, high = 100;
while (high - low > 1) {
int mid = (low + high) / 2;
if (ocv_table[mid] < ocv) {
low = mid;
} else {
high = mid;
}
}
// 线性插值
float ratio = (ocv - ocv_table[low]) /
(ocv_table[high] - ocv_table[low]);
return low + ratio;
}
卡尔曼滤波融合
typedef struct {
float soc; // 估计 SOC
float P; // 误差协方差
float Q; // 过程噪声
float R; // 测量噪声
} KalmanSOC_TypeDef;
float kalman_soc_update(KalmanSOC_TypeDef *k,
float soc_ah, // 安时积分 SOC
float soc_ocv) { // OCV 查表 SOC
// 预测
k->P = k->P + k->Q;
// 更新 (以 OCV 为测量值)
float K = k->P / (k->P + k->R); // 卡尔曼增益
k->soc = soc_ah + K * (soc_ocv - soc_ah);
k->P = (1 - K) * k->P;
return k->soc;
}
// 实际使用
void soc_fusion(SOC_TypeDef *soc, float current, float voltage) {
// 1. 安时积分
soc_coulomb_count(soc, current);
float soc_ah = soc->soc;
// 2. OCV 查表 (静置时)
float soc_ocv = 0;
if (fabs(current) < 0.1f) { // 静置电流<100mA
soc_ocv = soc_from_ocv(voltage / 8.0f); // 单节电压
}
// 3. 卡尔曼融合
if (soc_ocv > 0) {
soc->soc = kalman_soc_update(&kalman, soc_ah, soc_ocv);
}
}
保护策略
过充保护
#define OV_THRESHOLD 4.25f // 过充阈值
#define OV_RELEASE 4.15f // 恢复阈值
#define OV_DELAY_MS 1000 // 延时 1s
void check_over_voltage(float cell_voltage[8]) {
static uint32_t ov_start = 0;
for (int i = 0; i < 8; i++) {
if (cell_voltage[i] > OV_THRESHOLD) {
if (ov_start == 0) {
ov_start = HAL_GetTick();
}
if (HAL_GetTick() - ov_start > OV_DELAY_MS) {
// 关断充电 MOS
mosfet_charge_off();
fault_set(FAULT_OV);
}
} else {
ov_start = 0;
if (cell_voltage[i] < OV_RELEASE) {
mosfet_charge_on();
fault_clear(FAULT_OV);
}
}
}
}
过放保护
#define UV_THRESHOLD 2.80f // 过放阈值
#define UV_RELEASE 3.00f // 恢复阈值
#define UV_DELAY_MS 500 // 延时 500ms
void check_under_voltage(float cell_voltage[8]) {
static uint32_t uv_start = 0;
for (int i = 0; i < 8; i++) {
if (cell_voltage[i] < UV_THRESHOLD) {
if (uv_start == 0) {
uv_start = HAL_GetTick();
}
if (HAL_GetTick() - uv_start > UV_DELAY_MS) {
// 关断放电 MOS
mosfet_discharge_off();
fault_set(FAULT_UV);
}
} else {
uv_start = 0;
if (cell_voltage[i] > UV_RELEASE) {
mosfet_discharge_on();
fault_clear(FAULT_UV);
}
}
}
}
过流保护
#define OC_THRESHOLD 50.0f // 过流阈值 (A)
#define SC_THRESHOLD 150.0f // 短路阈值 (A)
#define OC_DELAY_MS 100 // 过流延时
#define SC_DELAY_US 200 // 短路延时 (硬件比较器)
void check_over_current(float current) {
static uint32_t oc_start = 0;
if (current > OC_THRESHOLD) {
if (oc_start == 0) {
oc_start = HAL_GetTick();
}
if (HAL_GetTick() - oc_start > OC_DELAY_MS) {
mosfet_discharge_off();
fault_set(FAULT_OC);
}
} else {
oc_start = 0;
fault_clear(FAULT_OC);
}
// 短路保护 (硬件快速响应)
if (current > SC_THRESHOLD) {
mosfet_discharge_off_hw(); // 硬件关断
fault_set(FAULT_SC);
}
}
主动均衡
均衡策略
#define BALANCE_START_SOC 80.0f // SOC>80% 开始均衡
#define BALANCE_THRESHOLD 5.0f // 压差>5mV 启动均衡
#define BALANCE_TARGET 2.0f // 目标压差<2mV
void balance_control(float cell_voltage[8]) {
// 1. 计算平均电压
float avg = 0;
for (int i = 0; i < 8; i++) {
avg += cell_voltage[i];
}
avg /= 8.0f;
// 2. 找出最高电压电池
int max_idx = 0;
float max_v = cell_voltage[0];
for (int i = 1; i < 8; i++) {
if (cell_voltage[i] > max_v) {
max_v = cell_voltage[i];
max_idx = i;
}
}
// 3. 判断是否需要均衡
float diff = max_v - avg;
if (diff > BALANCE_THRESHOLD / 1000.0f) {
// 4. 开启均衡
balance_enable(max_idx);
} else {
balance_disable_all();
}
}
均衡电路
采用电感式双向主动均衡:
- 拓扑: Buck-Boost
- 频率: 100kHz
- 效率: >85%
- 均衡电流: 100mA
工作原理:
充电模式 (BAT(n)→BAT(n+1))
- Q1 PWM 调制,Q2 关断
- 电感储能后释放到高电压电池
放电模式 (BAT(n+1)→BAT(n))
- Q2 PWM 调制,Q1 关断
- 电感储能后释放到低电压电池
通信接口
CAN 通信协议
// CAN 帧定义
typedef struct {
uint16_t id;
uint8_t data[8];
uint8_t len;
} CAN_Frame_t;
// 上报数据帧 (100ms 周期)
void can_send_status(void) {
CAN_Frame_t frame;
frame.id = 0x18FF50E5;
frame.len = 8;
// Byte 0-1: 总电压 (0.1V/bit)
frame.data[0] = (uint16_t)(total_voltage * 10) & 0xFF;
frame.data[1] = (uint16_t)(total_voltage * 10) >> 8;
// Byte 2-3: 电流 (0.1A/bit, 有符号)
frame.data[2] = (uint16_t)(current * 10 + 32768) & 0xFF;
frame.data[3] = (uint16_t)(current * 10 + 32768) >> 8;
// Byte 4: SOC (0.5%/bit)
frame.data[4] = (uint8_t)(soc * 2);
// Byte 5: 状态字
frame.data[5] = get_status_byte();
// Byte 6-7: 最高温度
frame.data[6] = max_temperature + 40; // -40~215°C
frame.data[7] = 0;
can_transmit(&frame);
}
测试验证
精度测试
| 参数 | 标称值 | 实测值 | 误差 |
|---|---|---|---|
| 电压 | 3.650V | 3.648V | 2mV |
| 电流 | 10.0A | 9.95A | 0.5% |
| SOC | 80% | 78% | 2% |
保护功能测试
| 测试项目 | 阈值 | 动作时间 | 结果 |
|---|---|---|---|
| 过充保护 | 4.25V | 1.02s | ✓ |
| 过放保护 | 2.80V | 510ms | ✓ |
| 过流保护 | 50A | 105ms | ✓ |
| 短路保护 | 150A | <1ms | ✓ |
均衡效果测试
初始压差:15mV 均衡 2 小时后:2mV 均衡效率:87%
成本分析
| 项目 | 成本 (RMB) |
|---|---|
| AFE 芯片 | 25 |
| MCU | 8 |
| MOSFET | 6 |
| 电流检测 | 3 |
| PCB+ 外壳 | 15 |
| 其他 | 8 |
| 总计 | 65 |
开源资料
参考资源
| 资源类型 | 链接 | 说明 |
|---|---|---|
| BMS 开源项目 | https://github.com/topics/bms | GitHub BMS 项目合集 |
| 原理图参考 | https://oshwhub.com/search?q=BMS | 立创 EDA 开源平台 |
| 固件源码 | https://github.com/xinyuan-lily/BMS | 开源 BMS 固件 |
| 上位机软件 | https://github.com/xinyuan-lily/BMS-Host | Python 上位机 |
推荐学习
- TI 参考设计: BMS 设计指南
- ADI 教程: 电池管理系统基础
- 论坛社区: 电源网 BMS 论坛
总结
本项目完整实现了 BMS 的硬件设计、SOC 算法、保护策略和通信功能。通过开源分享,为电池管理系统开发提供参考。
项目周期:6 周 | 代码量:4000 行 | 版本:v1.5