当前位置:   article > 正文

使用窗函数方法设计FIR滤波器与MATLAB代码分析_ideal_lp

ideal_lp

一,写在前面的话.

学习了以下链接,然后写出了MATLAB代码,在本文末,大家可以随便下载代码,进行尝试,我代码调试正常,可使用。

1. 如果你是初学者,建议你看一下这个链接https://blog.csdn.net/zhoufan900428/article/details/8969470

自学什么是窗函数,什么是滤波器,为啥要用窗函数,怎么计算一些值,怎么根据这些值选择窗函数。

2. 如果你明白了上述内容,但还不能单独写代码进行分析,推荐你看这个链接:https://www.cnblogs.com/xhslovecx/p/10196851.html

自学怎么计算,然后选好窗函数,就设计,写公式。在那文章末尾他给了MATLAB采用FIR I型设计20Hz以下的低通滤波器的代码。

3. 如果你明白了以上内容,那么就请看下去吧:

代码都上传到下面了,随便用,但如果你要发表的话,请改一改,因为我的论文已经入库了,你要是直接抄,老师可能从查重率上把你毙了,改个参数名啥的可以,写论文很少发代码的

二,简单介绍

    我们知道IIR(无限脉冲响应)数字滤波器的设计方法是利用模拟滤波器成熟的理论及设计图表进行的,因而保留了一些典型模拟滤波器优良的幅度特性,但设计中只考虑到了幅度特性,没考虑到相位特性,所设计的滤波器相位特性一般是非线性的。而FIR(有限脉冲响应)滤波器在保证幅度特性满足技术要求的同时,比较容易做到有严格的线性相位特性。

    FIR滤波器分为四种:LP(低通滤波器),HP(高通滤波器),BP(带通滤波器),BS(带阻滤波器)。

    它们的公式我就不写了,但是需要知道。还要知道什么是线性相位FIR滤波器幅度特性和零点分布特点。

    我们熟知的窗函数有:三角窗,矩形窗,汉明窗,汉宁窗,布莱克曼窗,

    我们若是分析特性,则需要知道什么是主瓣,旁瓣,若是选择窗函数,则需要计算窗长度N,然后选择合适的阻带衰减(dB),阻带衰减不能比窗长度小。

   然后写代码的时候,要手写时域表达式(这个叫写窗)。我把它们的公式写在下面:大家可以直接复制粘贴。

   我直接贴了四个窗函数MATLAB的代码,请大家先参悟一下,再看加上滤波器的代码。

第一个是矩形窗:

  1. n=0:1:14;
  2. wR=ones(1,15);% 编写矩形窗
  3. hd=sin(0.25*pi*(n-7+eps))./(pi*(n-7+eps));%读入hd(n)函数
  4. h1=hd.*wR;%计算h(n)
  5. N=64;
  6. H1=fft(h1,N);%调用子程序计算H(k)
  7. n=0:N-1;w=2*pi/64*n;subplot(2,2,1);
  8. plot(w,fftshift(20*log10((abs(H1)))));%画幅度曲线
  9. grid on
  10. xlabel('w/rad')
  11. ylabel('20lg|H(jw)|/dB')
  12. title('幅度曲线和相频曲线(n=15)');
  13. n=0:N-1;w=2*pi/64*n;subplot(2,2,3);
  14. plot(w,fftshift(unwrap(phase(H1))));%画相频曲线
  15. grid
  16. xlabel('w/rad')
  17. clear all;
  18. n=0:1:32;
  19. wR=ones(1,33);% 编写矩形窗
  20. hd=sin(0.25*pi*(n-16+eps))./(pi*(n-16+eps));%读入hd(n)函数
  21. h1=hd.*wR;%计算h(n)
  22. N=64;
  23. H1=fft(h1,N);%调用子程序计算H(k)
  24. n=0:N-1;w=2*pi/64*n;subplot(2,2,2);
  25. plot(w,fftshift(20*log10((abs(H1)))));%画幅度曲线
  26. grid on
  27. xlabel('w/rad')
  28. ylabel('20lg|H(jw)|/dB')
  29. title('幅度曲线和相频曲线(n=15)');
  30. n=0:N-1;w=2*pi/64*n;subplot(2,2,4);
  31. plot(w,fftshift(unwrap(phase(H1))));%画相频曲线
  32. grid
  33. xlabel('w/rad')

