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];
}

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

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的基于IIR滤波器的C语言实现: ```c #define N 3 //IIR滤波器的阶数 float a[N+1] = {1.0, -1.9, 0.95, -0.9025}; //IIR滤波器的反馈系数 float b[N+1] = {0.0483, 0.1449, 0.1449, 0.0483}; //IIR滤波器的前馈系数 float x[N+1] = {0.0}; //输入信号的缓冲区 float y[N+1] = {0.0}; //输出信号的缓冲区 void iir(float input, float *output) { int i; //将当前输入值存储到缓冲区的第一个位置 x[0] = input; y[0] = 0.0; //计算输出值 for (i = 0; i <= N; i++) { y[0] += b[i] * x[i]; } for (i = 1; i <= N; i++) { y[0] -= a[i] * y[i]; } //将缓冲区的值向后移动 for (i = N; i > 0; i--) { x[i] = x[i - 1]; y[i] = y[i - 1]; } //将输出值保存到输出指针所指向的位置 *output = y[0]; } ``` 这个代码,我们假设IIR滤波器的阶数为3,反馈系数存储在a数组,前馈系数存储在b数组。输入信号存储在x数组,输出信号存储在y数组。每次新的输入值存储在x[0]。输出信号保存在y[0]变量,并且向后移动缓冲区的值,以便下一次的运算。 我们可以在程序调用iir函数,传递输入值和输出指针作为参数。下面是一个示例: ```c int main() { float input = 1.0; float output; iir(input, &output); return 0; } ``` 这个示例,我们假设输入信号为1.0。我们调用iir函数,并将输出指针传递给它。当函数返回时,输出指针所指向的位置将保存输出信号的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值