【Zephyr电源与功耗专题】14_BMS电池管理算法(三重验证机制实现高精度电量估算)

发布于:2025-09-15 ⋅ 阅读:(13) ⋅ 点赞:(0)


前言

在嵌入式设备中,准确的电池电量管理是用户体验的关键因素之一。传统的单一电量估算方法往往存在精度不足、累积误差等问题。本文将深入分析一种基于三重验证机制的智能电池管理算法,该算法通过结合库仑计法、电压查表法和理论计算法,实现了高精度、高可靠性的电量管理。
电池管理算法的核心思想不管电池实际电流电压如何跳动,均需要呈现一个合理稳定且接近实际电量给用户看!!!

一、算法系统框架设计介绍

1.1:核心设计方式

该电池管理算法采用混合式电量估算方法,通过以下三个维度进行电量验证

  1. 库仑计法:基于电流积分的实时电量计算
  2. 电压查表法:基于电压-电量映射的绝对校准
  3. 理论计算法:基于欧姆定律的异常检测与补偿

1.2:系统架构图

					┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
					│   硬件数据采集   │    │   数据滤波处理   │    │   电量计算核心   │
					│                 │    │                 │    │                 │
					│ • 电压ADC采样   │───▶│ • 10点移动平均  │───▶│ • 三重验证机制  │
					│ • 电流ADC采样   │    │ • 异常值检测    │    │ • 偏差补偿算法  │
					│ • 温度传感器    │    │ • 数据平滑      │    │ • 状态自适应    │
					└─────────────────┘    └─────────────────┘    └─────────────────┘
					         │                       │                       │
					         ▼                       ▼                       ▼
					┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
					│   NV存储管理    │    │   校准机制      │       │   异常处理       │
					│                 │    │                 │    │                 │
					│ • 电量百分比    │    │ • 定期校准      │       │ • 电流偏差检测    │
					│ • 累积偏差      │    │ • 长时间休眠    │       │ • 备用方案       │
					│ • 时间戳        │    │ • 换电池检测    │       │ • 故障恢复      │
					└─────────────────┘    └─────────────────┘    └─────────────────┘

1.3:核心参数配置

#define MY_BAT_CAPACITY          460     // 电池容量 460mAh
#define BAT_CAPACITY_EQUAL_DIVISION 1.1  // 电池容量等分系数
#define BAT_IR                   0.5     // 系统等效内阻 0.5Ω
#define BAT_IR_WT                1.5     // 电池内阻加权系数
#define BAT_MIN_CURRENT          1.25    // 休眠时电流 1.25mA
#define SAMPLE_SIZE              10      // 采样缓冲区大小

说明:

  • 电池各项参数由供应商提供
  • 确定各项参数需要均衡选择
  • 休眠电流一般配置比实际大,以免实际电量耗尽死机 比 计算电量0%关机要提前。

二、核心算法详解

2.1:硬件数据采集与滤波

数据采集:

// 定时器回调函数 (1秒周期)
static void cpus_pmu_timer_callback(void *priv)
{
    // 硬件ADC采样
    pmu_manager_attr.vol_sampling = HAL_pmu_bat_volt_get();  // 电压采样
    pmu_manager_attr.cur_sampling = cpus_pmu_cur_get();     // 电流采样
    
    // 数据滤波处理
    pmu_voltage_smooth(&pmu_manager_attr);                  // 电压滤波
    pmu_current_smooth(&pmu_manager_attr);                  // 电流滤波
    
    // 电量计算
    pmu_percent_deal(&pmu_manager_attr);                    // 核心算法
}

移动平均滤波

// 10点移动平均滤波,有效抑制噪声
uint16_t pmu_voltage_smooth(pmu_manager_attr_t *pmup)
{
    // 异常值检测
    if((pmup->vol_sampling <= VOL_LOW_LIMIT) || (VOL_HIGH_LIMIT <= pmup->vol_sampling))
        return pmup->vol_buff_average;
    
    // 循环缓冲区更新
    pmup->vol_buff[pmup->vol_buff_i] = pmup->vol_sampling;
    pmup->vol_buff_i = (pmup->vol_buff_i + 1) % SAMPLE_SIZE;
    
    // 计算平均值
    uint32_t sum = 0;
    for(int i = 0; i < SAMPLE_SIZE; i++) {
        sum += pmup->vol_buff[i];
    }
    pmup->vol_buff_average = sum / SAMPLE_SIZE;
    
    return pmup->vol_buff_average;
}

