数字滤波器的matlab与FPGA实现读书笔记(二)FIR滤波器的matlab设计

FIR滤波器的matlab设计
1.采样fir1函数设计
b= fir1(n,wn),
b= fir1(n,wn,’ftype’)
b= fir1(n,wn,’ftype’,window)
b= fir1(…,’noscale’)
函数参数说明
b:返回的FIR滤波器单位脉冲响应,脉冲响应为偶对称,长度为n+1
n:滤波器的阶数,需要注意的是,设计出的滤波器长度为n+1.
wn:滤波器的截至频率,;需要注意的是,wn的取值范围为0< wn<1, 1对应为信号采样频率的1/2;如果wn是个单个数值,且ftype参数为low,则表示设计截止频率为wn的低通滤波器,如ftype,参数为high,则表示设计截止频率为wn的高通滤波器,如果wn是由两个数组成的向量[wn1,wn2],ftype为stop,则表示设计带阻滤波器,ftype为bandpass,则表示设计带通滤波器;如果wn是由多个数组成的向量,则表示根据ftype的值设计多个带通或带阻的滤波器;ftype为DC-1,表示设计的第一个频带为通带,ftype为DC-0,表示设计的第一个频带为阻带。
window:指定使用的窗函数向量,默认为海明窗(Hamming),最常用的窗函数有汉宁窗(Hanning)、海明(Hamming)窗、布拉克曼(Blackman)窗和凯塞(kaiser)窗,可以在MATLAB界面中输入help window命令查询各种窗函数名称。
noscale: 指定是否归一化滤波器的幅度。
2.函数使用方法
例:设计一个归一化截止频率为0.2,阶数为11、采用海明窗的低通滤波器
b= fir1(11,0.2);
plot(20log(abs(fft(b)))/log(10))
例: 分别设计长度为41的低通(截止频率为200HZ)、高通(截止频率为200HZ)、带通(通带为200400HZ)、带阻滤波器(阻带为200400HZ)FIR滤波器采样频率为2000HZ
N = 41; %滤波器长度
fs =2000; %采样频率
%各种滤波器的特征频率
fc_lpf =200;
fc_hpf =200;
fp_bandpass= [200,400];
fc_stop =[200,400];
%以采样频率的一半,对频率进行归一化处理
wn_lpf =fc_lpf
2/fs;
wn_hpf =fc_hpf2/fs;
wn_bandpass= fp_bandpass
2/fs;
wn_stop =fc_stop2/fs;
%采样fir1函数设计FIR滤波器
b_lpf =fir1(N-1,wn_lpf);
b_hpf =fir1(N-1,wn_hpf,‘high’);
b_bandpass= fir1(N-1,wn_bandpass,‘bandpass’);
b_stop =fir1(N-1,wn_stop,‘stop’);
%求滤波器的幅频响应
m_lpf =20
log(abs(fft(b_lpf)))/log(10);
m_hpf =20log(abs(fft(b_hpf)))/log(10);
m_bandpass=20
log(abs(fft(b_bandpass)))/log(10);
m_stop =20log(abs(fft(b_stop)))/log(10);
%设置幅频响应的横坐标单位为HZ
x_f=[0:(fs/length(m_lpf)):fs/2];
%绘制单位脉冲响应
subplot(421);stem(b_lpf);xlabel(‘n’);ylabel(‘h(n)’);
subplot(423);stem(b_hpf);xlabel(‘n’);ylabel(‘h(n)’);
subplot(425);stem(b_bandpass);xlabel(‘n’);ylabel(‘h(n)’);
subplot(427);stem(b_stop);xlabel(‘n’);ylabel(‘h(n)’);
%绘制幅频响应曲线
subplot(422);plot(x_f,m_lpf(1:length(x_f)));xlabel(‘频率(HZ)’,‘fontsize’,8);ylabel(‘幅度(dB)’,‘fontsize’,8);
subplot(424);plot(x_f,m_hpf(1:length(x_f)));xlabel(‘频率(HZ)’,‘fontsize’,8);ylabel(‘幅度(dB)’,‘fontsize’,8);
subplot(426);plot(x_f,m_bandpass(1:length(x_f)));xlabel(‘频率(HZ)’,‘fontsize’,8);ylabel(‘幅度(dB)’,‘fontsize’,8);
subplot(428);plot(x_f,m_stop(1:length(x_f)));xlabel(‘频率(HZ)’,‘fontsize’,8);ylabel(‘幅度(dB)’,‘fontsize’,8);在这里插入图片描述
例:采样各种窗函数,利用MATLAB软件分别设计截止频率为200HZ、采样频率为2000HZ的FIR低通滤波器,滤波器长度为81
N = 81; %滤波器长度
fs =2000; %采样频率
fc = 200; %低通滤波器的截止频率
%生成各种窗含数
w_rect =rectwin(N)’;
w_hann =hann(N)’;
w_hamm =hamming(N)’;
w_blac =blackman(N)’;
w_kais =kaiser(N,7.856)’;
%采用fir1函数设计FIR滤波器
b_rect =fir1(N -1 ,fc
2/fs,w_rect);
b_hann =fir1(N -1 ,fc2/fs, w_hann);
b_hamm =fir1(N -1 ,fc
2/fs, w_hamm);
b_blac =fir1(N -1 ,fc2/fs, w_blac);
b_kais =fir1(N -1 ,fc
2/fs, w_kais);
%求滤波器的幅频响应
m_rect =20log(abs(fft(b_rect,512)))/log(10);
m_hann =20
log(abs(fft(b_hann,512)))/log(10);
m_hamm =20log(abs(fft(b_hamm,512)))/log(10);
m_blac =20
log(abs(fft(b_blac,512)))/log(10);
m_kais =20log(abs(fft(b_kais,512)))/log(10);
%设置幅频响应的坐标单位为HZ
x_f =[0:(fs/length(m_rect)):fs/2];
%只显示正频率部分的幅频响应
m1 =m_rect(1:length(x_f));
m2 =m_hann (1:length(x_f));
m3 =m_hamm (1:length(x_f));
m4 =m_blac (1:length(x_f));
m5 =m_kais (1:length(x_f));
%绘制幅频响应曲线
plot(x_f,m1,’.’,x_f,m2,’
’,x_f,m3,‘x’,x_f,m4,’–’,x_f,m5,’-’);
xlabel(‘频率(Hz)’,‘fontsize’,8);ylabel(‘幅度(dB)’,‘fontsize’,8);
legend(‘矩形窗’,‘汉宁窗’,‘海明窗’,‘布拉克窗’,‘凯塞窗’);
grid;
五种窗函数对比
二、采用kaiserord函数设计
语法形式
[n,wn,beta,filtype]=kaiserord(f,a,dev,fs)
参数说明
f及fs:如果f是一个向量,其中的元素为待设计滤波器的过渡带的起始点和结束点;
如果没有fs参数,f中元素的取值范围为0~ 1,即相对于采样频率一半的归一化频率;有fs参数,则fs为信号采样频率,f中元素即为实际的截至频率。例如需要设计滤波器的过滤带宽为1000~ 1200Hz、2000~2100Hz;信号采样频率为8000Hz;如没有设置fs参数,则f=[0.25 0.3 0.5 0.525];如设置fs为8000,则f=[1000 1200 2000 2100]。
a:a是一个向量,参数f确定了待设计滤波器的过渡带,向量a用于指定这些频率段的理想幅度值;a的第一个参数a1对应为f中的0f1频段,第二个参数a2对应f中的f2f3频段,后续对应关系一次类推。比如,对于上面讲述f及fs参数的例子,设置a=[1 0 1],则表示需要设计的带阻滤波器。可以看出,由f及a可以表示滤波器的类型。
dev: dev是一个向量,用于指定通带或阻带内的容许误差。同样的是上述例子,需求通带容许误差为0.01,阻带容许误差为0.02,则dev=[0.01 0.02 0.01]。
n: 返回值n为kaiserord函数根据滤波器要求,得到满足设计的最小阶数。
wn:返回值wn是一个向量,kaiserord函数计算得到的滤波器截止频率点。
beta:返回值beta是根据滤波器要求,kaiserord函数计算得到的β值。
ftype:返回值ftype是根据设计要求获得的滤波器类型参数。
三、采用fir2函数设计
任意响应滤波器:滤波器的幅度频率响应在指定的频段范围内有不同的幅值,如在00.1的理想幅值为一,在0.20.4频段内的幅值为0.5,在0.6~0.7频段的幅值为1等。fir2H函数的算法是:根据要求的幅频响应的向量形式进行插值,而后进行傅里叶变换得到理想滤波器的单位脉冲响应,最后利用窗函数对理想滤波器的单位脉冲响应进行截短处理,fir2函数的6种语法形式如下。
b=fir2(n,f,m);
b=fir2(n,f,m,window);
b=fir2(n,f,m,npt);
b=fir2(n,f,m,npt,window);
b=fir2(n,f,m,npt,lap);
b=fir2(n,f,m, npt,lap ,window);
n及b:滤波器的阶数,与fir1函数类似,返回值b为滤波器系数,其长度为n+1。
同时,根据FIR滤波器的结构特点,当设计的滤波器在归一化频率为1处的幅度值不为0时,n不能为奇数。
f及m: f是一个向量,取值为01之间。对于为滤波器的归一化频率;m是长度与f相同的向量,用于设置对应频率范围内的理想幅值。例如,要求设计的滤波器在00.125范围内幅度为1,在0.1250.25范围内幅度为0.5,在0.250.5范围内幅度为0.25,在0.5~1范围内幅度为0.125,则f可以表示为[0 0.125 0.125 0.25 0.25 0.5 0.5 1],m可以表示为[1 1 0.5 0.5 0.25 0.25 0.125 0.125]。
window: window是一个向量,用于指定窗函数的种类,其长度为滤波器长度n+1,当没有指定窗函数时,默认为海明窗。
npt: npt 是一个正整数,用于指定在对幅度响应进行插值时的插值点个数,其默认值为512。
lap:lap是一个正整数,用于指定对幅度响应进行插值时,对于不连续点转变成连续时的点数,其默认值为25
例:利用fir2函数设计120阶的FIR滤波器,要求设计的滤波器在归一化频率0~ 0.125范围内幅度为1,在0.125~ 0.25范围内幅度为0.5,在0.25~ 0.5范围内幅度为0.25,在0.5~1范围内幅度为0.125.
N=120; %滤波器阶数
fc=[0 0.125 0.125 0.25 0.25 0.5 0.5 1]; %截至频率
mag =[1 1 0.5 0.5 0.25 0.25 0.125 0.125];%理想滤波器幅度
b=fir2(N,fc,mag); %设计海明窗滤波器
freqz(b); %绘制频率响应曲线在这里插入图片描述
三、采用firpm函数设计
firpm函数的语法形式
b=firpm(n,f,a);
b=firpm(n,f,a,w);
b=firpm(n,f,a,’ftype’);
b=firpm(n,f,a,w,’ftype’);
[b,delta]=firpm(…)
参数说明
n及b:滤波器的阶数,与fir1函数类似,返回值b为滤波器系数,其长度为n+1.
f及a:f是一个向量,取值为0~1之间,对应为滤波器的归一化频率;a是长度与f相同的向量,用于设置对应频段范围内的理想幅值。
w:w是长度为f的1/2的向量,表示设计滤波器时,实现对应频率幅度值得权值。
用下标表示向量的元素,则w0对应的是f0f1频段,w1对应的是f2f3频段,以此类推。权值越高,则实现时对应频段的幅值越接近理想状态。
ftype:ftype用于指定滤波器的结构类型,如没有设置参数,则表示设计偶对称脉冲响应的滤波器;如设置为“hilbert”,则表示设计奇对称结构的滤波器,即具有90°相移特性;如设置为“differentiator”,则表示设计奇对称结构的滤波器,且设计时针对非零幅度的频带进行了加权处理,使滤波器的频带越低,则幅值误差越小。
delta:delta为返回的滤波器的最大纹波值。
例:利用凯塞窗函数设计一个低通FIR滤波器,过渡带为1000~1500Hz,采样频率为8000Hz,通带纹波最大为0.01,阻带纹波最大为0.05,利用海明窗及firpm函数设计相同的低通滤波器,截至频率为1500Hz,滤波器阶数为凯塞窗函数求取的值。绘出三种方法设计的幅度频率的响应曲线
fs = 8000; %采样频率
fc=[1000 1500 ]; %过渡带
mag= [1 0]; %窗函数的理想滤波器幅度
dev = [0.01 0.05]; %纹波
[n,wn,beta,ftype]= kaiserord(fc,mag,dev,fs) %获取凯塞窗函数参数
fpm = [0 fc(1)2/fs fc(2)2/fs 1]; %firpm函数的频段向量
magpm=[1 1 0 0]; %firpm函数的幅值向量
%设计凯塞窗及海明窗滤波器
h_kaiser =fir1(n,wn,ftype,kaiser(n+1,beta));
h_hamm = fir1(n,fc(2)2/fs);
%设计最优滤波器
h_pm=firpm(n,fpm,magpm);
%求滤波器的幅频响应
m_kaiser =20
log(abs(fft(h_kaiser,1024)))/log(10);
m_hamm =20
log(abs(fft(h_hamm,1024)))/log(10);
m_pm =20
log(abs(fft(h_pm,1024)))/log(10);
%设置幅频响应的横坐标单位为Hz
x_f =[0:(fs/length(m_kaiser)):fs/2];
%只显示正频率部分的幅频响应
m1 =m_kaiser(1:length(x_f));
m2 =m_hamm(1:length(x_f));
m3 =m_pm(1:length(x_f));
%绘制幅频响应曲线
plot(x_f,m1,’-’,x_f,m2,’-.’,x_f,m3,’–’);
xlabel(‘频率(Hz)’);ylabel(‘幅度(dB)’);
legend(‘凯塞窗’,‘海明窗’,‘最优滤波器’);grid;
从图中可以看出使用kaiserord函数获得滤波器的阶数为36,截至频率为0.3125,凯塞窗的β值为3.3953从幅频响应曲线可以看出,最优滤波器与凯塞窗滤波器相比,最优滤波器的第一瓣电平约低2.5dB,且阻带纹波相同,而凯塞窗的阻带纹波却逐渐减小。
在这里插入图片描述
四、采用FDATOOL工具设计
例:利用FDATOOL工具设计设计一个带通FIR滤波器,带通范围为1000~ 2000Hz,低频过渡带为700~ 1000Hz,高频过渡带为2000~2300Hz,采样频率为8000Hz的等阻带纹波滤波器要求阻带衰减大与60dB。
启动MATLAB软件后,依次单击主界面左下方的“start→Toolboxes→Filter Design→Filter Design&Analysis Tool”即可打开FDATOOL工具界面
1.首先单击FDATOOL界面左下方的滤波器设计(Design filter)按键图标,进入滤波器设计界面。
2. 单击FDATOOL界面上方工具栏上的滤波器参数设置(Filter Specifications)工具,进入滤波器参数设置界面。
3. 单击滤波器响应类型(Response Type)部分的带通滤波器(Bandpass)选项,指定设计带通滤波器。
4. 在设计方法(Design Method)部分的FIR下拉列表框中,选择等纹波(Equiripple)
设计方法。需要注意的是,由4.2节可知,除了凯塞窗可以通过调整β参数来改变滤波器阻带衰减外,其他窗函数的阻带衰减是无法调整的,增加滤波器阶数只能改变滤波器的过渡带性能。最优滤波器设计方法(等纹波滤波器)可通过增加滤波器阶数改善阻带衰减性能。
5. 根据设计要求,设置滤波器截至频率。
6. 设置滤波器阶数(Specify order)参数后,单击FDATOOL界面下方的“Design Filter”按键开始滤波器设计。
7. 观察FDATOOL中的频率响应,调整滤波器阶数,直到满足设计要求。
通过单击“Analysis→Filter→Coefficients”菜单来察看滤波器系数,或通过单击“Targets→XILINX Coefficient(.COE) File”菜单直接生成FPGA所需的滤波器系数配置文件。

