项目概述

本项目设计并实现了一款 8 串锂电池管理系统 (BMS),支持 30A 持续放电、主动均衡、SOC/SOH 估算和 CAN 通信,适用于电动自行车、储能电源等应用。

技术指标

参数规格
串数8S (29.6V 标称)
持续电流30A
峰值电流60A (10s)
均衡电流100mA
电压精度±2mV
电流精度±1%
SOC 精度±3%

硬件设计

系统架构

BMS 系统架构图

信号流向

  1. 电池组 → AFE:8 串电池电压采集
  2. AFE → MCU:I2C 数字接口
  3. 传感器 → MCU:ADC 模拟输入
  4. 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

电压采集电路

电压检测电路图

工作原理

  1. 8 串电池通过分压电阻网络连接到 AFE
  2. 每节电池电压经过 RC 滤波(10kΩ + 100nF)
  3. ISL94208 内置 ADC 依次采样各串电压
  4. 通过 I2C 接口将数据发送给 MCU

关键参数

  • 分压电阻:10kΩ × 8
  • RC 滤波:fc ≈ 160Hz
  • 测量精度:±2mV

电流检测电路

电流检测电路图

工作原理

  1. 电流流过分流电阻产生压降(60A × 0.5mΩ = 30mV)
  2. INA240 差分放大器增益 20 倍(输出 600mV)
  3. MCU ADC 采集输出电压
  4. 计算得到实际电流值

关键参数

  • 分流电阻: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

工作原理

  1. 充电模式 (BAT(n)→BAT(n+1))

    • Q1 PWM 调制,Q2 关断
    • 电感储能后释放到高电压电池
  2. 放电模式 (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.650V3.648V2mV
电流10.0A9.95A0.5%
SOC80%78%2%

保护功能测试

测试项目阈值动作时间结果
过充保护4.25V1.02s
过放保护2.80V510ms
过流保护50A105ms
短路保护150A<1ms

均衡效果测试

初始压差:15mV 均衡 2 小时后:2mV 均衡效率:87%

成本分析

项目成本 (RMB)
AFE 芯片25
MCU8
MOSFET6
电流检测3
PCB+ 外壳15
其他8
总计65

开源资料

参考资源

资源类型链接说明
BMS 开源项目https://github.com/topics/bmsGitHub BMS 项目合集
原理图参考https://oshwhub.com/search?q=BMS立创 EDA 开源平台
固件源码https://github.com/xinyuan-lily/BMS开源 BMS 固件
上位机软件https://github.com/xinyuan-lily/BMS-HostPython 上位机

推荐学习

总结

本项目完整实现了 BMS 的硬件设计、SOC 算法、保护策略和通信功能。通过开源分享,为电池管理系统开发提供参考。


项目周期:6 周 | 代码量:4000 行 | 版本:v1.5