广告

原创 第三章 3.2——FIR滤波器的FPGA实现(1)

2017-9-9 20:26 723 0 分类: FPGA/CPLD




 一、数字滤波器的背景  

   数字滤波器是从信号中提取用户需要的信息,滤除不需要的干扰成分,根据信号与干扰的不同关系,可以从时域、频域或者变换域进行信号滤波设计。

   频域滤波就是要提取或者抑制所分析信号中某些频带的信号成分,比如电话网络DTMF(Dual Tone Multi-Frequence)码的识别。电话机的每个按键,使用一个高频正弦波和低频正弦波,两者叠加后组成一个DTMF码。在接收端设计一系列带通滤波器,检测各种频率正弦波有无,并且根据正弦波的频率识别DTMF码。进行频域滤波设计时,要求信号和被滤除的信号在频域具有可区分性,当二者的频带相互重叠时,就不可能从频域设计得到需要的信号。

    时域滤波主要是根据信号和噪声之间的统计特性差异完成滤波的。在观测信号的过程中,真实的信号往往受到加性噪声的干扰,由于噪声的频谱很宽,所以信号和噪声的频谱会产生重叠。当信噪比低时,信号的频谱会被噪声的频谱淹没。时域滤波一般基于最小二乘法(波形估计),按照不同的功能又可以分为线性平滑、线性预测和维纳滤波。

若信号没有受到时域加性噪声的影响,也会因为其他各种原因产生失真,最常见的是乘积性失真和卷积性失真。从失真信号中滤出真实信号的过程称为同态滤波,在同态滤波中,一般需要完成解卷积和解乘积运算。

    时域滤波属于经典数字滤波范畴,其余两种属于现代滤波器范畴。在频域滤波中,除了线性滤波外,还有非线性数字滤波以及多维滤波。


二、数字滤波器的数学模型

      

线性时不变数字滤波器的数学模型在时域中可以用线性常系数差分方程描述。

它的Z域传递函数为:




    当 d(k)值不全为0时,该滤波器的Z域系统函数至少包含一个极点,此时相应的单位脉冲必定为无限长,称为无限冲激响应数字滤波器(Infinite Impulse Response,IIR)。对一个稳定的数字系统,极点必须都在单位圆内部。

   当d(k)值全为0时,Z域的系统函数只有零点,滤波器的单位脉冲响应有限,称为有限冲激响应滤波器(Finite Impulse Response,FIR)。







    线性经典数字滤波器按照幅频特性可以分为低通、高通、带通、带阻滤波器。理想的滤波器只有通带和阻带之分,通带和阻带之间的幅频响应产生突变,其单位响应是非因果的,是物理不可实现的。为了得到稳定可实现的滤波器,实际滤波器的频谱往往由通带、阻带和过渡带组成,且通带和阻带内亦有纹波。

    除通带和阻带衰减指标外,过渡带的带宽和纹波是设计滤波器的重要频谱因素。在设计滤波器时,一般只需要考虑幅频响应,只有一些特殊的场合才对相频特性有严格的要求,此时主要是希望滤波器具有线性相位,即不同频率成分的信号经过滤波器的延时相同。对于IIR和FIR滤波器来讲,只有FIR具有线性相位,但是阻带衰减效率差;IIR相位特性差,但是阻带衰减效率高。为了得到稳定可实现的滤波器,实际滤波器的频谱响应往往由通带、阻带和过渡带组成,且通带和阻带也有纹波。


三、FIR数字滤波器的设计

  有限脉冲响应滤波器(FIR)由有限个采样值组成,在每个采样值时刻完成有限个卷积运算,可以将其幅度特性设计成多种多样,同时还可确保精确严格的相位特性。在高阶的滤波器中,还可以通过FFT来计算卷积,从而极大地提高运算效率。


1、FIR原理

      FIR滤波器只存在N个抽头h(n)N也称为滤波器的阶数,则滤波器的输出可以通过卷积的形式表示





通过 Z 变换:




   可以看出,FIR滤波器只在原点处存在极点,这使得FIR具有全局稳定性。FIR滤波器是由一个“抽头延迟线”加法器和乘法器的集合构成的,每一个乘法器的操作系数就是一个FIR系数。因此,也被人们称为“抽头延迟线”结构。FIR滤波器的一个重要特性就是具有线性相位,即系统的相移和频率成比例,可达到无失真传输。

    FIR滤波器可以用方框图的形式方便地表示。用方框图表示可以有以下几个好处:可通过观察法容易地写出算法,通过调整框图得到不同算法的等效框图,可以容易地确定硬件的需求;此外,还可以从传输函数所生成的框图直接得到多种等效表示。直接形式的方框图表示:



   利用转置定理,可以将直接型转化为其等效的转置式FIR滤波器,其结构如下图所示。转置FIR的优点在于不需要给x(n)提供额外的移位寄存器,而且也没有必要为达到高速处理给乘积的加法器添加额外的流水线。


2.FIR滤波器的设计方法

      在matlab信号处理工具箱中,matlab提供了几个子程序来实现上面的窗函数,同时还提供了两个基于窗函数的FIR数字滤波器设计函数b=fir1(n,Wn,options) 和 b=fir2(n,Wn,options)。前者多用于标准通带FIR滤波器的设计,后者多用于设计多带FIR滤波器。两者可以设计高通、低通、带通等多种FIR滤波器。

