3. 硬件滤波与软件滤波:RC滤波截止频率选择与滑动平均滤波算法

滤波这件事,说白了就是跟噪声打架。无感启动时电流采样信号里全是高频毛刺,你不把它滤干净,过流保护就会乱跳。我见过太多工程师一上来就调软件参数,结果发现硬件底子没打好,怎么调都白费力气。

这一章咱们就聊聊两种滤波手段——硬件RC滤波和软件滑动平均。它们不是二选一的关系,而是搭档。你想想看,硬件帮你干掉高频噪声,软件再平滑掉剩余的低频波动,这样过流保护才能既灵敏又稳定。

3.1 硬件RC滤波:第一道防线

RC低通滤波是最常用的硬件抗混叠手段。它的原理很简单——电容对高频信号呈现低阻抗,把高频分量旁路到地。但实际选型时,很多人只记得公式 f_c = 1 / (2πRC),却忽略了几个关键约束。

3.1.1 截止频率怎么定?

我个人习惯把截止频率放在PWM开关频率的1/10到1/20之间。举个例子,如果PWM是20kHz,那RC截止频率就选1kHz~2kHz。为什么?因为电流采样信号的主要能量集中在几百Hz以内,而PWM开关噪声在20kHz附近。留出足够的衰减带,才能保证有用信号不被过度削弱。

PWM频率 推荐RC截止频率 RC典型值(R=1kΩ)
10 kHz 500 Hz ~ 1 kHz C = 0.16 ~ 0.33 μF
20 kHz 1 kHz ~ 2 kHz C = 0.08 ~ 0.16 μF
40 kHz 2 kHz ~ 4 kHz C = 0.04 ~ 0.08 μF
注意:RC滤波会引入相位延迟。截止频率越低,延迟越大。对于无感启动这种需要快速响应的场景,延迟过大会导致过流保护动作滞后。我曾经在一个项目中把截止频率压到200Hz,结果启动瞬间电流都冲到额定值的2.5倍了,保护还没触发——就是因为RC把信号拖慢了。

3.1.2 电阻电容选型避坑

选R和C时,不能只看截止频率。电阻值太大会增加采样电路的输出阻抗,影响ADC的采样精度。我一般把R控制在100Ω~10kΩ之间。电容则要注意耐压和温度系数,X7R或C0G材质比较靠谱。

还有一个容易被忽略的点——RC滤波器的输入阻抗。如果前级是运放输出,那还好说。但如果直接接在采样电阻两端,RC网络会分流一部分电流,造成测量误差。这时候R不能太大,否则误差会超过1%。

小技巧:在RC滤波后加一级电压跟随器(运放缓冲),可以隔离后级ADC的采样电容充放电对RC网络的影响。这个做法在高速ADC采样时尤其重要。

3.2 软件滑动平均滤波:第二道防线

硬件滤波搞定了高频噪声,但中低频的随机波动还得靠软件来处理。滑动平均滤波(Moving Average Filter)是我在无感启动项目中最常用的算法。它简单、计算量小、效果直观。

3.2.1 算法原理

说白了就是取最近N个采样点的平均值。每来一个新数据,就把最老的那个丢掉,把新的加进来,重新算一次平均。公式长这样:

y[k] = (x[k] + x[k-1] + ... + x[k-N+1]) / N

N是窗口长度。N越大,平滑效果越好,但响应也越慢。这个道理跟RC滤波很像——你不可能既要平滑又要快速,得做取舍。

3.2.2 窗口长度怎么选?

我一般根据电流信号的基频来定。比如电机在低速运行时,电流变化周期大约是10ms。如果ADC采样周期是100μs,那一个周期内就有100个采样点。窗口长度取半个周期(50个点)左右,既能有效平滑,又不会把电流的真实变化给抹掉。

电机转速 电流周期 推荐窗口长度N
低速(~100 rpm) ~10 ms 40 ~ 60
中速(~1000 rpm) ~1 ms 10 ~ 20
高速(~10000 rpm) ~0.1 ms 3 ~ 8
核心原则:窗口长度不要超过电流信号最小周期的1/2。否则滑动平均会严重衰减电流的真实幅值,导致过流保护阈值形同虚设。