第二个是汉宁窗

  1. clear all;
  2. n=0:1:14;
  3. wH=0.5*(1-cos(2*pi/14*n));% 编写汉宁窗
  4. hd=sin(0.25*pi*(n-7+eps))./(pi*(n-7+eps));%读入hd(n)函数
  5. h1=hd.*wH;%计算h(n)
  6. N=64;
  7. H1=fft(h1,N);%调用子程序计算H(k)
  8. n=0:N-1;w=2*pi/64*n;subplot(2,2,1);
  9. subplot(2,2,1);
  10. plot(w,fftshift(20*log10((abs(H1)))));%画幅度曲线
  11. grid
  12. xlabel('w/rad')
  13. ylabel('20lg|H(jw)|/dB');
  14. title('幅度曲线和相频曲线(n=15)');
  15. n=0:N-1;w=2*pi/64*n;subplot(2,2,1);
  16. subplot(2,2,3);
  17. plot(w,fftshift(unwrap(phase(H1))));%画相频曲线
  18. grid
  19. xlabel('w/rad')
  20. n=0:1:32;
  21. wH=0.5*(1-cos(2*pi/32*n));% 编写汉宁窗
  22. hd=sin(0.25*pi*(n-16+eps))./(pi*(n-16+eps));%读入hd(n)函数
  23. h1=hd.*wH;%计算h(n)
  24. N=64;
  25. H1=fft(h1,N);%调用子程序计算H(k)
  26. n=0:N-1;w=2*pi/64*n;subplot(2,2,1);
  27. subplot(2,2,2);
  28. plot(w,fftshift(20*log10((abs(H1)))));%画幅度曲线
  29. grid
  30. xlabel('w/rad')
  31. ylabel('20lg|H(jw)|/dB')
  32. title('幅度曲线和相频曲线(n=33)');
  33. n=0:N-1;w=2*pi/64*n;subplot(2,2,1);
  34. subplot(2,2,4);plot(w,fftshift(unwrap(phase(H1))));%画相频曲线
  35. grid
  36. xlabel('w/rad')

第三个是汉明窗

  1. clear all;
  2. n=0:1:14;
  3. wH=0.54-0.46*cos(2*pi*n/(14+eps));% 编写海明窗
  4. hd=sin(0.25*pi*(n-7+eps))./(pi*(n-7+eps));%读入hd(n)函数
  5. h1=hd.*wH;%计算h(n)
  6. N=64;
  7. H1=fft(h1,N);%调用子程序计算H(k)
  8. n=0:N-1;w=2*pi/64*n;subplot(2,2,1);
  9. subplot(2,2,1);
  10. plot(w,fftshift(20*log10((abs(H1)))));%画幅度曲线
  11. grid
  12. xlabel('w/rad')
  13. ylabel('20lg|H(jw)|/dB');
  14. title('幅度曲线和相频曲线(n=15)');
  15. n=0:N-1;w=2*pi/64*n;subplot(2,2,1);
  16. subplot(2,2,3);
  17. plot(w,fftshift(unwrap(phase(H1))));%画相频曲线
  18. grid
  19. xlabel('w/rad')
  20. n=0:1:32;
  21. wH=0.5*(1-cos(2*pi/32*n));% 编写汉宁窗
  22. hd=sin(0.25*pi*(n-16+eps))./(pi*(n-16+eps));%读入hd(n)函数
  23. h1=hd.*wH;%计算h(n)
  24. N=64;
  25. H1=fft(h1,N);%调用子程序计算H(k)
  26. n=0:N-1;w=2*pi/64*n;subplot(2,2,1);
  27. subplot(2,2,2);
  28. plot(w,fftshift(20*log10((abs(H1)))));%画幅度曲线
  29. grid
  30. xlabel('w/rad')
  31. ylabel('20lg|H(jw)|/dB')
  32. title('幅度曲线和相频曲线(n=33)');
  33. n=0:N-1;w=2*pi/64*n;subplot(2,2,1);
  34. subplot(2,2,4);plot(w,fftshift(unwrap(phase(H1))));%画相频曲线
  35. grid
  36. xlabel('w/rad')

第四个是布莱克曼窗

  1. n=0:14
  2. wB=0.42-0.5*cos(2*pi/(14+eps)*n)+0.08*cos(4*pi/(14+eps)*n)
  3. hd=sin(0.25*pi*(n-7+eps))./(pi*(n-7+eps))
  4. h1=hd.*wB
  5. H1=fft(h1,64)
  6. n=0:63
  7. w=2*pi*n/64
  8. subplot(2,2,1)
  9. plot(w,fftshift(20*log10((abs(H1)))))
  10. grid
  11. xlabel('w/rad')
  12. ylabel('20lg|H(jw)|/dB')
  13. title('N=15幅度曲线')
  14. subplot(2,2,3)
  15. plot(w,unwrap(fftshift(phase(H1))))
  16. grid
  17. xlabel('w/rad')
  18. title('N=15相频曲线')
  19. clear all
  20. n=0:32
  21. wB=0.42-0.5*cos(2*pi/(32+eps)*n)+0.08*cos(4*pi/(32+eps)*n)
  22. hd=sin(0.25*pi*(n-16+eps))./(pi*(n-16+eps))
  23. h1=hd.*wB
  24. H1=fft(h1,64)
  25. n=0:63
  26. w=2*pi*n/64
  27. subplot(2,2,2)
  28. plot(w,fftshift(20*log10((abs(H1)))))
  29. grid
  30. xlabel('w/rad')
  31. ylabel('20lg|H(jw)|/dB')
  32. title('N=33幅度曲线')
  33. subplot(2,2,4)
  34. plot(w,unwrap(fftshift(phase(H1))))
  35. grid
  36. xlabel('w/rad')
  37. title('N=33相频曲线')

