你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【原创】【安富莱——DSP教程】第40章 IIR滤波器的实现

[复制链接]
baiyongbin2009 发布时间:2015-4-28 10:04
特别说明:完整45期数字信号处理教程,原创高性能示波器代码全开源地址:链接

第40章 IIR滤波器的实现

    本章节讲解IIR滤波器直接I型的低通,高通,带通和带阻滤波器的实现。
    40.1 IIR滤波器介绍
    40.2 Matlab工具箱fdatool生成IIR滤波器系数
    40.3 IIR低通滤波器设计
    40.4 IIR高通滤波器设计
    40.5 IIR带通滤波器设计
    40.6 IIR带阻滤波器设计
    40.7 总结

40.1 IIR滤波器介绍
    ARM官方提供的直接I型IIR库支持Q7,Q15,Q31和浮点四种数据类型。其中Q15和Q31提供了基于Cortex-M3和Cortex-M4的快速版本。
    直接I型IIR滤波器是基于二阶Biquad级联的方式来实现的。每个Biquad由一个二阶的滤波器组成:
y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
    直接I型算法每个阶段需要5个系数和4个状态变量。
40.1.png
    这里有一点要特别的注意,有些滤波器系数生成工具是采用的下面公式实现:
y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a2 * y[n-2]
    比如matlab就是使用上面的公式实现的,所以在使用fdatool工具箱生成的a系数需要取反才能用于直接I型IIR滤波器的函数中。
    高阶IIR滤波器的实现是采用二阶Biquad级联的方式来实现的。其中参数numStages就是用来做指定二阶Biquad的个数。比如8阶IIR滤波器就可以采用numStages=4个二阶Biquad来实现。
40.2.png
如果要实现9阶IIR滤波器就需要将numStages=5,这时就需要其中一个Biquad配置成一阶滤波器(也就是b2=0,a2=0)。


收藏 1 评论9 发布时间:2015-4-28 10:04

举报

9个回答
baiyongbin2009 回答时间:2015-4-28 10:13:21
40.2 Matlab工具箱fdatool生成IIR滤波器系数
    前面介绍FIR滤波器的时候,我们讲解了如何使用fdatool生成C头文件,从而获得滤波器系数。这里不能再使用这种方法了,主要是因为通过C头文件获取的滤波器系数需要通过ARM官方的IIR函数调用多次才能获得滤波结果,所以我们这里换另外一种方法。
    下面我们讲解如何通过fdatool工具箱生成滤波器系数。首先在matlab的命令窗口输入fdatool就能打开这个工具箱:
40.3.png
fdatool界面打开效果如下:
40.4.png
IIR滤波器的低通,高通,带通,带阻滤波的设置会在下面一一讲解,这里说一下设置后相应参数后如何生成滤波器系数。参数设置好以后点击如下按钮:
40.5.png
点击Design Filter之后,注意左上角生成的滤波器结构:
40.6.png
默认生成的IIR滤波器类型是Direct-Form II, Second-Order Sections(直接II型,每个Section是一个二阶滤波器)。这里我们需要将其转换成Direct-Form I, Second-Order Sections,因为本章使用的IIR滤波器函数是Direct-Form I的结构。
    转换方法,点击Edit->Convert Structure,界面如下,这里我们选择第一项,并点击OK:
40.7.png
转换好以后再点击File-Export,第一项选择Coefficient File(ASCII):
40.8.png
第一项选择好以后,第二项选择Decimal:
40.9.png
两个选项都选择好以后,点击Export进行导出,导出后保存即可:
40.10.png
保存后Matlab会自动打开untitled.fcf文件,可以看到生成的系数:
  1. %
  2. % Generated by MATLAB(R) 7.14 and the Signal Processing Toolbox 6.17.
  3. %
  4. % Generated on: 30-Dec-2014 21:08:50
  5. %

  6. % Coefficient Format: Decimal

  7. % Discrete-Time IIR Filter (real)                           
  8. % -------------------------------                           
  9. % Filter Structure    : Direct-Form II, Second-Order Sections
  10. % Number of Sections  : 2                                    
  11. % Stable              : Yes                                 
  12. % Linear Phase        : No                                   

  13.                                                             
  14. SOS Matrix:                                                  
  15. 1  2  1  1  -1.1130298541633479   0.57406191508395477        
  16. 1  2  1  1  -0.85539793277517018  0.20971535775655475        
  17.                                                             
  18. Scale Values:                                                
  19. 0.11525801523015171                                          
  20. 0.08857935624534613