(1)fir1函数(可以设计标准的加窗线性相位的FIR)

功能:设计标准频率响应的基于窗函数的FIR滤波器

语法:b=fir1(n,Wn); b=fir1(n,Wn,’ftype’); b=fir1(n,Wn,window); b=fir1(n,Wn,’ftype’,window);

b=fir1(…,’normalization’);

参数说明:

<1>n:滤波器阶数;

<2>Wn:通带带宽。在设计低通、高通时,Wn为一个小数,(取值【0,1】),Wn=1相当于0.5fs,在带通和带阻时,Wn为【0,1】之内的一个区间段【W1,W2】;

<3>‘ftype’: 用于设计高通和带阻滤波器。ftype=high时,设计高通滤波器;ftype=stop,设计带阻FIR滤波器。在设计高通和带阻时,要求阶数为偶数。因为阶数为奇数时,它的奈奎斯特频率处的频率响应为0。

<4>Window: 用来指定滤波器的窗函数,以向量形式表示。向量window 的长度必须n+1,若缺省,默认为汉明窗。

<5>‘normalization’:用于选择滤波器的幅度是否归一化。


例、设计一60阶FIR滤波器,通带带宽w=0.35


b = fir1(60,0.35);
freqz(b,1,512);





  

(2)fir2函数

功能:设计任意频率响应的基于频率抽样法的FIR滤波器

语法: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)

说明:fir2函数可以用于设计具有任意频率响应的加窗FIR滤波器,可以设计标准的低通、高通、带通和带阻滤波器。它的频域主要由参数f和m决定。

参数说明:

n:滤波器的阶数;

f:频率点矢量,且f取值【0,1】,矢量f按照升序排列;

m:幅度矢量,包含了与f相对应的期望得到的滤波器幅度;

window:用来指定滤波器的窗函数,其默认为汉明窗;

lap:指定fir2在重复频率点附近插入的区域大小。


例、设计一个30阶的低通滤波器,通带带宽w=0.6

f=[0 0.6 0.6 1];
m=[1 1 0 0];
b=fir2(30,f,m);
freqz(b,1,128);


(3)利用FDATool设计滤波器

例、设计一个采样率为61.44MHz的低通滤波器,其通带带宽为10MHz,阻带带宽为12.5MHz。通带内波纹抖动为1dB,阻带下降80dB,并将其系数量化为16bit后保存到coe文件。

1)在matlab的命令窗口输入 fdatool,弹出工具的配置界面。按下图配置。



从中可以看出,滤波器的阶数是62,则对应着63个抽头系数

(2)提取系数。选择FDATool工具File菜单中的Export命令,各项参数保持默认。确定后,可以在变量空间看到1X63的Num变量,接下来需要将其定点量化,并另存为变量coeff。

在matlab中输入以下语句:

coeff=round(Num / max(abs(Num))*32767 )



(3)保存系数到硬盘文件中。继续在Matlab命令行输入以下语句

fid=fopen('g:/fircoe.coe','wt');
 fprintf(fid,'%.0f,\n',coeff);
 fclose(fid);

(4)生成COE文件。在coe文件最后的逗号换成分号。在文件最开始添加下面两行:

radix=10;

coefdata=

(5)验证COE文件。FDATool 提供了加载Xilinx COE系数文件的功能,可以从幅频响应曲线验证COE文件内部是否正确。单击File 菜单下的Import Filter From Xilinx Coefficient File 命令,选择上一步生成的COE文件,


可得幅频曲线如图。

广告

文章评论 0条评论)

登录后参与讨论
相关推荐阅读
LoneSurvivor 2018-02-25 08:26
C++输入/输出流(2)
1. get()函数#include<iostream>using namespace std;int main(){    char s1[80], s2[...
LoneSurvivor 2018-02-23 12:19
C++输入/输出流(1)
1. 输入/输出流类层次 C++的输入/输出流类库是用派生方法建立起的,它有2个平行的基类,streambuf和ios。其他的流类都是从这两个基类直接或间接派生的。1.1  ...
LoneSurvivor 2018-02-19 11:36
C++多态(4)——特殊运算符重载和类类型转换
1.“++”和“--”的重载     运算符“++”和“--”的重载要区分前置和后置两种形式。如果不区分前置和后置,则使用operator++()或operator—()即可...
LoneSurvivor 2018-02-12 11:15
C++多态(3)——运算符重载
1.     运算符重载的定义     运算符重载也是实现多态的一个重要手段。运算符重载实现的是编译时的多态,即静态多态性。C++预...
LoneSurvivor 2018-02-12 10:31
C++多态(2)——纯虚函数与抽象类
   抽象类是一种特殊的类,它提供了统一的操作界面。建立抽象类是为了多态地使用抽象类的成员函数。抽象类是包含纯虚函数的类。 1.    ...
LoneSurvivor 2018-02-11 16:24
C++多态(1)
1.     多态      多态是人类思维方式的一种直接模拟,多态性是指不同对象接收到相同的消息时,根据对象类的不同而产...
我要评论
0
0
广告
关闭 热点推荐上一条 /2 下一条