当前位置:   article > 正文

IIR数字滤波器原理,设计方法及嵌入式应用

iir

目录

一、IIR数字滤波器原理

二、MATLAB/simulink设计方法及示例代码

三、基于stm32的嵌入式应用及代码


一、IIR数字滤波器原理

IIR(Infinite-duration Impulse Responses) 即无限长脉冲响应滤波器。

以设计IIR巴特沃斯低通滤波器为例,其离散形式为

其直接II型结构为:

二、MATLAB/simulink设计方法及示例代码

设计步骤:

Step1:对原时域信号进行傅里叶变换,得到原信号的频谱图;

举例:原信号是基波频率为10Hz、干扰信号为100Hz、300Hz的混合信号

  1. clear all;
  2. close all;
  3. fs = 1000; %采样频率 1KHz
  4. T = 1;%时间宽度,可以理解为采样时间长度
  5. ts = 1/fs;%数据之间采样间隔
  6. N = T*fs;%采样点数T/ts
  7. t = (0:N-1)*ts;
  8. %基波:幅值为3的1Hz正弦波
  9. Signal_Original_1 = 3*sin(20*pi*t);
  10. %噪声函数 赋值为基波的1/3 100hz 300hz 正弦波
  11. Noise_White_1 = sin(2*pi*100*t)+sin(2*pi*300*t);
  12. %构造的混合信号
  13. Mix_Signal = Signal_Original_1 + Noise_White_1;
  14. figure(1);
  15. subplot(211);
  16. plot(t,Mix_Signal);
  17. xlabel('时间t(s)');
  18. title('带噪声信号');
  19. %快速傅里叶变换
  20. Y = fft(Mix_Signal);
  21. P2 = abs(Y/N);
  22. % 计算双侧频谱 P2
  23. P1 = P2(1:N/2+1);
  24. % 将P2的前半段信号赋给P1,P1即是我们关心的部分
  25. P1(2:end-1) = 2*P1(2:end-1);
  26. %计算每个信号的双侧频谱和单侧频谱。
  27. f = fs*(0:(N/2))/N;%采样频率fs,因此只看fs/2内的信号
  28. subplot(212);
  29. plot(f,P1,'r');
  30. title('带噪声信号');
  31. xlabel('频率f(Hz)');
  32. ylabel('|P1(f)|');

Step2:选择需要保留的频率,设计满足需求的滤波器;

根据上述示例,需要保存的频率为10Hz,选用低通滤波器,以IIR巴特沃斯低通滤波器为例,可选取截止频率为30Hz。通过代码确认满足需求的滤波器阶次。

其中,通带波纹:是指在滤波器的频响中通带的最大幅值和最小幅值的差,正常的滤波器一般通带纹波小于1db,不过也视情况而定,通带纹波会导致通带内的信号幅值大小有变化,对一些要求高的系统,纹波越小越好。通带纹波和滤波器的阶数有关系,阶数越大纹波越小。

阻带衰减:滤波器有部分频率是通,部分是阻。但是阻的部分,未必能够全部阻隔,而只有部分衰减,部分留下来,因此最小衰减就可以描述它阻碍该阻碍的波段的能力的高低(理想状态是100%衰减),最小衰减越大,则能力越好。

  1. %IIR滤波器设计
  2. NN=0; % 阶数
  3. Fp=5; % 通带截止频率5Hz
  4. Fc=40; % 阻带截止频率30Hz
  5. Rp=1; % 通带波纹最大衰减为1dB,最好情况为1dB
  6. Rs=30; % 阻带衰减为30dB,截止频率的10倍频程时,衰减30dB,数值越大阻止能力越强。
  7. %计算最小滤波器阶数
  8. na=sqrt(10^(0.1*Rp)-1);
  9. ea=sqrt(10^(0.1*Rs)-1);
  10. NN=ceil(log10(ea/na)/log10(Fc/Fp));

Step3:使用fdatool(filterDesigner)工具箱,按照需求进行选择;

--->在MATLAB命令窗口输入 fdatool(或filterDesigner);

--->打开滤波器设计工具箱,设计选择低通,巴特沃斯 2阶 采样频率fs=1000,截止频率fc=50后,点击设计滤波器,选择[b,a]图标即可查看参数,但需要通过“编辑”选项,选择“转换为单节”,才能得到普遍意义上的滤波器系数,如图所示。

