IIR数字滤波器的实现(C语言)
- 经典滤波器和数字滤波器
一般滤波器可以分为经典滤波器和数字滤波器。
- 经典滤波器:假定输入信号中的有用成分和希望去除的成分各自占有不同的频带。如果信号和噪声的频谱相互重迭,经典滤波器无能为力。比如 FIR 和 IIR 滤波器等。
- 现代滤波器:从含有噪声的时间序列中估计出信号的某些特征或信号本身。现代滤波器将信号和噪声都视为随机信号。包括 Wiener Filter、Kalman Filter、线性预测器、自适应滤波器等
- Z变换和差分方程
在连续系统中采用拉普拉斯变换求解微分方程,并直接定义了传递函数,成为研究系统的基本工具。在采样系统中,连续变量变成了离散量,将Laplace变换用于离散量中,就得到了Z变换。和拉氏变换一样,Z变换可用来求解差分方程,定义Z传递函数成为分析研究采样系统的基本工具。
对于一般常用的信号序列,可以直接查表找出其Z变换。相应地,也可由信号序列的Z变换查出原信号序列,从而使求取信号序列的Z变换较为简便易行。
Z变换有许多重要的性质和定理:
- 线性定理
设a,a1,a2为任意常数,连续时间函数f(t),f1(t),f2(t)的Z变换分别为F(z),F1(z),F2(z),则有$$\mathbf{Z}[af(t)]=aF(z)$$ $$ \mathbf{Z}[a_1f_1(t)+a_2f_2(t)]=a_1F_1(z)+a_2F_2(z)$$
- 滞后定理
设连续时间函数在t<0时,f(t)=0,且f(t)的Z变换为F(z),则有$$\mathbf{Z}[f(t-kT)]=z^{-k}F(z)$$
应用Z变换求解差分方程的一个例子:已知系统的差分方程表达式为$y(n)-0.9y(n-1)=0.05u(n)$,若边界条件$y(-1)=1$,求系统的完全响应。
解:方程两端取z变换$$Y(z)-0.9[z^{-1}Y(z)+y(-1)]=0.05\frac{z}{z-1}\\Y(z)=\frac{0.05z^2}{(z-1)(z-0.9)}+\frac{0.9y(-1)z}{z-0.9}$$
可得$$\frac{Y(z)}{z}=\frac{A_1z}{z-1}+\frac{A_2z}{z-0.9}$$
其中A1=0.5,A2=0.45,于是$y(n)=0.5+0.45 \times(0.9)^n \quad(n\geq0)$
- IIR数字滤波器的差分方程和系统函数
IIR数字滤波器是一类递归型的线性时不变因果系统,其差分方程可以写为:$$y(n)=\sum_{i=0}^{M}a_ix(n-i)+\sum_{i=1}^{N}b_iy(n-i)$$
进行Z变换,可得:$$Y(z)=\sum_{i=0}^{M}a_iz^{-i}X(z)+\sum_{i=1}^{N}b_iz^{-i}Y(z)$$
于是得到IIR数字滤波器的系统函数:$$H(z)=\frac{Y(z)}{X(z)}=\frac{\sum_{i=0}^{M}a_iz^{-i}}{1-\sum_{i=1}^{N}b_iz^{-i}}=a_0\frac{\prod_{i=1}^{M}(1-c_iz^{-1})}{\prod_{i=1}^{N}(1-d_iz^{-1})}$$
其中ci为零点而di为极点。H(z)的设计就是要确定系数、或者零极点,以使滤波器满足给定的性能指标。
- IIR数字滤波器结构
数字滤波器的功能本质上是将一组输入数字序列通过一定的运算后转变为另一组输出数字序列。滤波器系统函数可以表达为多种不同的形式,每一种对应着不同的算法,也就对应着不同的实现结构。例如:$$H(z)=\frac{1}{1-0.3z^{-1}-0.4z^{-2}}$$
可以分解为:$$H(z)=\frac{1}{1-0.8z^{-1}}\cdot \frac{1}{1+0.5z^{-1}}$$
或$$H(z)=\frac{0.6154}{1-0.8z^{-1}}+\frac{0.3846}{1+0.5z^{-1}}$$
上述同一系统的三种不同描述形式就对应了不同的实现结构,或者说不同的滤波器结构可以实现相同的传递函数。IIR滤波器常见的结构形式有直接Ⅰ型、直接Ⅱ型(典范型)、级联型、并联型。通过差分方程能够画出包含反馈结构的数字网络称为直接型。
直接Ⅰ型滤波器的网络结构可以根据差分方程很直观地画出(The Direct-Form I structure implements the feed-forward terms first followed by the feedback terms):
可以看出直接Ⅰ型滤波器需要N+M个延时单元(N≥M)。直接Ⅱ型结构是对直接Ⅰ型的变型,将上面网络的零点与极点的级联次序互换,并将延时单元合并。实现N阶滤波器只需要N个延时单元(The Direct-Form II structure uses fewer delay blocks than Direct-Form I),故称为典范型。
直接Ⅱ型看上去不那么直观,可以通过下图进行理解。我们可以将整个滤波器系统看成A、B两个子系统串联而成,由于为线性系统因此交换顺序不影响最终输出结果,传递函数可写为:$$H(z)=B(z)\cdot \frac{1}{A(z)}=\frac{1}{A(z)}\cdot B(z)$$
直接型优点:直接型结构简单,用的延迟器较少(N和M中较大者的个数);缺点:系数ak,bk对滤波器性能的控制关系不直接,因此调整不方便;具体实现滤波器时ak,bk的量化误差将使滤波器的频率响应产生很大的改变,甚至影响系统的稳定性。直接型结构一般用于实现低阶系统。
MATLAB中二阶滤波器差分方程公式如下(注意反馈项符号为负号):$$y[n]=b_0 \cdot x[n]+b_1 \cdot x[n-1] + b_2 \cdot x[n-2] -a_1 \cdot y[n-1] -a_2 \cdot y[n-2]$$
高阶IIR滤波器的实现是采用二阶滤波器级联的方式来实现的。默认情况下,Filter Coefficients把结果分成多个2阶Section显示,其中还有增益。增益的目的是为了保证计算的精度和系统的稳定性。选择[edit]→[Convert to Single Section],这时候系数变成我们熟悉的形式:
按照上面的公式,滤波器差分方程为:y[n] = 0.06745527*x[n] + 0.134910547*x[n-1] + 0.06745527*x[n-2] -(-1.1429805025)*y[n-1] - (0.412801596)*y[n-2]
滤波器设计完成后还可以生成Simulink模型进行仿真:按照下图中数字标号进行,第一步点击左边Realize Model图标,第二步勾选“Build model using basic elements”这一项,右边四个灰色的项将自动打钩,最后点击“Realize Model”,matlab将自动生成滤波器模型,在弹出的窗口中双击模型可以观察该模型的内部结构。
下面是按照设计要求生成的2阶滤波器直接Ⅰ型的结构:
Direct-Form I
下面是直接Ⅱ型的内部结构:
Direct-Form II
使用生成的滤波器搭建一个简答的测试模型:将两个幅值为1,频率分别为10Hz、50Hz的正弦波叠加,输入滤波器后观察滤波前后的波形。仿真时间设为1s,仿真参数中求解器类型设为固定步长,求解器选择discrete(它适用于离散无连续状态的系统),步长设为0.005s(200Hz)
点击Run按钮开始进行仿真:
打开示波器结果如下图所示:上面一栏是不同频率叠加的波形,下面是10Hz正弦波和滤波后得到的波形的对比。由于50Hz正弦波频率高于滤波器截止频率20Hz,因此被滤除,同时滤波也产生了一定的滞后和失真。
知道了差分方程的形式并通过MATLAB得到滤波器系数后很容易写出相应的代码来实现数字滤波,另外还有一个网站能根据设计指标直接生成C代码:http://www-users.cs.york.ac.uk/~fisher/mkfilter/
根据前面的设计指标,在网页上填入相应参数后提交,会得到下面的C语言代码。简单修改后就可以使用:
#define NZEROS 2 #define NPOLES 2 #define GAIN 1.482463775e+01 static float xv[NZEROS+1], yv[NPOLES+1]; static void filterloop() { for (;;) { xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = next input value / GAIN; yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = (xv[0] + xv[2]) + 2 * xv[1] + ( -0.4128015981 * yv[0]) + ( 1.1429805025 * yv[1]); next output value = yv[2]; } }
在LabVIEW中为了自己实现IIR滤波器可以使用反馈结点来存储数据,下面的程序框图实现了与MATLAB模型相同的功能:
前面板波形图如下图所示:
参考:
Butterworth / Bessel / Chebyshev Filters
手把手教你用matlab生成STM32官方IIR滤波器的系数(二)
手把手教你用matlab生成STM32官方IIR滤波器的系数(三)
A Collection of Useful C++ Classes for Digital Signal Processing
IIR数字滤波器的实现(C语言)的更多相关文章
- FIR IIR数字滤波器特点简介
FIR:有限脉冲滤波器,线性较好,用非递归算法,可用FFT,计算速度快,不用四舍五入,适合于对相位敏感的线性应用场合,设计灵活没有现成公式可用. 输出与现在和过去的输入有关. IIR:无限脉冲滤波器, ...
- IIR数字滤波器
对于N阶IIR的计算方程式为: 一阶 Y(n)=a∗X(n)+(1−a)∗Y(n−1) 二阶 y[n]=b0⋅x[n]+b1⋅x[n−1]+b2⋅x[n−2]−a1⋅y[n−1]−a2⋅y[n−2]
- FIR滤波器与IIR滤波器
FIR(Finite Impulse Response)滤波器 有限长单位冲激响应滤波器,又称为非递归型滤波器 特点: FIR滤波器的最主要的特点是没有反馈回路,稳定性强,故不存在不稳定的问题: FI ...
- 基于FPGA的16阶级联型iir带通滤波器实现
警告 此文章将耗费你成吨的流量,请wifi下阅读,造成的流量浪费本人不承担任何责任.初版源代码获取(请勿用作他用,仅供学习):https://gitee.com/kingstacker/iir.git ...
- FIR滤波器和IIR滤波器的区别
数字滤波器广泛应用于硬件电路设计,在离散系统中尤为常见,一般可以分为FIR滤波器和IIR滤波器,那么他们有什么区别和联系呢. FIR滤波器 定义: FIR滤波器是有限长单位冲激响应滤波器,又称为非递归 ...
- FIR滤波器工作原理(算法)以及verilog算法实现(包含与IIR的一些对比)
滤波器在2017年IC前端的笔试中,出现频率十分的高.不论今后是否会涉及,还是要记住一些会比较好.接下来就将从这四个方面来讲解,FIR数字滤波器的工作原理(算法)与verilog实现. ·什么是FIR ...
- Matlab滤波器设计(转)
滤波器设计是一个创建满足指定滤波要求的滤波器参数的过程.滤波器的实现包括滤波器结构的选择和滤波器参数的计算.只有完成了滤波器的设计和实现,才能最终完成数据的滤波. 滤波器设计的目标是实现数据序列的频率 ...
- 半径无关单核单线程最快速高斯模糊实现(附完整C代码)
之前,俺也发过不少快速高斯模糊算法. 俺一般认为,只要处理一千六百万像素彩色图片,在2.2GHz的CPU上单核单线程超过1秒的算法,都是不快的. 之前发的几个算法,在俺2.2GHz的CPU上耗时都会超 ...
- FPGA与数字信号处理
过去十几年,通信与多媒体技术的快速发展极大地扩展了数字信号处理(DSP)的应用范围.眼下正在发生的是,以更高的速度和更低的成本实现越来越复杂的算法,这是针对高级信息服更高带宽以及增强的多媒体处理能力等 ...
随机推荐
- 【工具相关】Web-Sublime Text2-注释
按Command+/ 会出现<!----> 如图所示: 参考资料:<菜鸟教程>
- docker 安装jenkins
基于docker 进行安装 软件,首先需要有docker环境. 1.docker 下载 jenkins 镜像 指定版本 ,因为低版本的后面安装 软件会失败(亲测). docker pull jenki ...
- CentOS7 下源码安装 python3
CentOS 7 下源码安装 python3 在CentOS7下,默认安装的是python2.7:为满足项目要求,安装python3 的方法如下: 1. 首先安装python3.6可能使用的依 ...
- jpa 联表查询 返回自定义对象 hql语法 原生sql 语法 1.11.9版本
-----业务场景中经常涉及到联查,jpa的hql语法提供了内连接的查询方式(不支持复杂hql,比如left join ,right join). 上代码了 1.我们要联查房屋和房屋用户中间表,通过 ...
- JavaScript大杂烩10 - 理解DOM
操作DOM 终于到了JavaScript最为核心的部分了,通常来说,操作DOM,为页面提供更为友好的行为是JavaScript根本目标. DOM树 - HTML结构的抽象 既然DOM是操纵HTML ...
- MongoDB设置
添加mongodb用户组 groupadd mongodb 添加mongodb用户 useradd mongodb -g mongodb 将mongodb启动项目追加入rc.local保证mongod ...
- Oracle EBS FA 资产取值
SELECT fb.book_type_code, fth.ASSET_NUMBER, fdh.units_assigned, fdh.assigned_to, pf.FULL_NAME, fl.se ...
- REPLACE函数的使用方法
Replace函数的含义~ 用新字符串替换旧字符串,而且替换的位置和数量都是指定的. replace函数的语法格式 =Replace(old_text,start_num,num_chars,new_ ...
- python第四十三天--第三模块考核
面向对象: 概念:类,实例化,对象,实例 属性: 公有属性:在类中定义 成员属性:在方法中定义 私有属性:在方法中使用 __属性 定义 限制外部访问 方法: 普通方法 类方法: @classmeth ...
- plsql备份表---只是表---不包含表数据
写这个的同时还在备份,表的数据进度很慢,数据太大了. 用的工具是plsql 导出表:点击 tool工具 ---> export user object 导出用户目标 ----> ...