3.2.3 代码实现要点

滑动平均的代码不难写,但要注意几个细节。我习惯用环形缓冲区来存历史数据,这样每次更新时只需要做一次加法和一次减法,计算量恒定。

// 滑动平均滤波器 - 环形缓冲区实现
#define WINDOW_SIZE 32

typedef struct {
    float buffer[WINDOW_SIZE];
    uint8_t index;
    float sum;
    uint8_t count;
} MovingAverage;

float MovingAverage_Update(MovingAverage *ma, float new_sample) {
    // 减去最老的数据
    ma->sum -= ma->buffer[ma->index];
    // 存入新数据
    ma->buffer[ma->index] = new_sample;
    ma->sum += new_sample;
    // 更新索引
    ma->index = (ma->index + 1) % WINDOW_SIZE;
    // 返回平均值
    if (ma->count < WINDOW_SIZE) {
        ma->count++;
        return ma->sum / ma->count;
    }
    return ma->sum / WINDOW_SIZE;
}
注意:初始化时要把buffer全部清零,count置0。前N个采样点还没填满窗口时,直接用当前有效点数做平均,不要除以WINDOW_SIZE。否则初始阶段的输出会偏小。

3.3 硬件滤波 vs 软件滤波:谁主谁辅?

很多初学者会问:能不能只用软件滤波,省掉RC?我的回答是:可以,但不推荐。硬件滤波是物理层面的抗混叠,它能防止高频噪声进入ADC,避免采样信号发生频谱混叠。软件滤波只能处理已经进入数字域的信号,它没法消除混叠带来的失真。

反过来,只靠硬件滤波也不行。RC滤波的衰减特性是固定的,没法根据工况动态调整。而软件滤波的窗口长度可以随转速变化,灵活性更高。

所以我的做法是:硬件滤波负责干掉高频噪声(PWM开关频率以上),软件滤波负责平滑中低频波动(电流信号带宽以内)。两者配合,才能让过流保护既快又准。

一句话总结:硬件滤波是“防患于未然”,软件滤波是“亡羊补牢”。先防后补,才是正道。

3.4 知识体系总览

下面这张图把硬件滤波和软件滤波的关系、选型要点、以及它们在无感启动过流保护中的位置梳理清楚了。你可以把它当作调参时的参考地图。

硬件滤波与软件滤波知识体系 硬件滤波与软件滤波知识体系 滤波目标:无感启动电流信号 硬件RC低通滤波 软件滑动平均滤波 截止频率 = PWM频率 / 10 ~ 20 R: 100Ω ~ 10kΩ | C: X7R/C0G ⚠ 注意相位延迟对响应的影响 窗口长度N = 半个电流周期 环形缓冲区实现,计算量恒定 ⚠ 窗口过大 → 信号幅值衰减 硬件 + 软件 = 最佳组合 硬件滤波:抗混叠,防止高频噪声进入ADC 软件滤波:平滑中低频波动,适应不同工况

3.5 实战调参建议

最后分享一个我自己的调参流程。拿到一个新项目,我会先固定硬件RC参数(按PWM频率的1/15算),然后通过软件滑动平均的窗口长度来微调。具体步骤:

  1. 先测噪声频谱——用示波器看电流采样波形,确定主要噪声频段。
  2. 定RC截止频率——确保PWM开关频率处的衰减大于20dB。
  3. 设滑动平均窗口——从N=16开始,逐步增大,直到电流波形平滑但不过度失真。
  4. 验证过流保护响应——人为制造短路或过载,看保护动作时间是否在要求范围内。
避坑提醒:我曾经在一个项目中把滑动平均窗口设得太大(N=128),结果过流保护响应延迟了将近两个电流周期。电机都烧了,保护才跳。从那以后,我每次调完参数都会做一次短路测试,确保保护动作时间在200μs以内。

嗯,滤波这部分就聊到这儿。记住一个原则:硬件滤波做减法(去掉高频),软件滤波做平滑(不改变幅值)。两者配合好了,过流保护才能既灵敏又可靠。