IIR滤波器学习笔记
- 数字无限冲击响应,输出<==历史输入+当前输入+历史输出(反馈)。也被称为递归滤波器。
- 本质:来源自模拟滤波器的传输函数。
- 相位补偿:可以串联全通网络进行相位校正(额外运算量)
- 选择性越好,则相位非线性越严重
- 会因为运算精度而累积误差,导致极点偏移,出现系统不稳定(振荡)。
- 其冲击响应是非对称的,因此相位非线性
- 计算过程:递归方程
IIR递归方程:
- 递归系数与频率响应之间可以通过Z变换来转换
- 一阶IIR可近似于简单的RC滤波器
- C实现:CMSIS\DSP\Source\FilteringFunctions\arm_biquad_cascade_df1_f32.c
滤波器参数设计
- 设计思想:设计一个模拟滤波器,并得到它的传输函数,通过”双线性变换”、或”脉冲响应不变法”转换为数字滤波器。如果直接在频域/时域设计,需要求解方程组,通常用软件实现。
- 难点:在于确定模拟滤波器传输函数H(s),由软件生成/查表。
- 先确定滤波器类型(巴特沃斯、切比雪夫等)
- 根据设计参数和滤波器函数确定阶数、传输函数Hs表达式。
- 如果采用双线性变化法,需要先处理预扭曲问题
- 使用双线性变换或脉冲响应不变法将Hs求得数字域的差分方程。
传递函数Hs
- 传递函数包括零点和极点两组可调因素,对极点的惟一限制是在单位圆内。因此可用较低的阶数获得高的选择性,所用的存储单元少,计算量小,效率高。
- 必须采用递归结构来配置极点,并保证极点位置在单位圆内,否则自激
biquad型/双二阶(SOS)
- Second-Order Sections(二阶块)。
- biquad是多个二阶IIR模块块的级联。最为常用IIR设计。
- 转置结构直接II型biquad(先相加,再延迟,节省延迟器,且能模块化,实用的实现)参数不变,只是运算顺序变化
- MATLAB生成系数意义:格式为直接II型SOS块参数
固定四阶IIR的C代码实现:
typedef struct { float SOSCoeffs[2*5]; //b0 b1 b2 a1 a2 float Gain[2]; //每个抽头的增益 float Dealy[2*2]; //延迟缓冲state z1 z2 }IIR_context_Td; void biquad_filter_calc(IIR_context_Td *pCtx,int16_t *InData,int16_t *OutData,uint16_t InNum) { float *pGain = pCtx->Gain; float Out,In; //load param: float zdelay11,zdelay12; float b10,b11,b12,a11,a12; zdelay11=pCtx->Dealy[0]; zdelay12=pCtx->Dealy[1]; b10=pCtx->SOSCoeffs[0]; b11=pCtx->SOSCoeffs[1]; b12=pCtx->SOSCoeffs[2]; a11=pCtx->SOSCoeffs[3]; a12=pCtx->SOSCoeffs[4]; float zdelay21,zdelay22; float b20,b21,b22,a21,a22; zdelay21=pCtx->Dealy[2]; zdelay22=pCtx->Dealy[3]; b20=pCtx->SOSCoeffs[5]; b21=pCtx->SOSCoeffs[6]; b22=pCtx->SOSCoeffs[7]; a21=pCtx->SOSCoeffs[8]; a22=pCtx->SOSCoeffs[9]; //calc: while(InNum--) { In=(float)*InData++; Out=In*b10+zdelay11; zdelay11=In*b11+zdelay12+Out*a11; zdelay12=In*b12+Out*a12; Out= Out*pGain[0]; In=Out; Out=In*b20+zdelay21; zdelay21=In*b21+zdelay22+Out*a21; zdelay22=In*b22+Out*a22; Out= Out*pGain[1]; *OutData++ = (int16_t)Out; } //save param: pCtx->Dealy[0]=zdelay11; pCtx->Dealy[1]=zdelay12; pCtx->Dealy[2]=zdelay21; pCtx->Dealy[3]=zdelay22; }
本文为原创文章,转载请注明出处!