一阶低通滤波器系数的两种计算方法

在单片机控制程序中,经常能看到下面这种一阶低通滤波器:

c 复制代码
y += alpha * (x - y);

它也可以写成离散差分方程:
yk=(1−α)yk−1+αxkyk=(1-\alpha)yk-1+\alpha xk yk=(1−α)yk−1+αxk

其中:

  • xkxk xk 是当前采样值;
  • ykyk yk 是当前滤波输出;
  • α\alpha α 是滤波系数,通常满足 0<α≤10<\alpha\leq1 0<α≤1。

α\alpha α 越小,滤波越强,但响应越慢; α=1\alpha=1 α=1 时输出完全等于输入,相当于没有滤波。

工程中常见两种根据截止频率计算 α\alpha α 的方法:

  1. 指数映射法,即精确匹配连续系统的时间常数;
  2. 后向欧拉法,即将连续微分方程做数值离散化。

两种方法都来自同一个连续一阶低通模型,只是离散化方式不同。

1. 连续一阶低通模型

模拟RC低通滤波器满足:
τ dydt +y=x \tau\frac{dy}{dt}+y=x τdtdy+y=x

整理为:
dydt = x−yτ \frac{dy}{dt}=\frac{x-y}{\tau} dtdy=τx−y

其中 τ\tau τ 是滤波器时间常数。时间常数与截止频率的关系为:
τ= 1 2πfc \tau=\frac{1}{2\pi f_c} τ=2πfc1

这里 fc f_c fc 的单位是Hz。公式中出现 2π2\pi 2π,是因为微分方程使用角频率:
ωc=2πfc \omega_c=2\pi f_c ωc=2πfc

采样周期和采样频率的关系为:
Ts= 1fs T_s=\frac{1}{f_s} Ts=fs1

2. 方法一:指数映射法

假设一个采样周期内输入 xx x 保持不变,定义输入与输出之间的误差:
e=x−ye=x-y e=x−y

一阶系统的误差会按照指数规律衰减:
e(t+Ts)=e(t)e −Ts/τ e(t+T_s)=e(t)e^{-T_s/\tau} e(t+Ts)=e(t)e−Ts/τ

因此,一个采样周期后的输出为:
yk=xk+(yk−1−xk)e −Ts/τ yk=xk+\left(yk-1-xk\right)e^{-T_s/\tau} yk=xk+(yk−1−xk)e−Ts/τ

整理得到:
yk=yk−1+(1−e −Ts/τ )(xk−yk−1)yk=yk-1+\left(1-e^{-T_s/\tau}\right) \left(xk-yk-1\right) yk=yk−1+(1−e−Ts/τ)(xk−yk−1)

与标准代码形式对比:

c 复制代码
y += alpha * (x - y);

可以得到:
α=1−e −Ts/τ \boxed{\alpha=1-e^{-T_s/\tau}} α=1−e−Ts/τ

代入 Ts=1/fs T_s=1/f_s Ts=1/fs 和 τ=1/(2πfc)\tau=1/(2\pi f_c) τ=1/(2πfc):
α=1−e −2πfc/fs \boxed{\alpha=1-e^{-2\pi f_c/f_s}} α=1−e−2πfc/fs

从极点角度理解

连续一阶低通的极点是:
s=−2πfcs=-2\pi f_c s=−2πfc

经过采样后,连续极点映射到离散域:
z=e sTs =e −2πfc/fs z=e^{sT_s}=e^{-2\pi f_c/f_s} z=esTs=e−2πfc/fs

而差分方程的离散极点是 z=1−αz=1-\alpha z=1−α,所以:
1−α=e −2πfc/fs 1-\alpha=e^{-2\pi f_c/f_s} 1−α=e−2πfc/fs

最终仍然得到相同结果。

这种方法精确保持了连续系统的极点和时间常数,因此也常被称为精确极点映射或零阶保持离散化。

3. 方法二:后向欧拉法

从同一个连续微分方程出发:
dydt = x−yτ \frac{dy}{dt}=\frac{x-y}{\tau} dtdy=τx−y

使用后向差分近似导数:
yk−yk−1Ts = xk−ykτ \frac{yk-yk-1}{T_s}=\frac{xk-yk}{\tau} Tsyk−yk−1=τxk−yk

