打印

授之与渔:免费教你设计一个数字滤波器

[复制链接]
17636|82
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
highgear|  楼主 | 2010-7-27 22:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 highgear 于 2010-7-28 10:08 编辑

这个帖子通过讲解 rc 滤波器的设计过程, 可以学会如何设计一个迭代的数字滤波器。今后可以举一反三, 对于其他高阶的 iir 滤波器也不至于手足无措了。

  数字滤波器在 mcu 应该经常被用到,在whlz58 同学的帖子里(https://bbs.21ic.com/viewthread.php?tid=170880&highlight=%E7%AE%97%E6%B3%95), whlz58同学提出了一个非常简洁的算法,这个算法来自于whlz58自己的经验总结,非常难得。我想从理论方面简单的讨论一下数字滤波器的设计,就以大家熟悉的 RC 滤波电路为例, 从理论到实践,为大家以后设计提供一点参考。

(1)由微分方程得到迭代公式
RC滤波电路很简单,就不给出电路图了。假设输入为Vi, 输出为Vo, 那么电流为:
     i = C * dVo/dt
可以得到
     Vo = Vi – R* I = Vi – RC * Vo/dt
整理后,可得输入与输出的微分方程:
     Vo – RC * dVo/dt = Vi

假设我们的系统的采样时间为T, 具体说,设定一个时间为T 的定时中断,每次用AD 采样一个输入 x; 我们可以把微分方程化成差分方程:
  由于   dy/dt -- (y(k+1) – y(k))/ T
  则  Vo – RC * dVo/dt = Vi, 成为: 
   y – (RC/T) * ((y(k+1) – y(k)) = x(k)

令 a = RC/T, b = T/RC, 可得:

     a*y(k+1) = a*y(k) – y(k) + x(k)  或者  y(k+1) = y(k) – b*y(k) + b*x(k)

上面的两个公式,关系到应用时的滤波器增益问题,后面再说。

分析:可以看出,上述公式必须保证 1-b > 0 才能成立,也就是说, 必须保证 T > RC.

(2) 由传递函数得到迭代公式
    很多简单的滤波器都可以找到微分方程, 但是复杂一些的滤波器用微分方程描述就令人头痛了。这时候,使用laplace 的传递函数,就很有必要了,而且基本上,高阶的滤波器如车你雪夫等等,都是以传递函数函数形式存在的。我们知道,RC 电路突然加电DC,Vo 输出是一个指数函数:
      vo(t) = Vdc – Vdc* e^(t/RC)

  其实, 这是RC的阶越响应。RC的冲击响应是
      v(t) = e^(t/RC)

冲击响应就是滤波器的内核(kernel), 实际上,传递函数函数就是一个系统的冲击响应。

我们来看看最简单的指数函数的传递函数:
     f = 1/(s + 1/RC)  
这个是RC滤波器的传递函数, 而且忽略了增益问题。我们可以用很多种方法把它转化成离散的 z 变换方程,学过数值算法的同学应该知道数值积分的方法吧, 其中,最简单的是欧拉公式:
    y(k+1) = y(k) + x(k) * T

(未完)
评分
参与人数 4威望 +4 收起 理由
ccmc + 1 不错,mark
触觉的爱 + 1
dong_abc + 1
xuyiyi + 1

相关帖子

沙发
highgear|  楼主 | 2010-7-27 23:00 | 只看该作者
用欧拉公式可以得出变换: s = (z-1)/T. 所以, 我们可以得到:
      f(z) = 1/((z-1)/T + 1/RC) = T/(z + b -1).

由于RC 是线性系统,所以可以再次忽略增益:
      f(z) = 1/(z + b -1)
由此可以得到迭代公式:
      y*(z + b -1) = x;
     y(k+1) = (1-b)*y(k) + x(k)

(3) 增益问题
      y(k+1) = (1-b)*y(k) + x(k) 与 y(k+1) = y(k) – b*y(k) + b*x(k) 有一点不同,这是增益问题。由于系统是线性系统,所以如果 x’ = n*x, 那么 y’ = f(x’) = f(n*x) = n*f(x) = n*y, 就是说如果把输入x 增大数倍,那么相应的输出也会增大数倍。一个系统的增益怎么计算呢?用z 传递函数和容易求得:
      f(z) = 1/(z + b -1), 那么 f(1) = 1/(1 +b -1) = 1/b = RC/T.

因此,可以看出由微分方程得出的迭代公式的增益为 1。
而 y(k+1) = (1-b)*y(k) + x(k) 的增益为 1/b = RC/T.

(4) 实践中的问题

(待续)

使用特权

评论回复
板凳
highgear|  楼主 | 2010-7-28 10:13 | 只看该作者
是这个问题太简单了以至于大家都不感兴趣, 还是我写的太随意了?

使用特权

评论回复
地板
sheriff| | 2010-7-28 10:26 | 只看该作者
继续,还是比较有收获的,虽然有的地方不完全懂

使用特权

评论回复
5
ahljj| | 2010-7-28 10:28 | 只看该作者
学习了

使用特权

评论回复
6
望断云山| | 2010-7-28 10:30 | 只看该作者
很好,请继续!:lol

使用特权

评论回复
7
highgear|  楼主 | 2010-7-28 10:33 | 只看该作者
不懂的地方可以提出来, 我尽量的予以解答。

使用特权

评论回复
8
sheriff| | 2010-7-28 10:49 | 只看该作者
y(k+1) = y(k) – b*y(k) + b*x(k)
此公式及其推导过程能看懂,这也是平时用的一阶低通滤波算法,
y(k+1) = (1-b)*y(k) + x(k)
这个就不懂了,本次采样值前面怎么少乘了个系数?

使用特权

评论回复
9
highgear|  楼主 | 2010-7-28 10:49 | 只看该作者
之所以引出增益的问题, 是为了应用时效率的考虑。如果计算中使用了float 类型, 那么我们不必考虑太多。但是如果使用定点整数运算, 那么我们可以调整输入x 的系数, 已达到简化运算的目的。
例如:  y(k+1) = y(k) – b*y(k) + b*x(k) 中b < 1, 所以使用 b*x 不恰当处理会损失一部分精度。
而 y(k+1) = (1-b)*y(k) + x(k) 可以看到16bit 的 x 完全没有损失精度, 而且如果 b 采用 2 的次方, 比如 1/16, 那么运算可以变得更为简单:
   int32 y, yout;
   int16 x;

   y = y - yout + x;
   yout = y >> 4;

(未完)
yout 就是 rc 数字滤波器的输出.

使用特权

评论回复
10
highgear|  楼主 | 2010-7-28 10:57 | 只看该作者
回 8 楼:
上面两个公式中的 y 增益不同。因为是线性系统, 如果把 x 增大 1/b 倍, 也就是
x' = 1/b*x,
那么, 输出自然也会增大 1/b 倍, 也就是说:
y' = (1-b)*y' + x'   与 y  = (1-b)*y + b*x
中y'与y 的关系为:
y' = y / b

使用特权

评论回复
11
xuyiyi| | 2010-7-28 11:00 | 只看该作者
顶!
支持highgear大师!
写的好,俺坐着听highgear大师上课!

使用特权

评论回复
12
sheriff| | 2010-7-28 11:30 | 只看该作者
10# highgear
可不可以理解为y' = (1-b)*y' + x'这个公式是把采样值x(k)放大1/b倍后再参与计算呢?如果是这样,这个公式貌似就不能反映RC低通的输入输出之间的关系,因为RC低通滤波并没有把输入量放大1/b的环节啊。粗浅理解,还请指教。

使用特权

评论回复
13
宇宙飞船| | 2010-7-28 12:26 | 只看该作者
进来坐听楼主讲课。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
xlsbz + 1
14
电子菜鸟435| | 2010-7-28 12:48 | 只看该作者
则  Vo – RC * dVo/dt = Vi, 成为: 
   y – (RC/T) * ((y(k+1) – y(k)) = x(k)

令 a = RC/T, b = T/RC, 可得:

     a*y(k+1) = a*y(k) – y(k) + x(k)  或者  y(k+1) = y(k) – b*y(k) + b*x(k)
能由第一个式子得到第二个式子吗?
a*y(k+1) = a*y(k) – y(k) + x(k) 是不是应该是a*y(k+1) = a*y(k) +y(k) - x(k)

使用特权

评论回复
15
lbx_00| | 2010-7-28 13:48 | 只看该作者
模拟电路离散化,数字化, 就可以写程序了

使用特权

评论回复
16
ff_hust| | 2010-7-28 14:03 | 只看该作者
s = (z-1)/T?

使用特权

评论回复
17
粉丝| | 2010-7-28 14:23 | 只看该作者
数年前,俺反推过数字滤波的叠代公式,但是一下子也忘了,得复习一下,先听课,这个贴子有得扯。

使用特权

评论回复
18
大碗拉面| | 2010-7-28 14:54 | 只看该作者
so cool!

使用特权

评论回复
19
英雄无敌六| | 2010-7-28 14:54 | 只看该作者
我只会用matlab的FDATOOL设计系统函数,再转成差分方程,怎么推倒的已经交回老师了。

使用特权

评论回复
20
zw83724229| | 2010-7-28 16:35 | 只看该作者
学习学习

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
yu2818679526 + 1 淡定
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

1222

帖子

61

粉丝