BMS均衡算法简介

一. 电池均衡软件算法介绍
1 、被动均衡方法一

​  以单体端电压为监督目标,当单体压差进入一定范围,均衡开启,开始发挥作用。设定均衡控制的触发阈值,比如极值与平均值的差值达到50mV起动均衡过程,5mV结束均衡。管理系统按照固定的采集周期采集每一串单体端电压,先计算平均值,再计算每只电芯电压与电压均值的差值,电芯编号按照差值大小排队。差值与设定阈值比较,若最大的差值在阈值范围内,触发均衡程序。后续策略与具体均衡实现形式有关。

2、 被动均衡方法二

​  常温状态下(20℃以上正常使用温度区间)当系统未进行充放电,电芯在电流 < 0.5A以下并保持2H(低温5H)以上时认为电池去极化效应完成,此时采集的电芯电压近似认为为开路电压(OCV),通过查SOC-OCV表得出当前电芯SOC,并计算出电量差异 ,例如5%(根据需求进行调整)时,则需要控制开启电芯电量高的均衡电路,通过放电调平电池间容量差异减小电芯间容量一致性差异。发生电芯欠压、电芯高低温故障、均衡故障、均衡电阻过温、均衡时间到达时,则关闭均衡控制。

3. 均衡算法规划

​  均衡规划:主被动均衡配合使用;电芯压差、SOC差异两种算法配合使用;

4. 均衡测试方法

​ 《GBT34131-2022电力储能用电池管理系统》 中要求:

原文链接:BMS——电池均衡算法_吴二鸣的博客-CSDN博客

二、软件实现方式
1.被动均衡【包内均衡】

均衡启动条件

1、处于充电状态

2、无单体电压采集故障

3、当前设备最低单体电压大于均衡开启电压(3.0V)

4、当前设备压差大于均衡开启压差(30mV)

满足以上所有条件则开启均衡

备注:3、4开启阈值参考配置参数。

均衡关闭条件

不满足均衡启动条件中的任意一个,则关闭均衡

均衡电流大小

TBD

备注

最多同时均衡4路电芯,且不支持相邻两节同时开启均衡

typedef struct
{
    U16 MaxVolt;            //最大电压
    U8  Max_Volt_Cell;      //最大电压单体数
    U16 MinVolt;            //最小电压
    U8  Min_Volt_Cell;      //最小电压单体数
    U8  MaxTemp;            //最高温度
    U8  MaxTemp_CellNmu;    //最高温度单体数
    U8  MinTemp;            //最低温度
    U8  MinTemp_CellNmu;    //最低温度单体数
    U16 AvgVolt;            //平均电压
    U32 SumVolt;            //总电压
}_Bms_CalculateData;

程序设计思路:

  1. 读取均衡通道,查看通道的开启状态
  2. 读取均衡使能状态,使能信息由BMS发出
  3. 停止均衡,先停止全部均衡,开始新的均衡
  4. 计算均衡通道
void Balance_Passive_Task(void)  
{
    S32 s32BalEnable = 0;

    if(u8OtpTestFg == TRUE)
    {
        return;
    }

    xSemaphoreTake(g_BQ76952_Comm_MutexSemaphore, portMAX_DELAY);

    //读取均衡通道,查看通道的开启状态
    Balance_Passive_Channel_Read();

    //读取均衡使能状态,使能信息由BMS发出
    (void)GetSigVal(MBMS_SAM_SIG_ID_BALANCE_ENABLE, &s32BalEnable);
    
    //停止均衡,先停止全部均衡,开始新的均衡
    Balance_Passive_Stop();

    //不为充电状态则不进行均衡判断
    if(TRUE != s32BalEnable
    || EVENT_HAPPEN == GetMsgVal(ALARM_ID_BMS_COMM_ERROR))
    {
        xSemaphoreGive(g_BQ76952_Comm_MutexSemaphore);
        return;
    }

    //计算均衡通道
    Balance_Passive_Cal_Cmd();

    //开启均衡
    Balance_Passive_Start();

    xSemaphoreGive(g_BQ76952_Comm_MutexSemaphore);
}

采样获取Bms_CalculateData的各种数据

单体电压冒泡排序

单体电压与系统最小电压的压差大于均衡开启电压压差

计算该数组位 g_u32BalanceCmd 记录开始均衡的单体位置

不开启相邻节均衡

