1. 程式人生 > >[數字訊號處理] FIR濾波器基礎

[數字訊號處理] FIR濾波器基礎

對於一個濾波器而言,其單位衝擊響應是有限區間的數列的話,這個濾波器是FIR濾波器。反之,其單位衝擊響應是無限區間的數列的話,這個濾波器是IIR濾波器。

   下面使用線性差分方程式,在時域內,解釋一下FIR與IIR數字濾波器。使用單位脈衝響應和其輸入訊號進行卷積運算,可得到下式


   將其改寫為遞迴的方式,則

 

    上式是1次差分方程式,而對於N次數字濾波器的輸入輸出關係,表示為N次差分方程式,如下所示。

        

     由上式看,輸出 y(n) 需要自己的歷史值,也就是,含有反饋。

     a_k = 0的時候,反饋有作用,其系統框圖如下。

     此時,輸入單位脈衝,由於反饋的作用,系統的單位衝擊響應是無限的。

     a_k != 0的時候,無反饋作用,其單位衝擊響應是有限的,其單位框圖如下。

     輸入單位脈衝,由於沒有反饋的作用,系統的單位衝擊響應是有限的。也就是Finite Impulse Response,字面意思。

 接下來,用C實現一個FIR濾波器,這裡,係數是隨意設定的。

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <malloc.h>
  4. #include <string.h>
  5. double Real_Time_FIR_Filter(double *b,  
  6.                             int
         b_Lenth,  
  7.                             double *Input_Data)  
  8. {      
  9.     int Count;  
  10.     double Output_Data = 0;  
  11.     Input_Data += b_Lenth - 1;    
  12.     for(Count = 0; Count < b_Lenth ;Count++)  
  13.     {   
  14.             Output_Data += (*(b + Count)) *  
  15.                             (*(Input_Data - Count));  
  16.     }           
  17.     return (double)Output_Data;  
  18. }  
  19. void Save_Input_Date (double Scand,  
  20.                       int    Depth,  
  21.                       double *Input_Data)  
  22. {  
  23.     int Count;  
  24.     for(Count = 0 ; Count < Depth-1 ; Count++)  
  25.     {  
  26.         *(Input_Data + Count) = *(Input_Data + Count + 1);  
  27.     }  
  28.     *(Input_Data + Depth-1) = Scand;  
  29. }  
  30. int main(void)  
  31. {  
  32.     double b[] = {0.5 , -0.5 , 1};  
  33.     double Scand_Data = 0;  
  34.     char Command = 0;  
  35.     int b_Lenth = (sizeof(b)/sizeof(double));  
  36.     int Count = 0;  
  37.     double Input_Data[sizeof(b)/sizeof(double)] = {0};  
  38.     double Output_Data = 0;  
  39.     /*--------------------display----------------------------*/
  40.     printf("  b(k) : ");  
  41.     for(Count = 0; Count < b_Lenth ;Count++)  
  42.     {  
  43.         printf("%f " , b[Count]);  
  44.     }  
  45.     printf("\n");  
  46.     /*-----------------------------------------------------*/
  47.     Count = 0;  
  48.     while(1)  
  49.     {  
  50.         if(Count == 0) printf("The Input : ");     
  51.         else printf("The Next Input : ");     
  52.         scanf("%lf",&Scand_Data);  
  53.         printf("Input x(%d) : %lf         ",Count,Scand_Data);      
  54.         Save_Input_Date (Scand_Data,  
  55.                          b_Lenth,  
  56.                          Input_Data);  
  57.         Output_Data = Real_Time_FIR_Filter(b,  
  58.                                            b_Lenth,  
  59.                                            Input_Data);          
  60.         printf("Output y(%d) : %lf  \n",Count,Output_Data);                      
  61.         scanf("%c",&Command);  
  62.         if(Command == 27) break;    //ESC
  63.         Count++;  
  64.     }  
  65.     printf("\n");  
  66.     return (int)0;  
  67. }  

到此,一個FIR濾波器就實現了,只需要不停的輸入輸入訊號就好了,ESC鍵可以停止程式。

其單位衝擊響應用Matlab表示如下。