IIR滤波在嵌入式系统中的C语言代码实现

相比于FIR滤波,IIR滤波可用较少的阶数得到很好的选频特性,在嵌入式系统中占用更少的内存,但其缺点在于相位特性是非线性的,而FIR滤波能够做到严格的线性相位。因此,根据实际情况进行选择合适的滤波方法,以达到更好的工作效果。

此文应用直接形式来实现IIR滤波,所依据的差分方程为:


注:N和M分别是滤波器分母和分子的阶数,之所以这里说分母和分子,是因为这个差分方程是由原来的分式方程导来的,原方程中的分子变成差分方程中的减数,分母变为被减数。如果是非自适应IIR滤波,则系数bj(k)和aj(k)为常数,即可替换为b和a;若为自适应IIR滤波,则此系数为变量。


本文实现的是两阶非自适应IIR滤波器(其他阶数参照即可):

1. 用matlab工具设计butterworth的IIR滤波器,步骤如下:

a. 输入fdatool命令,会弹出设计对话框;

b. 本文设计低通滤波器,则选择“Lowpass”,类型选择“Butterworth”,阶数设为2,采样频率Fs设为500Hz,截止频率Fc设为5Hz;

c. 最终目的是要导出所设计的滤波器的系数,即上文中的bj(k)和aj(k)。接下来点击“Analysis”->“Filter Coefficients”、“Edit”->“Convert to Single Section”,结果如下图:

d. 上图中“Filter Coefficients”下的内容就是所要的系数部分,“Numerator”表示分子(差分方程中的减数)的系数,“Denominator”表示分母(差分方程的被减数)的系数。

2. 将得到的两组系数分别放入数组中,C代码实现如下:

float lowpassed_NUM[3] = {0.0009446, 0.0018893, 0.0009446};

float lowpassed_DEN[3] = {1, -1.9111970, 0.9149758};

float LOWfilter_value_in[3] ={0};
float LOWfilter_value_out[3] ={0};
float FILTER_LOWPASSED
(float value)

{

LOWfilter_value_in[2] = LOWfilter_value_in
[1];
LOWfilter_value_in[1] = LOWfilter_value_in[0];
LOWfilter_value_in[0] = value;


        LOWfilter_value_out[0] = LOWfilter_value_out[1];
        LOWfilter_value_out[1] = LOWfilter_value_out[2];
LOWfilter_value_out[2] =  (lowpassed_NUM[0]*LOWfilter_value_in[0] + lowpassed_NUM[1]*LOWfilter_value_in[1] + lowpassed_NUM[2]*LOWfilter_value_in[2]- lowpassed_DEN[1]*LOWfilter_value_out[1] - lowpassed_DEN[2]*LOWfilter_value_out[0] )/lowpassed_DEN[0]  ;

return LOWfilter_value_out[2];
}


注:此函数的的输入参数是逐个输入数据的形式,返回的值就是滤波后所得到的值。高通和带通的实现方法类似,只是滤波系数不同。

你可能感兴趣的:(IIR滤波在嵌入式系统中的C语言代码实现)