2.2:三重算法机制

2.2.1:库仑计法(电流积分)

if (cur_cal < cur - 5 || cur_cal > cur + 5) {
			Debug_printf(DISP_KEY_PMU, "电流偏差过大,cur_cal = %d, cur = %d, 播放音乐 = %d\r\n", cur_cal, cur, HAL_gpio_value_get(PIN_B16));
			cur = cur_cal;
		}
		diff_per =(float)diff_time * -cur / 36000 / MY_BAT_CAPACITY * BAT_CAPACITY_EQUAL_DIVISION;
		if (diff_per < 0) {
			diff_per = 0;
		}
}
// 公式分解:
// diff_time: 时间差(秒)
// -cur: 放电电流为负值
// 36000: 3600秒/小时 × 10(单位转换)
// MY_BAT_CAPACITY: 电池容量460mAh
// BAT_CAPACITY_EQUAL_DIVISION: 容量等分系数1.1

说明:

  • 实时性好,响应速度快
  • 能准确反映瞬时电量变化
  • 适合动态负载场景
  • 存在累积误差问题

2.2.2:电压查表法(绝对校准)

// 电压-电量映射表
#define BAT_LEVEL_10PERCENT_VOLT  3725  // 0-9%
#define BAT_LEVEL_20PERCENT_VOLT  3758  // 10-19%
#define BAT_LEVEL_30PERCENT_VOLT  3781  // 20-29%
// ... 更多阈值点

// 电压到电量百分比转换
uint8_t pmu_v2p(uint16_t vol)
{
    if (vol >= BAT_LEVEL_100PERCENT_VOLT) return 100;
    if (vol >= BAT_LEVEL_90PERCENT_VOLT)  return 90;
    // ... 查表逻辑
}

分段线性插值算法

uint8_t pmu_v2p(uint16_t volt)
{
    // 1. 查找电压所在的区间
    for (i = 0; i < CV_TABLE_LEN; i++) {
        if (volt <= coulomp_voltage_table[i])
            break;
    }
    
    // 2. 线性插值计算
    percent = (float)(BAT_QUANTITY_STEP_PERCENT * i) + 
              (float)(volt - base) / step;
    
    return (uint8_t)percent;
}

算法特点

  • 绝对精度高,无累积误差
  • 适合静态或准静态场景
  • 可作为其他方法的校准基准
  • 受温度影响较大

2.3:理论计算法(异常检测)

2.3.1:电池等效电路模型:
    ┌─────────┐    ┌─────────┐
    │   OCV   │────│  R_int  │──── 负载
    │(开路电压)│    │ (内阻)   │
    └─────────┘    └─────────┘
// 基于欧姆定律的理论电流计算
int32_t vout_to_iout(uint16_t vout, uint16_t v_base)
{
    int32_t x = vout - v_base;  // 电压差
    
    if (pmu_manager_attr.vbus_status && pmu_manager_attr.charge_status) {
        // 充电状态:使用加权内阻
        i = (int32_t)((x) / (BAT_IR * BAT_IR_WT));
    } else {
        // 放电状态:使用标准内阻
        i = (int32_t)((x) / (BAT_IR));
    }
    
    return i;
}

说明:

  • 物理原理:电池等效为理想电压源串联内阻
  • 根据欧姆定律:I = (V_ocv - V_load) / R_internal
  • 通过理论电流与实际电流对比,检测异常
2.3.2:异常检测机制:
// 电流偏差检测
cur_cal = vout_to_iout(pmup->vol_buff_average, pmu_p2v(pmup->percent));
if (cur_cal < cur - 5 || cur_cal > cur + 5) {
    Debug_printf(DISP_KEY_PMU, "电流偏差过大,cur_cal = %d, cur = %d\r\n", cur_cal, cur);
    cur = cur_cal;  // 使用理论电流替代测量电流
}
2.3.3:累积偏差补偿
// 累积偏差双向补偿机制
if (pmup->de_accumulation < -0.1) {
    pmup->percent += 1;  // 电量增加1%
    pmup->de_accumulation += 0.1;
} else if (pmup->de_accumulation > 0.1) {
    pmup->percent -= 1;  // 电量减少1%
    pmup->de_accumulation -= 0.1;
}

