FIR滤波器的设计方法主要有三种:窗函数法、频率取样法、切比雪夫等波纹逼近法。而在这个实验里,主要是采取第一种方法。
我们要设计一个滤波器,跟前面设计IIR滤波器一样,得先知道一些关于滤波器的指标。在用窗函数设计FIR滤波器需要知道的指标是:通带,阻带的边界频率,阻带衰减和通带衰减。
因为是FIR,有限冲激响应的滤波器,我们通常的理想滤波器的单位脉冲响应 h
是无限长的,所以我们需要通过窗来截断它,然后对它进行滤波器设计。
一、 加窗方法设计的步骤大概分以下几步:
1、根据阻带的衰减,选择合适的窗:
最小阻带衰减 过渡带带宽△w
矩形窗 20.9dB 0.92π/M
汉宁窗 43.9dB 3.11π/M
海明窗 54.5dB 3.32π/M
布莱克曼窗 75.3dB 5.56π/M
不同的窗有不同的性质:不同的窗函数,产生泄漏的大小不一样,频率分辨能力也不一样。信号的截断产生了能量泄漏,而用FFT算法计算频谱又产生了栅栏效应,从原理上讲这两种误差都是不能消除的,但是我们可以通过选择不同的窗函数对它们的影响进行抑制。(矩形窗主瓣窄,旁瓣大,频率识别精度最高,幅值识别精度最低;布莱克曼窗主瓣宽,旁瓣小,频率识别精度最低,但幅值识别精度最高)。
2、根据窗函数得到的序列经过firl或fir2得到一个滤波器传输函数系数的序列。
1)fir1 : 用来设计传统的低通,高通,带通,带阻,多频带FIR滤波器;
调用格式:b = fir1(N,Wn);
b = fir1(N,Wn,‘high’);
b = fir1(N,Wn, ‘stop’);
参数说明:N:阶次,滤波器长度为N+1;
Wn:通带截止频率,其值在0~1之间,1对应Fs/2;
b:滤波器系数。
在上述所有格式中,若不指定窗函数的类型,fir1自动选择Hamming窗。
2)fir2 : 用来设计具有任意幅度响应的FIR滤波器。
调用格式:b = fir2(N, F,
M);
参数说明:F是频率向量,其值在0~1之间;
M是和F相对应的所希望的幅频相应。
如同fir1,
缺省时自动选用Hamming窗。
3)为了观测到设计出来的滤波器的特性,我们可以用impz得到它的脉冲响应,用freqz得到频率响应。
其中在画频率响应的时候我们分为幅度和相位画出。
又因为我们要观测的是衰减的大小程度,以dB为单位,所以我们在画幅度的时候纵坐标应该转换成dB。
而相位,由于计算机中反正切函数规定,在一、二象限中的角度为0到π,三、四象限的角度为0到-π。我们一般要反应的角度变化是0到2π,但如果不经过处理,实际结果会在π处发生跳变,跳变的幅度为2π,这就是相位的卷绕。所以我们用解卷绕函数unwarp(w),使相位在π处不发生跳变,从而反应出真实的相位变化。
二、实例
%%第一题、通带截止频率为0.2pi,阻带截止频率为0.3pi,阻带衰减不小于50dB,通带衰减不大于3dB,设计一个FIR滤波器,并验证。
wp=0.2*pi;
ws=0.3*pi; %性能指标
wdelta=ws-wp; %过渡带宽度
M=ceil(3.32*pi/wdelta); %滤波器长度,朝正无穷方向舍入
N=2*M+1; %窗口长度
wc=(ws+wp)/2; %截止频率
win=hamming(N); %因为衰减不小于50dB,所以选择海明窗,这里得到海明窗的时域响应
b=fir1(N-1,wc/pi,win);
n=0:1:N;
[hi t]=impz(b,1,n);%得到脉冲响应
[hf w]=freqz(b,1,512); %得到频率响应
figure(1);
subplot(3,1,1); stem(n,hi);
xlabel('n'); ylabel('Magnitude'); title('impulse response');
subplot(3,1,2); plot(w/pi,20*log10(abs(hf)));
xlabel('Frequency(Hz)'); ylabel('Magnitude(dB)');
title('Frequency response');
subplot(3,1,3); plot(w/pi,180/pi*unwrap(angle(hf)));
xlabel('Frequency(Hz)'); ylabel('Phase(degrees)');
title('Frequency response');
%验证:
nn=0:50;
x1=sin(nn*0.2*pi); x2=sin(nn*0.8*pi);%假设两个信号,低频和高频
in=x1+x2; out=filter(b,1,in); %滤波过程
figure(2);
subplot(2,2,1); stem(x1);
xlabel('n'); ylabel('Magnitude');
title('x1'); axis([0 50 -1 1]);
subplot(2,2,2); stem(x2);
xlabel('n'); ylabel('Magnitude');
title('x2'); axis([0 50 -1 1]);
subplot(2,2,3); stem(in);
xlabel('n'); ylabel('Magnitude');
title('x1+x2 before filter'); axis([0 50 -2 2]);
subplot(2,2,4); stem(out);
xlabel('n'); ylabel('Magnitude');
title('x1+x2 after filter'); axis([0 50 -1 1]);
在这题要主要的是求分贝的公式:20*log10(abs(hf)),还有解卷绕函数的调用180/pi*unwrap(angle(hf))。
从上面的程序可以得到图:
%第二题,取1中相同的滤波器类型和阶数,通带和阻带的临界频率也相同,分别用矩形窗,汉宁窗,海明窗和布莱克曼窗设计滤波器,并分析它们的性能。
wp=0.2*pi;
ws=0.3*pi; %性能指标
wdelta=ws-wp; %过渡带宽度
M1=ceil(0.92*pi/wdelta); M2=ceil(3.11*pi/wdelta);
M3=ceil(3.32*pi/wdelta);
M4=ceil(5.56*pi/wdelta);
N1=2*M1+1; N2=2*M2+1;
N3=2*M3+1;
N4=2*M4+1;
wc=(ws+wp)/2; %截止频率
win1=boxcar(N1); %矩形窗的时域响应
win2=hanning(N2); %汉宁窗的时域响应
win3=hamming(N3); %海明窗的时域响应
win4=blackman(N4); %布莱克窗的时域响应
b1=fir1(N1-1,wc/pi,win1); b2=fir1(N2-1,wc/pi,win2); b3=fir1(N3-1,wc/pi,win3); b4=fir1(N4-1,wc/pi,win4); [h1 w1]=freqz(b1,1,512); [h2 w2]=freqz(b2,1,512) ;
[h3 w3]=freqz(b3,1,512) ;
[h4 w4]=freqz(b4,1,512) ;
figure(3);
subplot(4,2,1); plot(w1/pi,20*log10(abs(h1)));
ylabel('Magnitude'); title('Rectangle
Window');
subplot(4,2,2); plot(w1/pi,180/pi*unwrap(angle(h1)));
ylabel('Phase(degrees)'); title('Rectangle
Window');
subplot(4,2,3); plot(w2/pi,20*log10(abs(h2)));
ylabel('Magnitude'); title('Hanning Window');
subplot(4,2,4); plot(w2/pi,180/pi*unwrap(angle(h2)));
ylabel('Phase'); title('Hanning
Window');
subplot(4,2,5); plot(w3/pi,20*log10(abs(h3)));
ylabel('Magnitude'); title('Hamming Window');
subplot(4,2,6); plot(w3/pi,180/pi*unwrap(angle(h3)));
ylabel('Phase'); title('Hamming
Window');
subplot(4,2,7); plot(w4/pi,20*log10(abs(h4)));
ylabel('Magnitude'); title('Blankman Window');
subplot(4,2,8); plot(w4/pi,180/pi*unwrap(angle(h4)));
ylabel('Phase'); title('Blankman
Window');
这题只是单纯的重复4次滤波器的设计,设计的方法同第一题一样。得到的图如下:
从上可以观察到,
1、衰减:从上到下,衰减依次增大,以布莱克曼窗的为最优,矩形窗最差。
2、过渡带:从上到下,过渡带逐渐增宽,以矩形窗的为最优,布莱克曼窗最差。
其实,改善阻带衰减的一种办法是加宽过渡带宽,以牺牲过渡带换取阻带衰减的增加。也就是以增加主瓣宽度为代价来降低旁瓣。
所以,我们在设计滤波器的时候,要根据不同的指标,性能,需求去选择合适的窗来进行设计。