3、电压采集技术:单体电压采集方案

电压采集,是BMS最基础、也是最关键的一环。你想想看,SOC估算、SOH评估、均衡控制,哪一样离得开准确的单体电压?

我个人习惯把电压采集方案分成两大类:AFE芯片方案分立器件方案。这两种方案我都用过,各有各的脾气。

3.1 单体电压采集方案

3.1.1 AFE芯片方案

AFE芯片,说白了就是专门干电压采集的“专业选手”。像ADI的LTC6811、TI的BQ79616、NXP的MC33771,这些都是市面上常见的型号。

AFE芯片的好处很明显:

  • 集成度高:一个芯片能搞定12~16串电池的电压采集
  • 精度好:典型精度能做到±1mV以内
  • 隔离方便:通过SPI或变压器隔离,轻松实现高低压隔离
  • 自带功能:被动均衡、温度采集、故障检测都集成在里面

我在项目中遇到过一个问题:某款AFE芯片在低温环境下,电压读数会漂移。后来查了手册才发现,芯片内部有个参考电压源,温度系数是±50ppm/°C。嗯,这个坑我踩过,所以现在选型时一定会看温度特性曲线。

核心要点:AFE芯片方案适合12串以上的高压电池包。如果你的项目是48V、72V或者更高,直接上AFE芯片,省心省力。

3.1.2 分立器件方案

分立器件方案,就是用运放、电阻、电容自己搭采集电路。说实话,现在用分立器件的越来越少了,但在某些场景下它还是不可替代的。

什么时候用分立器件?

  • 成本敏感:AFE芯片一颗要几十块,分立器件几块钱搞定
  • 串数很少:比如只有2~4串的电池包,用AFE芯片有点浪费
  • 特殊需求:需要更高的采样率,或者需要定制化的滤波特性

我曾经给一个两轮电动车项目做过方案,电池包只有4串,客户要求成本压到最低。我用了差分运放+多路复用器+MCU内置ADC的方案,成本控制在3块钱以内。精度嘛,±5mV,够用了。

注意:分立器件方案对PCB布局要求很高。差分走线必须等长、等距,参考地要干净。否则噪声会直接耦合进采样信号,精度根本没法保证。

3.2 电压采样精度与误差分析

精度这东西,说起来简单,做起来全是坑。我见过太多人只看芯片手册上的“典型精度”,结果实际做出来差了一大截。

误差来源主要有这几个:

误差来源 典型值 影响程度
AFE芯片内部ADC量化误差 ±0.5mV 中等
参考电压温漂 ±50ppm/°C
分压电阻精度 ±0.1%
PCB走线压降 ±0.2mV
共模干扰 ±1mV

为什么会这样?我举个例子。假设你用了0.1%精度的分压电阻,在4.2V的电压下,误差就是4.2V × 0.1% = 4.2mV。这个误差已经比AFE芯片本身的精度大好几倍了。

所以我的习惯是:分压电阻必须用0.05%甚至0.01%的精密电阻。虽然贵一点,但省心。

避坑指南:我曾经在一个项目中,用了便宜的厚膜电阻,结果温度一变化,电压读数就飘。后来换成金属箔电阻,问题解决了。记住:电阻的温度系数比精度更重要。

3.3 电压采样滤波算法

硬件采集完了,软件还得做滤波。为什么?因为电池电压不是稳定的直流信号,它上面叠加了很多噪声:

  • 电机PWM开关噪声(几百kHz)
  • DC-DC变换器纹波(几十kHz)
  • 电池自身电化学噪声(低频)

我常用的滤波算法有三种,各有适用场景:

3.3.1 滑动平均滤波

最简单,也最常用。说白了就是取最近N次采样的平均值。

// 滑动平均滤波
#define FILTER_WINDOW 8
uint16_t buffer[FILTER_WINDOW];
uint8_t index = 0;
uint32_t sum = 0;

uint16_t moving_average_filter(uint16_t new_value) {
    sum -= buffer[index];
    buffer[index] = new_value;
    sum += new_value;
    index = (index + 1) % FILTER_WINDOW;
    return sum / FILTER_WINDOW;
}

这个算法有个问题:窗口越大,延迟越大。8次采样,如果采样率是100Hz,延迟就是80ms。对于SOC估算来说,这个延迟可以接受。

3.3.2 一阶低通滤波

适合滤除高频噪声,计算量小,适合嵌入式MCU。

// 一阶低通滤波
#define ALPHA 0.1  // 滤波系数,范围0~1

uint16_t low_pass_filter(uint16_t new_value, uint16_t last_value) {
    return (uint16_t)((float)last_value + ALPHA * ((float)new_value - (float)last_value));
}

ALPHA值怎么选?我一般这样估算:如果采样率是100Hz,想滤除10Hz以上的噪声,ALPHA取0.1左右。具体可以查一下“截止频率”的计算公式。

3.3.3 中值滤波

这个算法对付“毛刺”特别有效。比如电池连接器接触不良,偶尔跳出一个异常值,中值滤波直接把它干掉了。

// 中值滤波
#define MEDIAN_WINDOW 5

uint16_t median_filter(uint16_t *data, uint8_t len) {
    uint16_t temp[MEDIAN_WINDOW];
    for(uint8_t i = 0; i < len; i++) temp[i] = data[i];
    // 冒泡排序
    for(uint8_t i = 0; i < len - 1; i++) {
        for(uint8_t j = 0; j < len - 1 - i; j++) {
            if(temp[j] > temp[j+1]) {
                uint16_t t = temp[j];
                temp[j] = temp[j+1];
                temp[j+1] = t;
            }
        }
    }
    return temp[len / 2];
}

我的建议:实际项目中,我通常把三种算法组合使用。先用中值滤波去掉毛刺,再用滑动平均平滑数据,最后用一阶低通滤除高频噪声。三层滤波下来,电压数据基本就干净了。

嗯,这里要注意:滤波不是越强越好。滤波太狠,真实电压变化会被“抹平”,导致SOC估算响应变慢。我一般把滤波后的延迟控制在100ms以内,这样既干净又及时。

电压采集技术知识体系 电压采集技术 采集方案 精度与误差分析 滤波算法 AFE芯片方案 分立器件方案 量化误差 温漂误差 共模干扰 滑动平均 一阶低通 中值滤波 硬件方案决定精度上限,软件滤波决定实际表现 两者缺一不可

好了,电压采集这块就聊到这儿。记住一句话:硬件方案决定精度上限,软件滤波决定实际表现。两者缺一不可。