一阶IIR滤波器的C语言设计和优化

原创 2018年04月17日 14:19:08

对于N阶IIR的计算方程式为:


其中N表示滤波器的级数,当N=1的时候,其方程可以展开为如下所示:


本文的研究对象就是这个一阶方程,其中y为输出数据,x为输入数据,a和b为滤波器的系数。

x[n]为本次要滤波的输入数据,x[n-1]为上一次滤波前的输入数据,y[n-1]为上一次滤波器输出的数据。

设计这个滤波器,主要就是设计其中的系数a和b。

######################################

几乎网上的所有资料都是叫你使用matlab中的fdtool来设计参数,其实如果只是计算滤波参数,

完全不用安装matlab这个几百兆的大家伙,可以使用下面介绍的小工具完成任务:

1.直接在线计算:http://www-users.cs.york.ac.uk/~fisher/mkfilter

2.下载专用小软件ScopeIIR,官方网站:http://iowegian.com/scopeiir

3.下载专用小软件FiWiz,官方网站:http://www1.icsi.berkeley.edu/~storn/fiwiz.html

4.下载专用小软件Iowa Hill,官方网站:http://iowahills.com/8DownloadPage.html

#####################################

无论使用哪种方式计算参数,都要输入采样率,滤波器类型,滤波级数,截止频率等参数。

最后都会得到A0,A1,A2,B0,B1,B2这样的滤波器系数,直接代入到公式中计算就可以了。

默认情况下,公式中的数据用代码都是采用浮点数float或者double来计算,这样可以提高精度,
但是大量的浮点乘法计算量比较大,特别是对于主频不高的单片机而言就更为吃力;
所以我们希望可以使用定点整数以减少计算量,甚至希望用移位器和加法器来代替乘法。

下面就举一个实例来研究如何减少计算量:

我们要设计一个采样率为1000,截止频率为100,滤波器类型为Butterworth,阶数为1的IIR低通滤波器,
通过计算得到如下参数:

B[0]=+1.000000
B[1]=+1.000000
A[1]=-0.509525

(细心的人可能会发现高通滤波器和低通滤波器的区别只有B[1]这个参数,一个为+1.00,一个为-1.00)

代入公式得到:y[n]=x[n]+x[n-1]+0.509525*y[n-1]

我们优化的重点就是这个0.50952*y[n-1],利用移位法来代替小数乘法,
原理就是把小数分解为1/M[0]+1/M[1]+...的方式,其中M[n]必须为2的整数次幂,
分解的次数越多,分母越大,误差就越小,可以根据实际情况需要选择分解的精度。

分解过程:

0.509525 * 1024 = 521(注:需要更高精度,可以把1024改为2048,4096,8192.......)

=521/1024

=(512+8+1)/1024

=512/1024+8/1024+1/1024

=1/2+1/8+1/1024

所以这个公式可以改写为:y[n]=x[n]+x[n-1]+y[n-1]/2+y[n-1]/8+y[n-1]/1024

最后附上C语言代码:

/*************************************************************************************************
* 输入待滤波的数据,返回滤波后的数据
* 由于输入输出都是整型数据,为了防止数据溢出或数据太小,可以将输入数据先左/右移N位,最后返回时再右/左移N位
**************************************************************************************************/
int iir_filter(int x1)
{
    static int x0;
    static int y0;
    int y1;
    y1 = x1 + x0 + (y0>>1) + (y0>>3) + (y0>>10);
    x0 = x1;
    y0 = y1;
    return y1;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq446252221/article/details/79973441

butterworth级联iir低通滤波器c语言实现

  • 2015年12月31日 08:49
  • 18KB
  • 下载

IIR滤波器的C实现

第一步: 点击菜单中的Edit->Convert Structure 选择Direct Form I ,SOS,(必须是Direct Form I,  II不行) 一般情况下,按照默认设置,fda...
  • wangkeyen
  • wangkeyen
  • 2016-03-25 11:26:00
  • 1295

单片机中(C语言)IIR滤波器的实现

IIR是无限长单位脉冲响应数字滤波器,其系统对应函数有如下形式: 在知道滤波器相应的系数b[],a[]后可根据相应的差分方程,完成对数据的滤波,而滤波器的系数可以通过Matlab滤波器设计和分析...
  • qq_21905401
  • qq_21905401
  • 2016-12-27 12:51:22
  • 2963

IIR数字滤波器实现(mantlab+C语言)

题目:16k采样率音频数据下采样到8k采样率 求解方案分析:直接每隔一个取一个采样值,这样就可以得到8k采样率的数据。但是这样明显会有问题。按照采样率变换理论,首先应该通过一个低通滤波器,滤掉[...
  • cenzmin
  • cenzmin
  • 2015-03-04 13:17:07
  • 1466

[数字信号处理]IIR滤波器的间接设计(C代码)

1.模拟滤波器的设计       1.1巴特沃斯滤波器的次数         根据给定的参数设计模拟滤波器,然后进行变数变换,求取数字滤波器的方法,称为滤波器的间接设计。做为数字滤波器的设计基础的...
  • u010258235
  • u010258235
  • 2014-02-11 10:32:15
  • 697

IIR数字滤波器实现(mantlab+C语言) fdatool

IIR数字滤波器实现(mantlab+C语言) http://blog.csdn.net/syrchina/article/details/9053047
  • gtkknd
  • gtkknd
  • 2015-03-27 17:33:17
  • 1593

用Matlab的FDAtool生成IIR滤波器参数以及参数生成C 语言文件

  • 2015年04月28日 10:39
  • 366KB
  • 下载

c语言实现iir滤波器

  • 2009年05月05日 16:27
  • 178KB
  • 下载

IIR 滤波器的实现(C++)

IIR 滤波器的实现(C++) 最近在写的一个程序需要用到IIR滤波器,而且IIR滤波器的系数需要动态调整。因此就花了点时间研究IIR 滤波器的实现。 以前用到的IIR滤波器的参数都是事先确定好的...
  • liyuanbhu
  • liyuanbhu
  • 2014-08-26 16:46:32
  • 18491

IIR滤波器设计——个人感悟

查过很多资料,对于IIR滤波器结构和原理介绍很多,但是,真正对于FPGA的快速设计介绍很少。我对IIR滤波器的MATLAB仿真和FPGA硬件仿真做了充分的对比,关于IIR滤波器设计和实现做一下总结: ...
  • u924512005
  • u924512005
  • 2017-05-02 20:10:15
  • 2555
收藏助手
不良信息举报
您举报文章:一阶IIR滤波器的C语言设计和优化
举报原因:
原因补充:

(最多只允许输入30个字)