希望大家结合公式与窗函数特性加上代码,参悟一下。

好了现在我们开始设计FIR滤波器,至于书面的计算过程我就不写了,又不懂得请参考本文“写在前面的话”的第一个链接的内容。

第一个例子,用汉明窗设计一个低通滤波器,Wp=0.2π, Ws=0.4π, Ap=0.25dB, As=50dB

  1. %%%%%Write by Han%%%%%这是实时脚本文件%%%%%
  2. close all;
  3. clc
  4. Wp=0.2*pi;
  5. Ws=0.4*pi;
  6. tr_width=Ws-Wp; %Transition zone width
  7. N=ceil(6.6*pi/tr_width)+1 %Filter length
  8. n=0:1:N-1;
  9. Wc=(Ws+Wp)/2; %Cutoff frequency of ideal low-pass filter
  10. hd = ideal_lp(Wc,N); %Unit impulse response of an ideal low-pass filter
  11. w_ham=0.54-0.46*cos(2*pi*n/(14+eps)); % Writing a haming window
  12. h=hd.*w_ham; %Truncated to the actual unit impulse response
  13. [db,mag,pha,w]=freqz_m4(h,[1]); %Calculate the amplitude response of the actual filter
  14. delta_w=2*pi/1000;
  15. Ap=-(min(db(1:1:Wp/delta_w+1))) %Actual passband ripple
  16. As=-round(max(db(Ws/delta_w+1:1:501))) %Actual stop band ripple
  17. subplot(221)
  18. stem(n,hd) %Matchstick figure
  19. title('Ideal unit impulse response: hd(n)')
  20. subplot(222)
  21. stem(n,w_ham)
  22. title('Hamming window: w(n)')
  23. subplot(223)
  24. stem(n,h)
  25. title('Actual unit impulse response: h(n)')
  26. subplot(224)
  27. plot(w/pi,db)
  28. title('Amplitude response: (dB)')
  29. axis([0,1,-100,10])
  30. %2 Custom functions used by this program
  31. % One is the "freqz_m4.m"
  32. % Another is the "ideal_lp.m"

我在这用了两个自定义函数,所以大家还需要新建两个.m文件,一个是“freqz_m4.m”文件名与函数名需要保持一致。

  1. function[db,mag,pha,w]=freqz_m4(b,a)
  2. [H,w]=freqz(b,a,1000,'whole');
  3. H=(H(1:1:501));
  4. w=(w(1:1:501));
  5. mag=abs(H);
  6. db=20*log10((mag+eps)/max(mag));
  7. pha=angle(H);
  8. end

另一个是“ideal_lp.m”

  1. function hd=ideal_lp(Wc,N)
  2. alpha= (N-1)/2;
  3. n=0:1:N-1;
  4. m=n-alpha+eps;
  5. hd=sin (Wc*m)./(pi*m);
  6. end

