计算二阶巴特沃斯低通滤波器的系数

时间:2014-01-04 18:22:02

标签: c++ signal-processing

使用,

采样频率:10kHz
截止频率:1kHz

如何实际计算下面差分方程的系数?

我知道差分方程将采用这种形式,但不知道如何实际计算并得出系数b0,b1,b2,a1,a2

的数字
y(n)  =  b0.x(n) + b1.x(n-1) + b2.x(n-2) + a1.y(n-1) + a2.y(n-2)

我最终将在C ++中实现这个LPF,但我需要知道如何在我可以随身携带它之前先实际计算系数

6 个答案:

答案 0 :(得分:9)

你走了。 ff是频率比,在你的情况下为0.1:

    const double ita =1.0/ tan(M_PI*ff);
    const double q=sqrt(2.0);
    b0 = 1.0 / (1.0 + q*ita + ita*ita);
    b1= 2*b0;
    b2= b0;
    a1 = 2.0 * (ita*ita - 1.0) * b0;
    a2 = -(1.0 - q*ita + ita*ita) * b0;

结果是:

b0 = 0.0674553
B1 = 0.134911
B2 = 0.0674553
A1 = 1.14298
A2 = -0.412802

答案 1 :(得分:4)

您可以使用此链接获取具有特定采样率和频率削减的n阶巴特沃兹滤波器的系数。为了测试结果。您可以使用MATLAB获取系数并与程序的输出进行比较

http://www.exstrom.com/journal/sigproc

fnorm = f_cutoff/(f_sample_rate/2); % normalized cut off freq, http://www.exstrom.com/journal/sigproc
% Low pass Butterworth filter of order N
[b1, a1] = butter(nth_order, fnorm,'low');

答案 2 :(得分:3)

对于那些想知道其他答案中的神奇公式从何而来的人,以下是this example之后的推导。

从巴特沃斯滤波器的传递函数开始

G(s) = wc^2 / (s^2 + s*sqrt(2)*wc + wc^2)

其中wc是截止频率,应用双线性z变换,即替换s = 2/T*(1-z^-1)/(1+z^-1)

G(z) = wc^2 / ((2/T*(1-z^-1)/(1+z^-1))^2 + (2/T*(1-z^-1)/(1+z^-1))*sqrt(2)*wc + wc^2)

T是采样周期[s]。

截止频率需要预先扭曲以补偿非线性 z转换引入的模拟频率与数字频率之间的关系:

wc = 2/T * tan(wd*T/2)

其中wd所需的截止频率[rad / s]。

为了方便起见,请C = tan(wd*T/2),以便wc = 2/T*C

将其代入方程式,2/T因子消失:

G(z) = C^2 / ((1-z^-1)/(1+z^-1))^2 + (1-z^-1)/(1+z^-1)*sqrt(2)*C + C^2)

将分子和分母乘以(1+z^-1)^2并展开,得到:

G(z) = C^2*(1 + 2*z^-1 + z^-2) / (1 + sqrt(2)*C + C^2 + 2*(C^2-1)*z^-1 + (1-sqrt(2)*C+C^2)*z^-2')

现在,将分子和分母除以分母中的常数项。为了方便起见,让D = 1 + sqrt(2)*C + C^2

G(z) = C^2/D*(1 + 2*z^-1 + z^-2) / (1 + 2*(C^2-1)/D*z^-1 + (1-sqrt(2)*C+C^2)/D*z^-2')

这种形式等同于我们正在寻找的形式:

G(z) = (b0 + b1*z^-1 + b2*z^-1) / (1 + a1*z^-1 +a2*z^-2)

因此,我们通过将它们相等来获得系数:

a0 = 1

a1 = 2*(C^2-1)/D

a2 = (1-sqrt(2)*C+C^2)/D

b0 = C^2/D

b1 = 2*b0

b2 = b0

同样,D = 1 + sqrt(2)*C + C^2C = tan(wd*T/2)wd是所需的截止频率[rad / s],T是采样周期[s]。

答案 3 :(得分:2)

FYI 如果您需要高通滤波器系数,您只需使用相同的代码:

const double ita =1.0/ tan(M_PI*ff);
const double q=sqrt(2.0);
b0 = 1.0 / (1.0 + q*ita + ita*ita);
b1= 2*b0;
b2= b0;
a1 = 2.0 * (ita*ita - 1.0) * b0;
a2 = -(1.0 - q*ita + ita*ita) * b0;

然后将所有b项乘以ita ^ 2并否定b1

b0 = b0*ita*ita;
b1 = -b1*ita*ita;
b2 = b2*ita*ita;

现在你有一个二阶高通滤波器

答案 4 :(得分:1)

我的 a 和 b 在这里切换,但我的代码看起来像这样:

//Boulanger and Lazzarini, The Audio Programming Book, pg 484
void calculateDifferenceEquation() {
    float lambda = 1.0 / (tan(M_PI * mFrequency / mSampleRate));
    a0 = 1.0 / (1.0 + (2.0 * lambda) + pow(lambda, 2.0));
    a1 = 2.0 * a0;
    a2 = a0;
    b1 = 2.0 * a0 * (1.0 - pow(lambda, 2.0));
    b2 = a0 * (1.0 - (2.0 * lambda) + pow(lambda, 2.0));
}

答案 5 :(得分:-1)

最好的方法是使用实​​验室视图之类的东西来模拟你的滤镜,并根据你的fc和fs得到系数。然后在c中使用它们。最后将代码刻录到您的微控制器中。并将响应与实验室视图或simulink中的响应进行比较。