补偿机制优势

  • 智能消耗:优先消耗相反方向的累积偏差
  • 精度提升:避免测量误差的长期累积
  • 双向平衡:充电和放电分别累积,相互补偿

三、数学模型(闭环反馈系统)

3.1:稳态平衡条件

当系统达到稳态时,必须满足以下平衡条件:
条件1:电流平衡

实际测量电流 ≈ 理论计算电流
即:|I_measured - I_calculated| ≤ 5mA

条件2:电压平衡

实际测量电压 ≈ 理论计算电压
即:V_measured ≈ V_theoretical = pmu_p2v(percent)

条件3:累积偏差平衡

充电累积偏差 ≈ 放电累积偏差
即:in_accumulation ≈ de_accumulation

3.2:收敛性数学证明

3.2.1 迭代方程

设第n次迭代:

  • 实际电流:I_n
  • 理论电流:I_cal_n
  • 电量百分比:P_n
  • 实际电压:V_n
  • 理论电压:V_cal_n
迭代关系:
P_{n+1} = P_n + ΔP_n  (基于I_cal_n计算)
V_cal_{n+1} = pmu_p2v(P_{n+1})
I_cal_{n+1} = vout_to_iout(V_n, V_cal_{n+1})

3.2.2:收敛条件

收敛条件:当 |I_cal_{n+1} - I_n| ≈ 0mA (足够小)时,系统达到稳态
收敛速度:取决于以下因素:
内阻精度:BAT_IR的准确性
电压表精度:coulomp_voltage_table的准确性
采样精度:ADC测量精度
负载稳定性:外部负载变化

3.3:收敛场景举例

场景:

  • 电流传感器突然出现偏差或更换电池
  • 与上一块电池断电时记录的电压相差较大
初始状态:
- 实际电流:100mA
- 理论电流:100mA
- 电量:50%
- 实际电压:3800mV
- 理论电压:3859mV

第1次迭代(电流传感器偏差+20mA):
- 实际电流:120mA (传感器偏差)
- 理论电流:100mA
- 偏差:|120-100| = 20mA > 5mA
- 系统使用理论电流:100mA
- 电量更新:基于100mA计算

第2次迭代:
- 实际电流:120mA (传感器仍有偏差)
- 理论电流:基于新电量重新计算
- 如果新理论电流接近120mA,则偏差减小

第N次迭代:
- 实际电流:120mA
- 理论电流:≈120mA
- 偏差:|120-120| = 0mA < 5mA
- 系统达到稳态

3.4:数学平衡的物理意义

3.4.1:能量守恒

累积偏差平衡:
充电累积 = 放电累积
∫I_charge dt ≈ ∫I_discharge dt

3.4.2:电荷守恒

累积偏差平衡:
充电累积 = 放电累积
∫I_charge dt ≈ ∫I_discharge dt

闭环模型总结:

这个电池管理系统是一个闭环反馈系统:
收敛机制:即使初始电流偏差很大,通过多次迭代反馈,系统会逐渐调整电量百分比,使得理论电流接近实际电流,最终达到稳态平衡。

四、睡眠检测机制

睡眠检测流程:

系统进入睡眠
    ↓
硬件睡眠检测 (RTC状态)
    ↓
软件睡眠检测 (timer_status)
    ↓
执行 drv_pmu_suspend()
    ├── 关闭ADC
    └── 记录睡眠时间
    ↓
系统唤醒
    ↓
执行 drv_pmu_resume()
    ├── 启用ADC
    ├── 计算睡眠时间
    ├── 计算理论电量消耗
    └── 判断是否需要唤醒
    ↓
执行 timer_long_time_not_active()
    ├── 判断休眠时间
    │   ├── <24小时:理论计算模式
    │   └── >24小时:重新校准模式
    ├── 更新电量百分比
    └── 发送电量变化事件

4.1:睡眠状态管理

进入睡眠

static int drv_pmu_suspend(struct cdev *dev)
{
    HAL_pmu_adc_enable(false);  // 关闭ADC以节省功耗
    return 0;
}

睡眠唤醒处理