Step4:验证数字滤波器性能;

为验证滤波器设计是否达到效果,需要进行滤波验证。

首先,生成simulink单元模型--->选择,选择使用基本元素构建模型,点击实现模型。

以此得到滤波器系数b,a,在MATLAB中形成代码如下:

  1. a2=-1.734725714;
  2. a3=0.7660065889;
  3. b1=0.007820207626;
  4. b2=0.01564041525;
  5. b3=0.007820207626;
  6. delay0=0;
  7. delay1=0;
  8. delay2=0;
  9. for i = 1:N
  10. delay0 = Mix_Signal(i)-a2*delay1-a3*delay2;
  11. output(i) = b1*delay0+b2*delay1+b3*delay2;
  12. delay2=delay1;
  13. delay1=delay0;
  14. end
  15. hold on;
  16. figure(2);
  17. subplot(211);
  18. plot(t,output);
  19. xlabel('时间t(s)');
  20. title('滤波后信号');
  21. %快速傅里叶变换
  22. OY = fft(output);
  23. P21 = abs(OY/N);
  24. % 计算双侧频谱 P2
  25. P11 = P21(1:N/2+1);
  26. % 将P2的前半段信号赋给P1,P1即是我们关心的部分
  27. P11(2:end-1) = 2*P11(2:end-1);
  28. %计算每个信号的双侧频谱和单侧频谱。
  29. f = fs*(0:(N/2))/N;%采样频率fs,因此只看fs/2内的信号
  30. subplot(212);
  31. plot(f,P11,'');
  32. title('滤波后信号');
  33. xlabel('频率f(Hz)');
  34. ylabel('|P11(f)|');

对比原信号和滤波后信号:

  1. figure(3);
  2. plot(t,[s0;output]);
  3. legend('原信号','IIR滤波后信号');
  4. xlabel('时间t(s)');
  5. title('信号');

结果分析:截止频率选择30Hz时,幅值上没有衰减,相位上存在一定滞后。也说明数字滤波器在采样后与模拟滤波器存在一定差异。

三、基于stm32的嵌入式应用及代码

为了应用于stm32,需要重复目录二。

import通过jscope或采集系统得到的时域数据,设置采样频率与上述设备一致,设置一周期以上时宽后,进行傅里叶变换(fft),确定截止频率fc,从而设计滤波器,通过滤波器工具箱得到滤波系数。

点击目标,生成C头文件,选择导出类型为单精度即可满足stm32需求。

生成C头文件后,用VSCode打开,得到滤波器系数如下:

  1. const int NL = 3;
  2. const real32_T NUM[3] = {
  3. 0.007820207626, 0.01564041525, 0.007820207626
  4. };
  5. const int DL = 3;
  6. const real32_T DEN[3] = {
  7. 1, -1.734725714, 0.7660065889
  8. };

在stm32中实现对应程序如下:

  1. static float NUM[3]={0.007820207626, 0.01564041525, 0.007820207626};
  2. static float DEN[3]={1,-1.734725714,0.7660065889};
  3. //子函数
  4. float IIR_LPF_FILTER(float input,float* NUM,float* DEN)
  5. {
  6. float output;
  7. static float delay[3]={0};
  8. delay[0] = input - DEN[1]*delay[1]-DEN[2]*delay[2];
  9. output = NUM[0]*delay[0]+NUM[1]*delay[1]+NUM[2]*delay[2];
  10. delay[2]=delay[1];
  11. delay[1]=delay[0];
  12. return output;
  13. }
  14. //主函数调用
  15. void main()
  16. {
  17. float input;
  18. input = sdp();
  19. IIR_LPF_FILTER(input,NUM,DEN);
  20. }

至此,即完成了基于STM32的二阶直接II型巴特沃斯低通滤波器。

参考:

https://zhuanlan.zhihu.com/p/357619650

一文看懂MATLAB 滤波器设计(IIR滤波器、FIR滤波器)及单片机实现 - 知乎 (zhihu.com)

MATLAB中FFT的用法 - 知乎 (zhihu.com)

通带纹波、阻带纹波、通带最大波纹和阻带最小衰减-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/579800
推荐阅读
相关标签
  

闽ICP备14008679号