复制代码
由于咱们前面选择的是4阶IIR滤波,生成的结果就是由两组二阶IIR滤波系数组成,系数的对应顺序如下:
  1. SOS Matrix:                                                  
  2. 1   2   1   1   -1.1130298541633479   0.57406191508395477        
  3. b0  b1  b2  a0        a1                      a2
  4. 1 2   1   1   -0.85539793277517018  0.20971535775655475        
  5. b0  b1  b2  a0        a1                      a2
复制代码
注意,实际使用ARM官方的IIR函数调用的时候要将a1和a2取反。另外下面两组是每个二阶滤波器的增益,滤波后的结果要乘以这两个增益数值才是实际结果:
  1. 0.11525801523015171                                          
  2. 0.08857935624534613
复制代码
实际的滤波系数调用方法,看下面的例子即可。

stary666 回答时间:2015-4-28 10:20:58
沙发,支持原创
baiyongbin2009 回答时间:2015-4-28 10:21:58
40.3 IIR低通滤波器设计
    本章使用的IIR滤波器函数是arm_biquad_cascade_df1_f32。下面使用此函数设计IIR低通,高通,带通和带阻滤波器。
40.3.1 函数arm_biquad_cascade_df1_f32说明
函数定义如下:
    void arm_biquad_cascade_df1_f32(
            const arm_biquad_casd_df1_inst_f32 * S,
            float32_t * pSrc,
            float32_t * pDst,
           uint32_t blockSize)
参数定义:
       [in]  *S         points to an instance of the floating-point Biquad cascade structure.   
       [in]  *pSrc      points to the block of input data.   
      [out] *pDst      points to the block of output data.   
      [in]  blockSize  number of samples to process per call.   
      return     none.   
注意事项:
结构arm_fir_instance_f32的定义如下(在文件arm_math.h文件):
      typedef struct
      {
      /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
      uint32_t numStages;   
       /**< Points to the array of state coefficients. The array is of length 4*numStages. */
      float32_t *pState;
      /**< Points to the array of coefficients.  The array is of length 5*numStages. */
          float32_t *pCoeffs;
      } arm_biquad_casd_df1_inst_f32;