static int drv_pmu_resume(struct cdev *dev)
{
    uint32_t diff_time = (uint32_t)(HAL_get_timestamp()/1000 - pmu_manager_attr.update_time);
    float diff_per = 0;
    HAL_pmu_adc_enable(true);  // 重新启用ADC
    
    // 计算睡眠期间的电量消耗
    diff_per = (float)diff_time * BAT_MIN_CURRENT / 36000 / MY_BAT_CAPACITY * BAT_CAPACITY_EQUAL_DIVISION;
    
    // 判断是否掉电累计1%。若是:唤醒系统进行电量更新
    if (diff_per + pmu_manager_attr.de_accumulation - pmu_manager_attr.in_accumulation > 1) {
        cpus_OAL_timer_activate(&pmu_manager_attr.pmu_suspend_timer, cpus_OAL_TIMER_AUTO_ACTIVATE);
    }
    return 0;
}

长时间休眠唤醒检测机制

void timer_long_time_not_active(void)
{
    uint32_t diff_time = (uint32_t)(HAL_get_timestamp()/1000 - pmu_manager_attr.update_time);
    float diff_per = 0;
    uint8_t old_percent = pmu_manager_attr.percent;
    static uint32_t last_mode = 0;
    
    pmu_manager_attr.update_time += diff_time;
    Debug_printf(DISP_KEY_PMU, "pmu_timer_activate = %d\r\n", diff_time);
    
    if (diff_time < 1000*60*60*24) {  // 小于24小时
        // 使用理论计算进行电量更新
        theoretical_calculation_mode();
    } else {  // 大于24小时
        // 重新采样校准
        recalibration_mode();
    }
}

五、算法特点与优势分析

5.1:三重验证机制的优势

1. 高精度保证

  • 库仑计法:提供实时动态响应
  • 电压查表法:提供绝对精度校准
  • 理论计算法:提供异常检测和补偿

2. 鲁棒性设计

  • 多重异常检测:电流偏差、电压范围、累积误差
  • 状态感知处理:充电/放电状态自适应
  • 故障恢复机制:长时间休眠自动校准

3. 工程实用性

  • 系统等效内阻:包含电池+PMU+PCB+连接器总内阻
  • 实际测量点:基于硬件ADC测量位置设计
  • 状态相关参数:充电/放电使用不同内阻值

5.2:算法精度分析

数据类型 获取方式 精度 响应时间 用途
实际电压 ADC采样 硬件精度 实时 主要测量数据
实际电流 ADC采样 硬件精度 实时 主要测量数据
理论电压 查表计算 1% 计算时间 参考基准
理论电流 欧姆定律 依赖内阻模型 计算时间 偏差检测
计算电压 反向计算 依赖电流精度 计算时间 校准验证

六、实际应用场景举例

6.1:正常放电场景

当前电量: 50%
理论开路电压: 3859mV (pmu_p2v(50))
实际端电压: 3800mV (ADC测量)
系统等效内阻: 0.5Ω
理论电流 = (3800 - 3859) / 0.5 = -118mA (放电)
电量变化量 = 1秒 × (-118mA) / 36000 / 460mAh × 1.1 = -0.008%

6.2:充电场景

当前电量: 50%
理论开路电压: 3859mV
实际端电压: 3900mV (充电器提供)
系统等效内阻: 0.75Ω (充电时加权)
理论电流 = (3900 - 3859) / 0.75 = 55mA (充电)
电量变化量 = 1秒 × 55mA / 36000 / 460mAh × 1.1 = 0.004%

6.3:电流偏差场景

实际测量电流: 120mA
理论计算电流: 118mA
偏差: |120 - 118| = 2mA < 5mA (正常范围)
实际测量电流: 150mA
理论计算电流: 118mA
偏差: |150 - 118| = 32mA > 5mA (异常)
处理: 使用理论电流118mA进行电量计算

特别说明:

  • 即计算电流差过大,但最后会恢复到差距较小的稳态(变闭环)

总结:

本文深入分析了一种基于三重验证机制的智能电池(BMS)管理算法,这种算法设计在嵌入式系统中是一个相对完善的电池电量管理方案,平衡了精度、实时性和计算复杂度,为类似应用提供了有价值的参考,其核心在于:

  • 过滤电压、电流跳动等情况
  • 为用户提供稳定可观的电量变化情况
  • 闭环算法使得计算电量靠近实际电量
  • 将电压分为110份,避免电池低电而计算电量未到0就关机的情况
  • 睡眠时自动进行校准