DSP

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

2019-07-13 20:01发布

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语言)


#include #include #include #include double IIR_Filter(double *a, int Lenth_a, double *b, int Lenth_b, double Input_Data, double *Memory_Buffer) { int Count; double Output_Data = 0; int Memory_Lenth = 0; if(Lenth_a >= Lenth_b) Memory_Lenth = Lenth_a; else Memory_Lenth = Lenth_b; Output_Data += (*a) * Input_Data; //a(0)*x(n) for(Count = 1; Count < Lenth_a ;Count++) { Output_Data -= (*(a + Count)) * (*(Memory_Buffer + (Memory_Lenth - 1) - Count)); } //------------------------save data--------------------------// *(Memory_Buffer + Memory_Lenth - 1) = Output_Data; Output_Data = 0; //----------------------------------------------------------// for(Count = 0; Count < Lenth_b ;Count++) { Output_Data += (*(b + Count)) * (*(Memory_Buffer + (Memory_Lenth - 1) - Count)); } //------------------------move data--------------------------// for(Count = 0 ; Count < Memory_Lenth -1 ; Count++) { *(Memory_Buffer + Count) = *(Memory_Buffer + Count + 1); } *(Memory_Buffer + Memory_Lenth - 1) = 0; //-----------------------------------------------------------// return (double)Output_Data; } int main(void) { double a[] = {1 , 0.5554 ,0.1542 }; double b[] = {0 , 0 ,0.1542 }; int Lenth_a = sizeof(a)/sizeof(double); int Lenth_b = sizeof(b)/sizeof(double); int Memory_Lenth = 0; if(Lenth_a >= Lenth_b) Memory_Lenth = Lenth_a; else Memory_Lenth = Lenth_b; printf("Memory Lenth : %d " , Memory_Lenth); double Input = 0 ; double Output = 0; double *Memory_Buffer; Memory_Buffer = (double *) malloc(sizeof(double)*Memory_Lenth); memset(Memory_Buffer, 0, sizeof(double)*Memory_Lenth); FILE* Input_Data; FILE* Output_Data; Input_Data = fopen("input.dat","r"); Output_Data= fopen("output.txt","w"); while(1) { if(fscanf(Input_Data, "%lf", &Input) == EOF) break; Output = IIR_Filter( a, Lenth_a, b, Lenth_b, Input, Memory_Buffer); fprintf(Output_Data,"%lf,",Output); //printf("Output: %lf " ,Output); } printf("Finish "); return (int)1; }
        当然,这里的参数还是随意设置的。之后我会就IIR的滤波器的间接设计与直接设计,进行详细的说明。
       博客地址:http://blog.csdn.net/thnh169/