一阶低通滤波:从连续模型到离散实现(含工程代码)
在电机控制、传感器信号处理和嵌入式系统中,一阶低通滤波(First-Order Low-Pass Filter, LPF)几乎是最常用、也是最容易被误用的基础模块之一。
1. 为什么需要一阶低通滤波?
在实际系统中,我们经常会遇到以下问题:
- 编码器角度差分得到的速度噪声很大
- ADC 采样存在抖动和高频干扰
- 控制环(PI / PID)对高频噪声极其敏感
低通滤波的目的只有一个:
抑制高频噪声,只保留系统真实的低频动态。
2. 连续时间的一阶低通模型
最经典的一阶低通模型来自 RC 电路,其微分方程为:
\[\tau \frac{dy(t)}{dt} + y(t) = x(t)
\]
等价写成:
\[\frac{dy(t)}{dt} = \frac{1}{\tau}\big(x(t) - y(t)\big)
\]
其中:
- \(x(t)\):输入信号
- \(y(t)\):滤波后输出
- \(\tau\):时间常数(决定滤波强度)
3. 离散化的前提条件
在嵌入式系统中,信号是周期性采样的:
- 采样周期:\(dt\)
- 只在 \(t = k \cdot dt\) 进行一次计算
同时我们做一个关键假设(工程默认):
在一个采样周期内,输入信号保持不变(ZOH)
4. 从连续到离散:前向欧拉法
对导数项进行离散近似:
\[\frac{dy}{dt} \approx \frac{y[k] - y[k-1]}{dt}
\]
代入连续方程:
\[\frac{y[k] - y[k-1]}{dt} = \frac{1}{\tau}\big(x[k] - y[k-1]\big)
\]
整理得到:
\[y[k] = y[k-1] + \frac{dt}{\tau}\big(x[k] - y[k-1]\big)
\]
5. 标准离散形式(指数平滑)
引入参数:
\[\alpha = \frac{dt}{\tau}
\]
即可得到工程中最常见的一阶低通公式:
\[y[k] = y[k-1] + \alpha \big(x[k] - y[k-1]\big)
\]
这个公式的直觉含义是:
每个采样周期,输出只向输入靠近一小步。
6. 更稳定的工程写法(推荐)
严格来说,前向欧拉在 \(dt\) 较大时存在误差。利用连续系统的精确解,可以得到更稳定的参数形式。
连续系统在一个采样周期内的精确解:
\[y[k] = x[k] + (y[k-1] - x[k])e^{-dt/\tau}
\]
整理后仍然是同一形式:
\[y[k] = y[k-1] + \alpha (x[k] - y[k-1])
\]
其中参数 \(\alpha\) 推荐定义为:
\[\alpha = 1 - e^{-dt/\tau}
\]
7. 离散实现中的“因果性”问题
注意公式中使用的是 \(x[k] - y[k-1]\) 而不是 \(x[k] - y[k]\)。
原因很简单:在计算时刻 \(k\),\(y[k]\) 还不存在,系统只能使用上一次的状态 \(y[k-1]\)。这保证了滤波器是一个因果、可实时实现的系统。
8. 代码实现(C / MCU 风格)
typedef struct {
float y; // 滤波输出
float alpha; // 滤波系数
} LPF1_t;
/**
* @brief 一阶低通滤波更新函数
* @param f 滤波器结构体指针
* @param x 当前输入值
*/
void LPF1_Update(LPF1_t *f, float x)
{
// y(k) = y(k-1) + alpha * (x(k) - y(k-1))
f->y += f->alpha * (x - f->y);
}

浙公网安备 33010602011771号