0 授之与渔:免费教你设计一个数字滤波器 - 第2页 - 单片机论坛,单片机技术交流论坛 - 21ic电子技术开发论坛
打印

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

[复制链接]
楼主: highgear
手机看帖
扫描二维码
随时随地手机跟帖
21
lz你第一步好像有问题,就是:
”Vo=Vi-RC(dVo/dt),所以Vo-RC*(dVo/dt)=Vi“
符号笔误了好像。
应该是:
”Vo+RC*(dVo/dt)=Vi“

使用特权

评论回复
22
Wxy8030| | 2010-7-28 19:01 | 只看该作者
mark !

使用特权

评论回复
23
Siderlee| | 2010-7-28 19:09 | 只看该作者
加油

使用特权

评论回复
24
宇宙飞船| | 2010-7-28 21:21 | 只看该作者
听完课,俺也提了一个问题贴,放到AVR板块中去了,就当是楼主的课后练习。
有兴趣的朋友大可一试身手,看看学习接受效果如何。

使用特权

评论回复
25
highgear|  楼主 | 2010-7-28 21:35 | 只看该作者
谢谢 zhulu18. 不好意思,确实写错了。应为
Vo+RC*(dVo/dt)=Vi
y + (RC/T) * ((y(k+1) – y(k)) = x(k)

使用特权

评论回复
26
highgear|  楼主 | 2010-7-28 21:36 | 只看该作者
(4) 实践中的问题
   实际应用中,计算使用float 类型,可以让程序变得相对简单,而且不必考虑太多, 这是用效率换来的。对于8-bit或者是16-bit的cpu 来说,很多的时候需要追求效率,以减少资源消耗。大部分的时候,滤波器等等运算可以使用16-bit, 32-bit 的运算来取代float 运算。假设,滤波器的 z 变换公式为:
         f(z) = (a3*z^3 + a2*z^2 + a1*Z * + a0)/( (b3*z^3 + b2*z^2 + b1*Z * + b0)

我们可以重新构造一个新的函数
         g(z) = Ka* (a3*z^3 + a2*z^2 + a1*Z * + a0) / (Kb* (b3*z^3 + b2*z^2 + b1*Z * + b0))
    =(c3*z^3 + c2*z^2 + c1*Z * + c0)/( (d3*z^3 + d2*z^2 + d1*Z * + d0)
这么做不会改变滤波器的滤波特性,改变的是最后输出的幅度,即增益。调整系数的目的是为了更好的实现整数运算。比如AD 为 12-bit, 那么
(a)  调整 a3, a2, a1, a0 可以获取输入计算最大精度。把其中最大的值比如 a2调整为c2, 取值在 0.9 – 1.0 之间,比如0.98,这样可以把c2 乘以2^15, d2*32768 = 0.98*32768 = 32112, 这样在运算中只要把a3*x(k) + a2*x(k-1) + a1*x(k-2) +a0*(k-3)  右移15 位,则可以得到正确的结果

(b) 调整 b3, b2, b1, b0 可以获取输出运算最大精度,并可以让参与运算的 y(k), y(k-1)等等 保持为16-bit, 虽然最后的运算结果y(k+1)是32-bit.

(c) 最后的结果 y(k+1) 做增益调整,得到正确的输出。调整增益为
      g(1) = (c3+c2+c1+c0)/(d3+d2+d1+d0)
正确的输出为:Yout = y(k+1)/g(1)

使用特权

评论回复
27
highgear|  楼主 | 2010-7-28 21:55 | 只看该作者
总结:
(1) 由微分方程得到一个迭代公式是非常有用的方法,不仅可以用来构造滤波器,也可以用于产生其它迭代运算。
(2) 由s 传递函数推导出 z 传递函数,从而可以得到迭代公式。其中的重要的变换为 s = (z - 1)/T, 这也被称为0阶保持。1阶保持精度更高些,但一般没有必要.
(3) 调整系数以便于整数运算,浮点运算也可以因此减少一些运算量。
(4) 最后再调整输出。调整增益为 Y(k+1) / g(1),增益使把z 传递函数中的z = 1.

以上的方法不仅仅是用于滤波器, 也适用于各种数字控制和计算。

使用特权

评论回复
28
lfjwfm| | 2010-7-28 21:58 | 只看该作者
HAHA.BCBC

使用特权

评论回复
29
highgear|  楼主 | 2010-7-28 22:13 | 只看该作者
解释:
s = (z - 1)/T 是关键, 可以从 laplace 传递函数得出迭代公式。
matlab 里有命令 c2d 可做s到z转换: C2D(SYSC,Ts,METHOD),其中Ts是采样时间, 也就是 T, method 可以选择 'zoh' (Zero-order hold) 或'foh'(First-oder hold). 很多人会用这条命令, 但不知道其中转换的原理。

很简单, 最简单的积分器, 也就是欧拉公式:
   y(k+1) = y(k) + x(k) * T
得到 z 传递函数: f(z) = T/(z -1)
积分器的 s 传递函数为:f(s) = 1/s
所以: s = (z - 1)/T

使用特权

评论回复
30
highgear|  楼主 | 2010-7-28 22:26 | 只看该作者
当然, 也可以直接由微分得到: dy = (y(k+1) - y(k))/T = (z-1)/T = s
由 y(k+1) = y(k) + x(k) * T, 可以看出为什么叫 0阶保持的原因了吧。
因此, 可以想出1阶保持的积分,就是通俗术语“梯形积分“:
y(k+1) = y(k) + (x(k) + x(k-1)) * T /2

<全文结束>

使用特权

评论回复
31
程序匠人| | 2010-7-29 00:02 | 只看该作者
这个要加酷

使用特权

评论回复
32
宇宙飞船| | 2010-7-29 02:15 | 只看该作者
楼主什么时候再开讲微分(高通),带通滤波的课程?搬凳子坐着听课是一件令人很快乐的事情。
期待继续开新课。

使用特权

评论回复
33
英雄无敌六| | 2010-7-29 09:25 | 只看该作者
7张图片,不需要你学高深的数学,教你快速设计数字滤波器。
安装matlab,可以用电驴下载。
最后得到差分方程的系数,可以在MCU中直接使用。

匠人的MCU滤波,其实都是属于IIR/FIR的一种简化,不推荐。应该使用MATLAB设计。

IIR数字滤波器和FIR数字滤波器在区别:
IIR和输出、输入的数据都相关,所以阶数少,计算量小。但同时如果参数选择不当,容易振荡,用MATLAB设计可以避免。
FIR只和输入有关,等效平滑滤波、中值滤波什么的。想做到比较好的频率响应,阶数高很多。一般不建议在MCU中使用,除非只1-2阶。

7.JPG (28.71 KB )

7.JPG

1.JPG (54.67 KB )

1.JPG

2.JPG (54.93 KB )

2.JPG

3.JPG (22.18 KB )

3.JPG

4.JPG (25.55 KB )

4.JPG

5.JPG (13.02 KB )

5.JPG

6.JPG (36.75 KB )

6.JPG

使用特权

评论回复
34
论坛游客| | 2010-7-29 12:51 | 只看该作者
恩   matlab有专门的滤波器设计工具箱

使用特权

评论回复
35
yalingcat| | 2010-7-29 13:31 | 只看该作者
很好,支持一下

使用特权

评论回复
36
宇宙飞船| | 2010-7-29 13:50 | 只看该作者
PC机中MATLAB的滤波器算法中看不中用,跟在单片机中的工程实现相差十万八千里。

使用特权

评论回复
37
nbcskk| | 2010-7-29 14:30 | 只看该作者
好贴,mark一下。

使用特权

评论回复
38
xuyiyi| | 2010-7-29 16:27 | 只看该作者
路过!
帮highgear大师顶一把!

使用特权

评论回复
39
highgear|  楼主 | 2010-7-29 21:25 | 只看该作者
顶 英雄无敌六 提供的matlab 设计。谢谢程序匠人加裤子。

关于高通滤波器:   
(1) 可以同样使用上面所述的方法:通过微分方程和传递函数导出迭代公式。高通滤波器的传递函数书中和网上都有。
(2) 可以通过低通获得。低通输出y(k+1) 只是输入 x 的低频部分, 从输入x中除去低频部分, 剩下的自然就是高频部分: x(k+1) - y(k+1). 想想一个例子:一个正弦波叠加在一个直流上。


IIR数字滤波器和FIR数字滤波器最大的区别在于 迭代, 即:
    FIR: y(k+1) = A0*x(k) + A1*x(k-1) + A2*x(k-2) + ...
   IIR: y(k+1) = B0*y(k) + B1*y(k-1) + ... + A0*x(k) + A1*x(k-1) + A2*x(k-2) + ...

IIR 里包含了以前的输出, 实际上也就包括了以前所有的输入, 所以被称为无限冲击响应(Infinite Impulse Response). 由于迭代, 所以计算量相对较少。
FIR(Finite Impulse Response) 没有迭代, 依靠内核(kernal) Impulse Response 序列(就是说A0, A1, A2...是冲击响应序列) 通过卷积获得, 计算量相对较大。

使用特权

评论回复
40
jiamingz| | 2010-7-30 13:45 | 只看该作者
顶。。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则