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;
}
本文为原创文章,转载请注明出处!