[数字信号处理]IIR滤波器基础

80 篇文章 5 订阅
73 篇文章 1 订阅

1.IIR滤波器构造

          之前在介绍FIR滤波器的时候,我们提到过,IIR滤波器的单位冲击响应是无限的!用差分方程来表达一个滤波器,应该是下式这个样子的。
          
        这个式子是N次差分方程的表达式。我们明显可以看出,计算输出y(n)的时候,需要以前的输出值与输入值。换言之,这个可能表达式还有反馈环节。当 为0的时候,这个滤波器由于没有反馈,其单位冲击响应是有限的,是FIR滤波器。当 不为0是时候,是IIR滤波器。

2.直接I型IIR滤波器

        就如同之前所说一样,我们考虑这样一个滤波器。
 
        很明显,这是一个1阶才差分方程。由于 不为0,这是一个1阶IIR滤波器的差分方程。为了方便观察,我们将其画系统成框图。

        很明显的,要实现这个滤波器,我们需要2个单位的存储空间,用来存储过去的输入值与输出值。这样的话,考虑N阶的滤波器,我们就需要2N个存储单元。这种结构被称作直接I型结构。

3.直接II型IIR滤波器

       我们先观察上图的直接I型滤波器,将其视为有两个较小系统串联而成的系统。由于是串联,那么,顺序必定不影响输入输出结果,那么,我们将其调整一下位置。得到就像下图一样的一个新的系统。

        然后,我们可以发现,其实,这个系统完全没有必要使用两个延迟算子,可以合并使用。将其延迟算子合并,那么,可以得到下面这样一个系统。

        这个系统与之前的直接I型系统一样,拥有完全相同的输入输出特性。并且,节省了一半的延迟算子。实现这个滤波器所需要的存储空间为N。

3.直接II型IIR滤波器的实现(C语言)


[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <math.h>  
  3. #include <malloc.h>  
  4. #include <string.h>  
  5.   
  6.   
  7. double IIR_Filter(double *a, int Lenth_a,  
  8.                   double *b, int Lenth_b,  
  9.                   double Input_Data,  
  10.                   double *Memory_Buffer)   
  11. {  
  12.     int Count;  
  13.     double Output_Data = 0;   
  14.     int Memory_Lenth = 0;  
  15.       
  16.     if(Lenth_a >= Lenth_b) Memory_Lenth = Lenth_a;  
  17.     else Memory_Lenth = Lenth_b;  
  18.       
  19.     Output_Data += (*a) * Input_Data;  //a(0)*x(n)               
  20.       
  21.     for(Count = 1; Count < Lenth_a ;Count++)  
  22.     {  
  23.         Output_Data -= (*(a + Count)) *  
  24.                        (*(Memory_Buffer + (Memory_Lenth - 1) - Count));                                         
  25.     }   
  26.       
  27.     //------------------------save data--------------------------//   
  28.     *(Memory_Buffer + Memory_Lenth - 1) = Output_Data;  
  29.     Output_Data = 0;  
  30.     //----------------------------------------------------------//   
  31.       
  32.     for(Count = 0; Count < Lenth_b ;Count++)  
  33.     {         
  34.         Output_Data += (*(b + Count)) *  
  35.                        (*(Memory_Buffer + (Memory_Lenth - 1) - Count));        
  36.     }  
  37.       
  38.     //------------------------move data--------------------------//   
  39.     for(Count = 0 ; Count < Memory_Lenth -1 ; Count++)  
  40.     {  
  41.         *(Memory_Buffer + Count) = *(Memory_Buffer + Count + 1);  
  42.     }  
  43.     *(Memory_Buffer + Memory_Lenth - 1) = 0;  
  44.     //-----------------------------------------------------------//  
  45.   
  46.     return (double)Output_Data;   
  47. }  
  48.   
  49.   
  50.   
  51. int main(void)  
  52. {      
  53.     double a[] = {1   , 0.5554 ,0.1542 };     
  54.     double b[] = {0   ,      0 ,0.1542 };     
  55.      
  56.     int Lenth_a = sizeof(a)/sizeof(double);  
  57.     int Lenth_b = sizeof(b)/sizeof(double);  
  58.     int Memory_Lenth = 0;  
  59.       
  60.     if(Lenth_a >= Lenth_b) Memory_Lenth = Lenth_a;  
  61.     else Memory_Lenth = Lenth_b;  
  62.       
  63.     printf("Memory Lenth : %d  \n" , Memory_Lenth);   
  64.      
  65.     double Input = 0 ;  
  66.     double Output = 0;  
  67.       
  68.     double *Memory_Buffer;  
  69.     Memory_Buffer = (double *) malloc(sizeof(double)*Memory_Lenth);    
  70.     memset(Memory_Buffer,  
  71.            0,  
  72.            sizeof(double)*Memory_Lenth);  
  73.       
  74.   
  75.     FILE* Input_Data;  
  76.     FILE* Output_Data;  
  77.        
  78.     Input_Data = fopen("input.dat","r");   
  79.     Output_Data= fopen("output.txt","w");   
  80.       
  81.     while(1)  
  82.     {  
  83.         if(fscanf(Input_Data, "%lf", &Input) == EOF)  break;  
  84.           
  85.         Output = IIR_Filter( a, Lenth_a,  
  86.                              b, Lenth_b,  
  87.                              Input,  
  88.                              Memory_Buffer);  
  89.   
  90.         fprintf(Output_Data,"%lf,",Output);  
  91.           
  92.         //printf("Output:  %lf \n" ,Output);  
  93.     }     
  94.       
  95.     printf("Finish \n");  
  96.   
  97.     return (int)1;  
  98. }  
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值