ex:设计一个高通最优FIR滤波器,过渡带为1000~1500Hz,采样频率为8000Hz,通带纹波最大为0.01,阻带纹波最大为0.001绘制比较系数12位、14位量化以及无量化是的幅度响应曲线,将14位量化结果转换成十六进制补码格式,并将14位量化的十进制存放在文本文件中。
设计一个对纹波及截至频率有确定要求的滤波器,需要使用firpm函数设计最优滤波器。而firpm函数无法确定滤波器的阶数,因此需要使用kaiserord函数先求取满足设计需求的最小滤波器阶数。
function
hn=fir_1;
fs = 8000; %采样频率
fc = [1000 1500]; %过渡带
mag = [0 1]; %窗函数的理想滤波器幅度
dev = [0.001 0.01]; %纹波
[n,wn,beta,ftype] =kaiserord(fc,mag,dev,fs); %获取凯塞窗函数参数
fpm = [0 fc(1)2/fs fc(2)2/fs 1]; %firpm函数的频段向量
magpm = [0 0 1 1]; %firpm函数的幅值向量
%设计最优滤波器
h_pm = firpm(n,fpm,magpm);
%滤波器系数进行量化
h_pm12 = round(h_pm/max(abs(h_pm))
(2^11-1));
h_pm14 = round(h_pm/max(abs(h_pm))
(2^13-1));
hn=h_pm14;
%转换进制
q14_hex_pm =dec2hex(h_pm14+2^14*(h_pm14<0));
%将生成的滤波器系数写入FPGA所需的文件中
fid=fopen(‘f:\lbq\fir_1.txt’,‘w’);
fprintf(fid,’%8d\r\n’,h_pm);
fprintf(fid,’;’);
fclose(fid);
%求滤波器的幅频响应
m_pm = 20log(abs(fft(h_pm,1024)))/log(10);
m_pm = m_pm-max(m_pm);
m_pm12 =20
log(abs(fft(h_pm12,1024)))/log(10);
m_pm12 = m_pm12-max(m_pm12);
m_pm14 =20*log(abs(fft(h_pm14,1024)))/log(10);
m_pm14 = m_pm14-max(m_pm14);
%设置幅频响应的横坐标单位为Hz
x_f= [0:(fs/length(m_pm)):fs/2];
%只显示正频率部分的幅频响应
mf_pm = m_pm(1:length(x_f));
mf_pm12 = m_pm12(1:length(x_f));
mf_pm14 = m_pm14(1:length(x_f));
%绘制幅频响应曲线
plot(x_f,mf_pm,’-’,x_f,mf_pm12,’-.’,x_f,mf_pm14,’–’);
xlabel(‘频率(Hz)’);
ylabel(‘幅度(dB)’);
legend(‘未量化’,‘12位量化’,‘14位量化’);
grid;
matlab 运行结果如图在这里插入图片描述

发布了3 篇原创文章 · 获赞 3 · 访问量 124

猜你喜欢

转载自blog.csdn.net/weixin_43603526/article/details/104722786