注意右侧使用的是当前输出 ykyk yk,这正是"后向欧拉"名称的来源。

整理方程:
yk= τ Ts+τ yk−1+ Ts Ts+τ xkyk=\frac{\tau}{T_s+\tau}yk-1 +\frac{T_s}{T_s+\tau}xk yk=Ts+ττyk−1+Ts+τTsxk

写成标准滤波形式:
yk=yk−1+α(xk−yk−1)yk=yk-1+\alpha\left(xk-yk-1\right) yk=yk−1+α(xk−yk−1)

得到:
α= Ts Ts+τ \boxed{\alpha=\frac{T_s}{T_s+\tau}} α=Ts+τTs

代入采样频率和截止频率:
α= 2πfc fs+2πfc \boxed{ \alpha=\frac{2\pi f_c}{f_s+2\pi f_c} } α=fs+2πfc2πfc

也可以定义:
r= 2πfc fs r=\frac{2\pi f_c}{f_s} r=fs2πfc

于是:
α= r1+r \alpha=\frac{r}{1+r} α=1+rr

后向欧拉法属于近似离散化,但它有一个重要优点:对于正的时间常数,计算得到的 α\alpha α 始终处于0到1之间,数值稳定性很好。

4. 两种方法为什么很接近

令:
r= 2πfc fs r=\frac{2\pi f_c}{f_s} r=fs2πfc

指数映射法为:
αexp =1−e−r \alpha_{exp}=1-e^{-r} αexp=1−e−r

后向欧拉法为:
αBE = r1+r \alpha_{BE}=\frac{r}{1+r} αBE=1+rr

当截止频率远低于采样频率,即 r≪1r\ll1 r≪1 时,可以做级数展开:
1−e−r=r−r22+⋯1-e^{-r}=r-\frac{r^2}{2}+\cdots 1−e−r=r−2r2+⋯
r1+r =r−r2+⋯ \frac{r}{1+r}=r-r^2+\cdots 1+rr=r−r2+⋯

两者的一阶项完全相同:
α≈ 2πfc fs \boxed{\alpha\approx\frac{2\pi f_c}{f_s}} α≈fs2πfc

所以,当 fc f_c fc 远低于 fs f_s fs 时,两种方法的实际差别很小。截止频率越接近采样频率,两种离散化方法的差别才会逐渐明显。

5. 数值计算示例

假设:
fs=20000 Hz,fc=100 Hz f_s=20000\text{ Hz},\qquad f_c=100\text{ Hz} fs=20000 Hz,fc=100 Hz

指数映射法

αexp =1−e−2π×100/20000≈0.03093 \alpha_{exp} =1-e^{-2\pi\times100/20000} \approx0.03093 αexp=1−e−2π×100/20000≈0.03093

后向欧拉法

αBE = 2π×10020000+2π×100 ≈0.03046 \alpha_{BE} =\frac{2\pi\times100}{20000+2\pi\times100} \approx0.03046 αBE=20000+2π×1002π×100≈0.03046

两者相差约1.5%,在大多数电机控制滤波场景中几乎没有明显区别。

6. 20kHz采样时的参数对比

截止频率 指数映射法 后向欧拉法 相对差异
20Hz 0.006263 0.006244 0.31%
23.5Hz 0.007356 0.007329 0.37%
30Hz 0.009381 0.009337 0.47%
50Hz 0.015585 0.015465 0.77%
100Hz 0.030928 0.030459 1.51%
200Hz 0.060899 0.059117 2.92%
500Hz 0.145364 0.135755 6.61%
1kHz 0.269597 0.239057 11.33%

可以看到,在20kHz采样、几十到几百赫兹截止频率的情况下,两种方法结果非常接近。

7. C语言实现

c 复制代码
#include <math.h>

#define PI_F 3.14159265358979323846f

/* 方法一:指数映射,精确匹配连续时间常数 */
static float lpf_alpha_exponential(float cutoff_hz, float sample_hz)
{
    return 1.0f - expf(-2.0f * PI_F * cutoff_hz / sample_hz);
}

/* 方法二:后向欧拉,计算简单且稳定 */
static float lpf_alpha_backward_euler(float cutoff_hz, float sample_hz)
{
    float r = 2.0f * PI_F * cutoff_hz / sample_hz;
    return r / (1.0f + r);
}