加一道防护,防止相邻节开启

根据 g_u32BalanceCmd 开启均衡

void Balance_Passive_Cal_Cmd(void)
{
    S32 s32BalStaDV = 0;
    U8 CellCnt = 0;
    U16 celldiffvolt = 0;
    U8 BalCellCnt = 0;
    U8 GetSysBoardCellNum = 0;
    CELL_BALANCE_DATA BALANCE_DATA_cell;
    _Bms_CalculateData GetBmsData;
    U8 u8CellNo = 0;
    U8 u8Offset = 0;
    U8 u8LastOffset = 0;
    U8 u8AfeCnt = 0;
    BOOL blBalanceSts = FALSE;

    //单体个数
    GetSysBoardCellNum = g_SysSampleData.SysSampleCellNum;
    
    //读取BMS统计数据、电压、温度
    GetBmsData = SampleGetCalData();

    //读取均衡启动电压差
    (void)GetSigVal(MBMS_SET_SIG_ID_BALANCE_START_DIFF_VOLT, &s32BalStaDV);

    //当前设备最低单体电压大于均衡开启电压,比开启电压小也不开均衡
    if(GetBmsData.MinVolt < GetMsgVal(MBMS_SET_SIG_ID_BALANCE_START_VOLT))
    {
        return;
    }

    //对电压进行冒泡排序 --升序
    BALANCE_DATA_cell = bubble_sort();

    //依次判断每个引脚采集的电压值
    for(CellCnt = (GetSysBoardCellNum - 1); CellCnt > 0; CellCnt--)
    {
        //最多均衡路数--4路
        if(BalCellCnt < SYS_BALANCE_MAX_CELL_NUM)
        {
            //求与系统最小电压的电压差--从排序开始算电压差
            celldiffvolt = BALANCE_DATA_cell.CellVolt[CellCnt] - GetBmsData.MinVolt;
            
            //均衡开启条件:单体电压与系统最小电压的压差大于均衡开启电压压差
            if(celldiffvolt >= s32BalStaDV)//满足开启条件
            {
                u8CellNo = BALANCE_DATA_cell.Cellnum[CellCnt]-1;  //从0开始计数
                u8Offset = g_SysSampleData.u8PinNo[u8CellNo]; //记录电芯在全部采集引脚中的编号,从0开始计(用于配置均衡控制时使用)
                if((u8LastOffset == (u8Offset + 1)) || (u8LastOffset == (u8Offset - 1)))  //如果是相邻两个则开始下一次FOR循环
                {
                    continue;
                }
                //g_u32BalanceCmd[0] == 0 初始化为0 
                //u8Offset 会从0递增到16 经过上面if语句处理后不会出现相邻为1的情况 
                g_u32BalanceCmd[g_SysSampleData.DevID[u8CellNo]] |= 1UL << u8Offset;//电压都是在一片AFE芯片上采集的
                u8LastOffset = u8Offset;
                BalCellCnt++;
            }
        }
        else
        {
            break;
        }
    }
    
    //防止相邻节开启均衡
    g_u32BalanceCmd[u8AfeCnt]位10101010
    1 << 0,结果为 00000001。
    ~(1UL << CellCnt) 的结果为 11111110。
    g_u32BalanceCmd[u8AfeCnt] 与 11111110 进行按位与操作,结果为 10101010 & 11111110 = 10101010。
    此操作将 g_u32BalanceCmd[u8AfeCnt] 的第0位(最低位)设置为0,其余位保持不变。
    
    for(u8AfeCnt = 0; u8AfeCnt < g_SysSampleData.u8BQ76952Num; u8AfeCnt++)
    {
        for(CellCnt = 0; CellCnt <= SIGNAL_AFE_MAX_CELL_NUM; CellCnt++)
        {
            if(blBalanceSts == TRUE)
            {
                g_u32BalanceCmd[u8AfeCnt] &= ~(1UL << CellCnt);
            }
            blBalanceSts = (g_u32BalanceCmd[u8AfeCnt] >> CellCnt) & TRUE;
        }
    }
}

2.主动均衡

在均衡时可采用短时大电流,从而实现快速均衡;由此,主动均衡方式对电池的一致性要求相对不高,在性能上完胜被动均衡方式,即使其结构相对复杂、成本相对较高,仍可能成为未来BMS电量均衡的主流方式

【后续再做补充】

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值