注意要把这三个文件保存在一个英文命名的文件夹中,不然MATLAB可能会出现.m文件打不开,或者找不到路径的问题。这个问题可参考(https://blog.csdn.net/Smile_h_ahaha/article/details/92477206)进行修正。代码是没问题的。

然后生成了以下图像:

第二个,我们设计个使用汉宁窗的高通滤波器,设计参数是:Wp=0.6 π,Ws=0.4 π,,Ap=0.25dB,As=40dB

  1. %%%%%%%%%%%%%%% Write by Han %%%%%%%%%这是实时脚本文件%%%%%%%%%%%%
  2. Wp=0.6*pi; Ws=0.4*pi;
  3. tr_width=Wp-Ws; %Transition zone width
  4. N=ceil (6.2*pi/tr_width) +1 %Filter length
  5. n=0:1:N-1;
  6. Wc= (Ws+Wp) /2; %The cut-off frequency of the ideal high-pass filter
  7. hd=ideal_hp2(Wc,N); %Unit impulse response of an ideal high-pass filter
  8. w_han=0.5*(1-cos(2*pi/14*n)); % Writing Hanning window
  9. h=hd.*w_han; %Truncated to the actual unit impulse response
  10. [db,mag,pha,w]=freqz_m4 (h,[1]); %Calculate the amplitude response of the actual filter
  11. delta_w=2*pi/1000;
  12. Ap=-(min(db(Wp/delta_w+1:1:500))) %Actual passband ripple
  13. As=-round(max(db(1:1:Wp/delta_w+1))) %Actual stop band ripple
  14. subplot(221)
  15. stem(n,hd) %Matchstick figure
  16. title('Ideal unit impulse response: hd(n)')
  17. subplot(222)
  18. stem(n,w_han)
  19. title('Hanning: w(n)')
  20. subplot(223)
  21. stem(n,h)
  22. title('Actual unit impulse response: h(n)')
  23. subplot(224)
  24. plot(w/pi,db)
  25. title('FIR digital high-pass filter amplitude response: (dB)')
  26. axis([0,1,-100,10])

这也用到两个自定义函数,

  1. %%%%%%%%%%%%% ideal_hp2.m %%%%%%%%%%%%%
  2. function hd=ideal_hp2(Wc,N)
  3. alpha= (N-1)/2;
  4. n=0:1:N-1;
  5. m=n-alpha+eps;
  6. hd=(sin (pi*m)-sin(Wc*m))./(pi*m);
  7. %%%%%%%%%%%请再新建一个.m文件放以下部分%%%%%
  8. function[db,mag,pha,w]=freqz_m4(b,a)
  9. [H,w]=freqz(b,a,1000,'whole');
  10. H=(H(1:1:501));
  11. w=(w(1:1:501));
  12. mag=abs(H);
  13. db=20*log10((mag+eps)/max(mag));
  14. pha=angle(H);
  15. end

第三个,我们用汉宁窗设计一个bandstop(带阻) FIR滤波器,设计参数是:

  1. %%%%%%%%%%%%%%%%%% Write by Han %%%%%%%%%%这是实时脚本文件%%%%%%%%%%%%
  2. Wpl=0.2*pi; Wph=0.8*pi; Wsl=0.4*pi; Wsh=0.6*pi;
  3. tr_width=min((Wsl-Wpl),(Wph-Wsh));
  4. N=ceil (6.2*pi/tr_width)
  5. n=0:1:N-1;
  6. Wcl= (Wsl+Wpl) /2; %Lower cutoff frequency of ideal band stop filter
  7. Wch= (Wsh+Wph) /2; %Upper cutoff frequency of ideal band stop filter
  8. hd=ideal_bs(Wcl,Wch,N); %Unit impulse response of an ideal band stop filter
  9. w_hann= 0.5*(1-cos(2*pi/14*n)); %Hanning window
  10. h=hd.*w_hann; %Truncated to the actual unit impulse response
  11. [db,mag,pha,w]=freqz_m4 (h,[1]); %Calculate the amplitude response of the actual filter
  12. delta_w=2*pi/1000;
  13. Ap=-(min(db(1:1:Wpl/delta_w+1))) %Actual passband ripple
  14. As=-round(max(db(Wsl/delta_w+1:1:Wsh/delta_w+1))) %Actual stop band ripple
  15. subplot(221)
  16. stem(n,hd) %Matchstick figure
  17. title('Ideal: hd(n)')
  18. subplot(222)
  19. stem(n,w_hann)
  20. title('hanning w(n)')
  21. subplot(223)
  22. stem(n,h)
  23. title('Real h(n)')
  24. subplot(224)
  25. plot(w/pi,db)
  26. title('FIRHanning window digital band rejection filter amplitude response(dB)')
  27. axis([0,1,-100,10])
  28. %%%%%%%%%%%%%%%%%%%%% ideal_bs.m %%%%%%%%新建一个.m文件%%%%%%%%%%%%
  29. function hd=ideal_bs(Wcl,Wch,N)
  30. alpha= (N-1) /2; n=0:1:N-1;
  31. m=n-alpha+eps;
  32. hd=(sin (Wcl*m) + sin(pi*m)-sin(Wch*m) ) ./(pi*m);
  33. end
  34. %%%%%%%%%%%%%%%%%%%%freqz_m4.m%%%%%%新建一个.m文件%%%%%%%%%%%
  35. function[db,mag,pha,w]=freqz_m4(b,a)
  36. [H,w]=freqz(b,a,1000,'whole');
  37. H=(H(1:1:501));
  38. w=(w(1:1:501));
  39. mag=abs(H);
  40. db=20*log10((mag+eps)/max(mag));
  41. pha=angle(H);
  42. end

其他的大家能参悟到这,其他的估计也就触类旁通了吧,学海无涯,兴趣作舟,祝大家好运!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/147544?site
推荐阅读
相关标签
  

闽ICP备14008679号