DSP新人来了!
我正在修补 TI DSP 并尝试在 C 中实现二阶 IIR 滤波器。输入是 16 位 2 的补码,输出也是如此,累加器是 32 位宽。我尝试了几种结构:直接形式 I、转置直接形式 II、Gold & Rader 结构。但是,我似乎无法工作,我不确定这是否是我所有过滤器实现的代码中的拼写错误,还是因为我误解了定点算术的原理。我假设 - 或者更好:希望 - 这是影响所有实现的同一个错误。
这是我的转置 df II 实现的代码:
// state variables
int w[3] = {0};
short filter_dfii(short value) {
w[0] = ((value * sos_filter_coeffs_b[0] + w[1]) >> 15 ) & 0xffff;
w[1] = value * sos_filter_coeffs_b[1]
- w[0] * sos_filter_coeffs_a[1]
+ w[2];
w[2] = value * sos_filter_coeffs_b[2]
- w[0] * sos_filter_coeffs_a[2];
return (short) w[0];
}
我的 df I 实现如下所示:
int last_value[2] = {0};
short filter_dfi(short value) {
w[0] =
((value * sos_filter_coeffs_b[0]
+ last_value[0] * sos_filter_coeffs_b[1]
+ last_value[1] * sos_filter_coeffs_b[2]
- w[1] * sos_filter_coeffs_a[1]
- w[2] * sos_filter_coeffs_a[2])
>> 15) & 0xffff;
last_value[1] = last_value[0];
last_value[0] = value;
w[2] = w[1];
w[1] = w[0];
return (short) w[0];
}
滤波器系数为:
int sos_filter_coefficients_a = {32767, -51150, 21015};
int sos_filter_coefficients_b = {658, 1316, 658};
我是如何得到这些系数的?我使用了 Matlab 的“黄油”功能,并在我的具体情况下指定了截止频率为 0.05*fs 或 2400 kHz 的二阶巴特沃斯低通。然后我将每个系数乘以 32767 并将其四舍五入为整数值。如果我用这些量化系数调用 Matlab freqz 函数,我会得到一个带有预期结果的波特图,所以我相信量化误差不是这里的问题。
但是,结果不是低通,而是垃圾。不幸的是,我缺乏适当的测试设备来科学地描述结果,但它听起来像数字振荡,受实际输入信号的轻微调制,即使完全没有输入也存在。
所以,在我看来,这不可能是一个不稳定的过滤器,因为极点在单位圆内。它也不能是溢出限制循环,因为当只有低输入电平或根本没有输入时它不应该发生......对吗?
如果我将系数更改为
int sos_filter_coefficients_a = {32767, 0, 0};
int sos_filter_coefficients_b = {32767, 0, 0};
输入基本上没有按预期返回,所以我的问题很可能不是由任何外部因素引起的——我的系数、函数本身或两者都有问题。
任何帮助深表感谢!