特别注意,参数pState指向的数组大小要是4倍的numStages,pCoeffs指向的数组大小要是5倍的numStages。
1. 参数pCoeffs指向滤波因数,滤波因数数组长度为numTaps。但要注意pCoeffs指向的滤波因数应该按照如下的顺序进行排列:
       {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
    先放第一个二阶Biquad系数,然后放第二个,以此类推。
2. pState指向状态变量数组。
3. blockSize 这个参数的大小没有特殊要求,用户只需保证大于1且小于等于采样点个数即可。

40.3.2 fdatool获取低通滤波器系数
    设计一个如下的例子:
    信号由50Hz正弦波和200Hz正弦波组成,采样率1Kbps,现设计一个巴特沃斯滤波器低通滤波器,采用直接I型,截止频率80Hz,采样400个数据,滤波器阶数设置为4。fadtool的配置如下:
40.11.png
配置好低通滤波器后,具体滤波器系数的生成大家参考本章第二小节的方法即可。

40.3.3 低通滤波器实现
    通过工具箱fdatool获得低通滤波器系数后在开发板上运行函数arm_biquad_cascade_df1_f32来测试低通滤波器的效果。
  1. #define numStages  2                /* 2阶IIR滤波的个数 */
  2. #define TEST_LENGTH_SAMPLES  400    /* 采样点数 */

  3. static float32_t testInput_f32_50Hz_200Hz[TEST_LENGTH_SAMPLES]; /* 采样点 */
  4. static float32_t testOutput[TEST_LENGTH_SAMPLES];               /* 滤波后的输出 */
  5. static float32_t IIRStateF32[4*numStages];                      /* 状态缓存,大小numTaps + blockSize - 1*/
  6.                                                                              
  7. /* 巴特沃斯低通滤波器系数 80Hz*/                                                                                                                                         
  8. const float32_t IIRCoeffs32LP[5*numStages] = {
  9. 1.0f,  2.0f,  1.0f, 1.4797988943972167f,  -0.68867695305386178f,        
  10. 1.0f,  2.0f,  1.0f, 1.2128120926202184f,  -0.38400416228655354f                          
  11. };
  12. /*
  13. *********************************************************************************************************
  14. *        函 数 名: arm_iir_f32_lp
  15. *        功能说明: 调用函数arm_iir_f32_lp实现低通滤波器
  16. *        形    参:无
  17. *        返 回 值: 无
  18. *********************************************************************************************************
  19. */
  20. static void arm_iir_f32_lp(void)
  21. {
  22. uint32_t i;
  23. arm_biquad_casd_df1_inst_f32 S;
  24. float32_t ScaleValue;

  25. /* 初始化 */
  26. arm_biquad_cascade_df1_init_f32(&S, numStages, (float32_t *)&IIRCoeffs32LP[0], (float32_t
  27. *)&IIRStateF32[0]);
  28. /* IIR滤波 */
  29.         arm_biquad_cascade_df1_f32(&S, testInput_f32_50Hz_200Hz, testOutput, TEST_LENGTH_SAMPLES);
  30. /*放缩系数 */
  31. ScaleValue = 0.052219514664161221f * 0.04279801741658381f
  32. /* 打印滤波后结果 */
  33. for(i=0; i<TEST_LENGTH_SAMPLES; i++)
  34. {
  35. printf("%f\r\n", testOutput[i]*ScaleValue);
  36. }
  37. }
复制代码
运行如上函数可以通过串口打印出函数arm_biquad_cascade_df1_f32滤波后的波形数据,下面通过Matlab绘制波形来对比Matlab计算的结果和ARM官方库计算的结果。
    对比前需要先将串口打印出的一组数据加载到Matlab中, arm_biquad_cascade_df1_f32的计算结果起名sampledata,加载方法在前面的教程中已经讲解过,这里不做赘述了。Matlab中运行的代码如下:
  1. fs=1000;              %设置采样频率 1K
  2. N=400;               %采样点数      
  3. n=0:N-1;
  4. t=n/fs;                %时间序列
  5. f=n*fs/N;              %频率序列

  6. x1=sin(2*pi*50*t);
  7. x2=sin(2*pi*200*t);     %50Hz和200Hz正弦波
  8. subplot(211);
  9. plot(t, x1);
  10. title('滤波后的理想波形');
  11. grid on;

  12. subplot(212);
  13. plot(t, sampledata);
  14. title('ARM官方库滤波后的波形');
  15. grid on;
复制代码
Matlab计算结果如下:
40.12.png
从上面的波形对比来看,matlab和函数arm_biquad_cascade_df1_f32计算的结果基本是一致的。为了更好的说明滤波效果,下面从频域的角度来说明这个问题,Matlab上面运行如下代码:
  1. fs=1000;                %设置采样频率 1K
  2. N=400;                 %采样点数      
  3. n=0:N-1;
  4. t=n/fs;                  %时间序列
  5. f=n*fs/N;                %频率序列

  6. x = sin(2*pi*50*t) + sin(2*pi*200*t);      %50Hz和200Hz正弦波合成
  7.   
  8. subplot(211);
  9. y=fft(x, N);                %对信号x做FFT   
  10. plot(f,abs(y));
  11. xlabel('频率/Hz');
  12. ylabel('振幅');
  13. title('原始信号FFT');
  14. grid on;

  15. y3=fft(sampledata, N);    %经过IIR滤波器后得到的信号做FFT
  16. subplot(212);                              
  17. plot(f,abs(y3));
  18. xlabel('频率/Hz');
  19. ylabel('振幅');
  20. title('IIR滤波后信号FFT');
  21. grid on;
复制代码
Matlab计算结果如下:
40.13.png
上面波形变换前的FFT和变换后FFT可以看出,200Hz的正弦波基本被滤除。

baiyongbin2009 回答时间:2015-4-28 10:27:34
40.4 IIR高通滤波器设计
40.4.1 fdatool获取高通滤波器系数
    设计一个如下的例子:
    信号由50Hz正弦波和200Hz正弦波组成,采样率1Kbps,现设计一个巴特沃斯滤波器高通滤波器,采用直接I型,截止频率140Hz,采样400个数据,滤波器阶数设置为4。fadtool的配置如下:
40.14.png
配置好高通滤波器后,具体滤波器系数的生成大家参考本章第二小节的方法即可。

40.4.2 高通滤波器实现
    通过工具箱fdatool获得高通滤波器系数后在开发板上运行函数arm_biquad_cascade_df1_f32来测试高通滤波器的效果。
  1. #define numStages  2                /* 2阶IIR滤波的个数 */
  2. #define TEST_LENGTH_SAMPLES  400    /* 采样点数 */

  3. static float32_t testInput_f32_50Hz_200Hz[TEST_LENGTH_SAMPLES]; /* 采样点 */
  4. static float32_t testOutput[TEST_LENGTH_SAMPLES];               /* 滤波后的输出 */
  5. static float32_t IIRStateF32[4*numStages];                      /* 状态缓存,大小numTaps + blockSize - 1*/
  6.                                                                              
  7. /* 巴特沃斯高通滤波器系数 140Hz */                                                                                                                                         
  8. const float32_t IIRCoeffs32HP[5*numStages] = {
  9. 1.0f,  -2.0f,  1.0f,  0.9845430147411518f,   -0.54456536085081642f,      
  10. 1.0f,  -2.0f,  1.0f,  0.74471447786432121f,  -0.16831887384397309f,                                
  11. };

  12. /*
  13. *********************************************************************************************************
  14. *        函 数 名: arm_iir_f32_hp
  15. *        功能说明: 调用函数arm_iir_f32_hp实现高通滤波器
  16. *        形    参:无
  17. *        返 回 值: 无
  18. *********************************************************************************************************
  19. */
  20. static void arm_iir_f32_hp(void)
  21. {
  22. uint32_t i;
  23. arm_biquad_casd_df1_inst_f32 S;
  24. float32_t ScaleValue;

  25. /* 初始化 */
  26. arm_biquad_cascade_df1_init_f32(&S, numStages, (float32_t *)&IIRCoeffs32HP[0], (float32_t
  27. *)&IIRStateF32[0]);
  28. /* IIR滤波 */
  29.         arm_biquad_cascade_df1_f32(&S, testInput_f32_50Hz_200Hz, testOutput, TEST_LENGTH_SAMPLES);
  30.    
  31. /*放缩系数 */   
  32. ScaleValue = 0.63227709389799203f * 0.47825833792707356f;  
  33. /* 打印滤波后结果 */
  34. for(i=0; i<TEST_LENGTH_SAMPLES; i++)
  35. {
  36. printf("%f\r\n", testOutput[i]*ScaleValue);
  37. }
  38. }
复制代码
运行如上函数可以通过串口打印出函数arm_biquad_cascade_df1_f32滤波后的波形数据,下面通过Matlab绘制波形来对比Matlab计算的结果和ARM官方库计算的结果。
    对比前需要先将串口打印出的一组数据加载到Matlab中, arm_biquad_cascade_df1_f32的计算结果起名sampledata,加载方法在前面的教程中已经讲解过,这里不做赘述了。Matlab中运行的代码如下:
  1. fs=1000;              %设置采样频率 1K
  2. N=400;               %采样点数      
  3. n=0:N-1;
  4. t=n/fs;                %时间序列
  5. f=n*fs/N;              %频率序列

  6. x1=sin(2*pi*50*t);
  7. x2=sin(2*pi*200*t);     %50Hz和200Hz正弦波
  8. subplot(211);
  9. plot(t, x2);
  10. title('滤波后的理想波形');
  11. grid on;

  12. subplot(212);
  13. plot(t, sampledata);
  14. title('ARM官方库滤波后的波形');
  15. grid on;
复制代码
Matlab计算结果如下:
40.15.png
从上面的波形对比来看,matlab和函数arm_biquad_cascade_df1_f32计算的结果基本是一致的。为了更好的说明滤波效果,下面从频域的角度来说明这个问题,Matlab上面运行如下代码:
  1. fs=1000;                %设置采样频率 1K
  2. N=400;                 %采样点数      
  3. n=0:N-1;
  4. t=n/fs;                  %时间序列
  5. f=n*fs/N;                %频率序列

  6. x = sin(2*pi*50*t) + sin(2*pi*200*t);      %50Hz和200Hz正弦波合成
  7.   
  8. subplot(211);
  9. y=fft(x, N);                %对信号x做FFT   
  10. plot(f,abs(y));
  11. xlabel('频率/Hz');
  12. ylabel('振幅');
  13. title('原始信号FFT');
  14. grid on;

  15. y3=fft(sampledata, N);    %经过IIR滤波器后得到的信号做FFT
  16. subplot(212);                              
  17. plot(f,abs(y3));
  18. xlabel('频率/Hz');
  19. ylabel('振幅');
  20. title('IIR滤波后信号FFT');
  21. grid on;
复制代码
Matlab计算结果如下:
40.16.png
上面波形变换前的FFT和变换后FFT可以看出,50Hz的正弦波基本被滤除。

baiyongbin2009 回答时间:2015-4-28 10:32:14
40.5 IIR带通滤波器设计
40.5.1 fdatool获取低通滤波器系数
    设计一个如下的例子:
    信号由50Hz正弦波和200Hz正弦波组成,采样率1Kbps,现设计一个巴特沃斯滤波器带通滤波器,采用直接I型,截止频率140Hz和,采样400个数据,滤波器阶数设置为4。fadtool的配置如下:
40.17.png
配置好带通滤波器后,具体滤波器系数的生成大家参考本章第二小节的方法即可。

40.5.2 带通滤波器实现
    通过工具箱fdatool获得带通滤波器系数后在开发板上运行函数arm_biquad_cascade_df1_f32来测试带通滤波器的效果。
  1. #define numStages  2                /* 2阶IIR滤波的个数 */
  2. #define TEST_LENGTH_SAMPLES  400    /* 采样点数 */

  3. static float32_t testInput_f32_50Hz_200Hz[TEST_LENGTH_SAMPLES]; /* 采样点 */
  4. static float32_t testOutput[TEST_LENGTH_SAMPLES];               /* 滤波后的输出 */
  5. static float32_t IIRStateF32[4*numStages];                      /* 状态缓存,大小numTaps + blockSize - 1*/
  6.                                                                              
  7. /* 巴特沃斯带通滤波器系数140Hz 400Hz*/                                                                                                                                         
  8. const float32_t IIRCoeffs32BP[5*numStages] = {
  9. 1.0f,  0.0f,  -1.0f,    -1.1276518720541668f,   -0.47001314508753411f,      
  10. 1.0f,  0.0f,  -1.0f,    0.77495305804604886f,  -0.36707750055668387f                              
  11. };

  12. /*
  13. *********************************************************************************************************
  14. *        函 数 名: arm_iir_f32_bp
  15. *        功能说明: 调用函数arm_iir_f32_hp实现带通滤波器
  16. *        形    参:无
  17. *        返 回 值: 无
  18. *********************************************************************************************************
  19. */
  20. static void arm_iir_f32_bp(void)
  21. {
  22. uint32_t i;
  23. arm_biquad_casd_df1_inst_f32 S;
  24. float32_t ScaleValue;

  25. /* 初始化 */
  26. arm_biquad_cascade_df1_init_f32(&S, numStages, (float32_t *)&IIRCoeffs32BP[0], (float32_t
  27. *)&IIRStateF32[0]);
  28. /* IIR滤波 */
  29.         arm_biquad_cascade_df1_f32(&S, testInput_f32_50Hz_200Hz, testOutput, TEST_LENGTH_SAMPLES);
  30.    
  31. /*放缩系数 */   
  32. ScaleValue = 0.55815658576077365f * 0.55815658576077365f;  
  33. /* 打印滤波后结果 */
  34. for(i=0; i<TEST_LENGTH_SAMPLES; i++)
  35. {
  36. printf("%f\r\n", testOutput[i]*ScaleValue);
  37. }
  38. }
复制代码
运行如上函数可以通过串口打印出函数arm_biquad_cascade_df1_f32滤波后的波形数据,下面通过Matlab绘制波形来对比Matlab计算的结果和ARM官方库计算的结果。
    对比前需要先将串口打印出的一组数据加载到Matlab中, arm_biquad_cascade_df1_f32的计算结果起名sampledata,加载方法在前面的教程中已经讲解过,这里不做赘述了。Matlab中运行的代码如下:
  1. fs=1000;              %设置采样频率 1K
  2. N=400;               %采样点数      
  3. n=0:N-1;
  4. t=n/fs;                %时间序列
  5. f=n*fs/N;              %频率序列

  6. x1=sin(2*pi*50*t);
  7. x2=sin(2*pi*200*t);     %50Hz和200Hz正弦波
  8. subplot(211);
  9. plot(t, x1);
  10. title('滤波后的理想波形');
  11. grid on;

  12. subplot(212);
  13. plot(t, sampledata);
  14. title('ARM官方库滤波后的波形');
  15. grid on;
复制代码
Matlab计算结果如下:
40.18.png
从上面的波形对比来看,matlab和函数arm_biquad_cascade_df1_f32计算的结果基本是一致的。为了更好的说明滤波效果,下面从频域的角度来说明这个问题,Matlab上面运行如下代码:
  1. fs=1000;                %设置采样频率 1K
  2. N=400;                 %采样点数      
  3. n=0:N-1;
  4. t=n/fs;                  %时间序列
  5. f=n*fs/N;                %频率序列

  6. x = sin(2*pi*50*t) + sin(2*pi*200*t);      %50Hz和200Hz正弦波合成
  7.   
  8. subplot(211);
  9. y=fft(x, N);                %对信号x做FFT   
  10. plot(f,abs(y));
  11. xlabel('频率/Hz');
  12. ylabel('振幅');
  13. title('原始信号FFT');
  14. grid on;

  15. y3=fft(sampledata, N);    %经过IIR滤波器后得到的信号做FFT
  16. subplot(212);                              
  17. plot(f,abs(y3));
  18. xlabel('频率/Hz');
  19. ylabel('振幅');
  20. title('IIR滤波后信号FFT');
  21. grid on;
复制代码
Matlab计算结果如下:
40.19.png
上面波形变换前的FFT和变换后FFT可以看出,50Hz的正弦波基本被滤除。

wambob 回答时间:2015-4-28 11:14:32
标记学习
baiyongbin2009 回答时间:2015-4-28 12:45:41
40.6 IIR带阻滤波器设计
40.6.1 fdatool获取带阻滤波器系数
    设计一个如下的例子:
    信号由50Hz正弦波和200Hz正弦波组成,采样率1Kbps,现设计一个巴特沃斯滤波器带阻滤波器,采用直接I型,截止频率100Hz和325Hz,采样400个数据,滤波器阶数设置为4。fadtool的配置如下:
40.20.png
配置好带阻滤波器后,具体滤波器系数的生成大家参考本章第二小节的方法即可。

40.6.2 带阻滤波器实现
    通过工具箱fdatool获得带阻滤波器系数后在开发板上运行函数arm_biquad_cascade_df1_f32来测试带阻滤波器的效果。
  1. #define numStages  2                /* 2阶IIR滤波的个数 */
  2. #define TEST_LENGTH_SAMPLES  400    /* 采样点数 */

  3. static float32_t testInput_f32_50Hz_200Hz[TEST_LENGTH_SAMPLES]; /* 采样点 */
  4. static float32_t testOutput[TEST_LENGTH_SAMPLES];               /* 滤波后的输出 */
  5. static float32_t IIRStateF32[4*numStages];                      /* 状态缓存,大小numTaps + blockSize - 1*/
  6.                                                                              
  7. /* 巴特沃斯带阻滤波器系数100Hz 325Hz*/                                                                                                                                         
  8. const float32_t IIRCoeffs32BS[5*numStages] = {
  9. 1.0f,  -0.61400192638335005f,  1.0f,  1.1451427879497746f,   -0.50298007146721391f,
  10. 1.0f,  -0.61400192638335005f,  1.0f,  -0.47458704658841883f, -0.35305199748708849f                        
  11. };

  12. /*
  13. *********************************************************************************************************
  14. *        函 数 名: arm_iir_f32_bs
  15. *        功能说明: 调用函数arm_iir_f32_bs实现带阻滤波器
  16. *        形    参:无
  17. *        返 回 值: 无
  18. *********************************************************************************************************
  19. */
  20. static void arm_iir_f32_bs(void)
  21. {
  22. uint32_t i;
  23. arm_biquad_casd_df1_inst_f32 S;
  24. float32_t ScaleValue;

  25. /* 初始化 */
  26. arm_biquad_cascade_df1_init_f32(&S, numStages, (float32_t *)&IIRCoeffs32BS[0], (float32_t
  27. *)&IIRStateF32[0]);
  28. /* IIR滤波 */
  29.         arm_biquad_cascade_df1_f32(&S, testInput_f32_50Hz_200Hz, testOutput, TEST_LENGTH_SAMPLES);
  30.    
  31. /*放缩系数 */   
  32. ScaleValue = 0.58347920314378698f * 0.58347920314378698f;  
  33. /* 打印滤波后结果 */
  34. for(i=0; i<TEST_LENGTH_SAMPLES; i++)
  35. {
  36. printf("%f\r\n", testOutput[i]*ScaleValue);
  37. }
  38. }
复制代码
运行如上函数可以通过串口打印出函数arm_biquad_cascade_df1_f32滤波后的波形数据,下面通过Matlab绘制波形来对比Matlab计算的结果和ARM官方库计算的结果。
    对比前需要先将串口打印出的一组数据加载到Matlab中, arm_biquad_cascade_df1_f32的计算结果起名sampledata,加载方法在前面的教程中已经讲解过,这里不做赘述了。Matlab中运行的代码如下:
  1. fs=1000;              %设置采样频率 1K
  2. N=400;               %采样点数      
  3. n=0:N-1;
  4. t=n/fs;                %时间序列
  5. f=n*fs/N;              %频率序列

  6. x1=sin(2*pi*50*t);
  7. x2=sin(2*pi*200*t);     %50Hz和200Hz正弦波
  8. subplot(211);
  9. plot(t, x1);
  10. title('滤波后的理想波形');
  11. grid on;

  12. subplot(212);
  13. plot(t, sampledata);
  14. title('ARM官方库滤波后的波形');
  15. grid on;
复制代码
Matlab计算结果如下:
40.21.png
从上面的波形对比来看,matlab和函数arm_biquad_cascade_df1_f32计算的结果基本是一致的。为了更好的说明滤波效果,下面从频域的角度来说明这个问题,Matlab上面运行如下代码:
  1. fs=1000;                %设置采样频率 1K
  2. N=400;                 %采样点数      
  3. n=0:N-1;
  4. t=n/fs;                  %时间序列
  5. f=n*fs/N;                %频率序列

  6. x = sin(2*pi*50*t) + sin(2*pi*200*t);      %50Hz和200Hz正弦波合成
  7.   
  8. subplot(211);
  9. y=fft(x, N);                %对信号x做FFT   
  10. plot(f,abs(y));
  11. xlabel('频率/Hz');
  12. ylabel('振幅');
  13. title('原始信号FFT');
  14. grid on;

  15. y3=fft(sampledata, N);    %经过IIR滤波器后得到的信号做FFT
  16. subplot(212);                              
  17. plot(f,abs(y3));
  18. xlabel('频率/Hz');
  19. ylabel('振幅');
  20. title('IIR滤波后信号FFT');
  21. grid on;
复制代码
Matlab计算结果如下:
40.22.png
上面波形变换前的FFT和变换后FFT可以看出,200Hz的正弦波基本被滤除。

baiyongbin2009 回答时间:2015-4-28 12:46:42
40.7 总结
    本章节主要讲解了巴特沃斯低通,高通,带通和带阻滤波器的实现,有兴趣的可以使用同样的方法实现切比雪夫滤波器的设计。

XDLH 回答时间:2015-11-15 13:40:28
不错挺好的!受教了!

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版