/* 一阶低通滤波器 */
static float lpf_update(float input, float previous_output, float alpha)
{
    return previous_output + alpha * (input - previous_output);
}

alpha 应在初始化阶段计算一次,不建议在高频中断中反复调用 expf()

如果采样频率和截止频率都是固定常量,也可以提前计算好系数:

c 复制代码
#define CURRENT_LPF_ALPHA 0.03093f   /* fs=20kHz, fc=100Hz, 指数映射 */

8. 应该选择哪一种

优先选择指数映射法的情况

  • 希望准确保持连续系统的时间常数;
  • 希望连续极点和离散极点严格对应;
  • 参数在初始化阶段计算,计算量不是问题。

公式为:
α=1−e −2πfc/fs \boxed{\alpha=1-e^{-2\pi f_c/f_s}} α=1−e−2πfc/fs

可以选择后向欧拉法的情况

  • 希望计算形式简单;
  • 需要始终保证 0<α<10<\alpha<1 0<α<1;
  • 截止频率远低于采样频率;
  • 希望沿用常见的数字RC滤波写法。

公式为:
α= 2πfc fs+2πfc \boxed{\alpha=\frac{2\pi f_c}{f_s+2\pi f_c}} α=fs+2πfc2πfc

复刻既有控制器时

如果目标是复刻原控制器,应优先保留原始系数。例如YKD3505M中的滤波系数:
α=24132768=0.0073547 \alpha=\frac{241}{32768}=0.0073547 α=32768241=0.0073547

在20kHz采样频率下,按照指数映射反算,对应时间常数频率约为23.5Hz。此时应先保持原系数验证整体算法,再根据新硬件和电机响应调整。

9. 一个容易忽略的严谨性问题

上面两种公式的 fc f_c fc 都来自连续RC模型。指数映射法精确保持连续系统的时间常数,后向欧拉法近似保持连续系统的动态特性。

fc≪fs f_c\ll f_s fc≪fs 时,离散滤波器实际的-3dB频率与目标值几乎一致;当截止频率已经接近采样频率时,这种近似会出现明显偏差。此时如果必须精确控制数字域的-3dB频率,应按照离散频率响应直接求系数,或者使用双线性变换设计IIR滤波器,而不应继续使用低频近似。

总结

两种系数计算方法并不矛盾:
α=1−e −2πfc/fs \alpha=1-e^{-2\pi f_c/f_s} α=1−e−2πfc/fs

来自连续一阶系统的精确指数响应;
α= 2πfc fs+2πfc \alpha=\frac{2\pi f_c}{f_s+2\pi f_c} α=fs+2πfc2πfc

来自后向欧拉离散化。

当截止频率远低于采样频率时,两者都近似为:
α≈ 2πfc fs \alpha\approx\frac{2\pi f_c}{f_s} α≈fs2πfc

在常见的电机控制场景中,只要明确采样频率、截止频率和使用的离散化方法,两种公式都可以可靠使用。

相关推荐
geovindu1 小时前
go: Enumeration Algorithm
开发语言·后端·算法·golang·枚举算法
退休倒计时2 小时前
【每日一题】LeetCode 287. 寻找重复数 TypeScript
算法·leetcode·typescript
奋发向前wcx2 小时前
y1,y2总复习笔记2 2026.7.15
java·笔记·算法
AI科技星2 小时前
《全域数学·工程应用大典》113–200讲完整总目录
数据结构·人工智能·算法·机器学习·线性回归·乖乖数学·全域数学
ttod_qzstudio2 小时前
【软考算法】软件设计师下午第四题算法总纲:从“直接放弃“到“稳稳拿分“
算法·软考
广州灵眸科技有限公司3 小时前
xfce桌面旋转说明:基于灵眸科技EASY-EAI-Nano-TB
网络·网络协议·tcp/ip·算法·php
得物技术3 小时前
从"机械应答"到"服务伙伴":得物高可控智能客服的 Agent 工程实践|AICon 演讲整理
算法·llm·agent
想要成为糕糕手3 小时前
NO.48 旋转图像 —— LeetCode 热题 100 面试导向深度解析
javascript·算法·面试
JieE2123 小时前
LeetCode 138 随机链表的复制|两种解法详解(哈希表 + 原地 O (1) 空间)
javascript·算法·面试