FIR滤波器设计-FPGA附带源码

发布时间:2018-11-14 10:07    发布者:luckyb1
1      项目背景 (源码下载,至简设计法辅导交流群:5444538371.1 FIR和IIR滤波器
      FIR(Finite Impulse Response)Filter:有限冲激响应滤波器,又称为非递归线性滤波器。
      FIR滤波器,顾名思义,其脉冲响应由有限个采样值构成。长度(抽头数)为N、阶数为N−1的FIR系统的转移函数、差分方程和单位冲激响应分别如下列三式所示。


      IIR(Infinite Impulse Response)Filter:无限冲激响应滤波器,又称为递归线性滤波器。
      FIR相对与IIR来说,具有如下的优点:
Ø  可以具备线性相位特性
      线性相位的概念:如果滤波器的N个实值系数为对称或者反对称结构,该滤波器具有线性相位。        W(n)=±W(N−1−n)W(n)=±W(N−1−n)
线性相位的特性:通过线性相位滤波器的信号的所有频率部分具有相同的延迟量。

Ø  易于设计
但FIR也有自身的缺点:同样指标的滤波器,FIR需要更多的参数,即实现时消耗更多的计算单元,产生更大的延迟。

1.2   FIR滤波器的原理
      信号通过一个FIR滤波器其实就是信号与FIR滤波器的系数进行卷积(即乘累加)的过程。我们以一个简单信号模型为例,了解一下FIR波形器的原理。
     现在有三组信号,分别是:
     信号1:低频信号,即在时域上变化慢的信号,其输入先后为1 1 1 1 2 2 2 2。
     信号2:直流信号,其输入先后为1 1 1 1 1 1 1 。
    信号3:高频信号,即在时域上变化快的信号,其输入先后为1 2 1 2 1 2 1 2 。
     简单的滤波器模型
     低通滤波器:1 1
     信号1与低通滤波器进行卷积运算,其结果再除以2,得到如下数据:1 1 1 1.5 2 2 2。可以看到,低频信号经过低通滤波器后,各个点仍然保持了其形状,而且在1变成2时,还变平缓了。
     信号2与低通滤波器进行卷积运算,其结果再除以2,得到如下数据:1 1 1 1 1 1 1。可以看到,直流信号与输入的信号完成相同。
信号3与低通滤波器进行卷积运算,其结果再除以2,得到如下数据:1.5 1.5 1.5 1.51.5 1.5 1.5。可以看到,高频信号经过低通滤波器后,已经完成消去了形状,变成了直流信号。
      再考虑另一种滤波器模型,高通滤波器:1 -1
     信号1与高通滤波器进行卷积运算,其结果再除以2,得到如下数据:0 0 0 -0.5 0 0 0。可以看到,低频信号经过高通滤波器后,信号变化基本上消失。
     信号2与低通滤波器进行卷积运算,其结果再除以2,得到如下数据:0 0 0 0 0 0 0。可以看到,直流信号仍然是没有变化。
     信号3与低通滤波器进行卷积运算,其结果再除以2,得到如下数据:-0.5 0.5 -0.5 0.5-0.5 0.5 -0.5 0.5。可以看到,高频信号已经仍然保持了变化的形状。
由这两个例子可以看出,FIR滤波器其实就是信号与FIR滤波器的系数进行卷积(即乘累加)的过程。通过调整滤波器系数、抽头个数,就可实现低通、高通、带通等滤波器。
1.3    FIR滤波器的设计1.3.1  matlab产生滤波器系数
     打开matlab在其命令窗口输入fdatool 按下回车


     调出FIR滤波器的设计界面。


      在波形设计界面中,我们重要关注以下选项。
      Response Type:选择可以选择滤波器的类型,可选择:lowpass低通滤波器、Highpass高通滤波器、bandpass带通滤波器、bandstop带阻滤波器。
     Fs(采样频率):
      Fstop :信号截止频率
     Fpass:
     Filter Order:用来设置滤波器的抽头个数。可以在specify order中输入个数,也可以选择Minimumorder,让系统计算满足要求的前提下的最小抽头个数。
     点击Design Filter,就可以计算出抽头系数。
     产生系数后点击file 菜单里的Export 将系数保存到工作区


点击export


      点击之后打开工作区里的Num。


    而后将下图第一列的数据复制粘贴到txt文件中。


注意复制后需在两个系数间插入逗号(英文输入状态下的的逗号)。


这样就得到滤波器的系数了。
1.3.2FPGA生成FIR IP核
     打开工程后,在IP catalog这一界面中选择DSP下一目录中选择Filter 在选择选择 FIR II


     首先在Fitter这一界面做如下操作


     Filter Type
    Interpolation Factor:
    Decimation Factor:
    Max Number of channels:

    Clock rate:填写本IP核的工作时钟频率。
     clock slack:
     Input sample rate (msps):采样率
     点击coefficients,进入coefficients界面。
     这一界面点击import from file ,弹出一下界面,找出我们之前用matlab生成的系数文件,点击import,导入成功后可以看到下图的 frequency response界面的波形发生变化


     在coefficient界面,还可以设置系数的格式、数据位宽等。


      其它选项不改按默认的来点击finish即可。
     以上就是生成 FIR滤波器的主要步骤。

2    设计目标
     本次案例将使用到采样率大于100M的双通道的示波器。将示波器的两个通道,分别与FPGA的DA通道1和DA通道2相连,观察两路DA的输出。其连接示意如下图所示。


     本案例是FPGA内部产生正弦信号,这个正弦信号一路输出给DA通道1,另一路经过FIR滤波器后,输出给DA通道2。


      正弦信号的频率受开发板上的3个拨码开关控制,用3位信号key表示,一共可以产生8种频率。
     正弦信号的频率 约等于: 100KHz * (key+1)。
     例如,当key等于0时,产生约100KHz的正弦信号;
    当key等于1时,产生约200KHz的正弦波;
     当key等于7时,产生约800KHz的正弦波。
      FIR滤波器是低通滤波器,其截止频率是500KHz,这样原则上超过500KHz的信号就会被滤除。滤波器的输出给通道2。
     下面是示波器的显示效果,其中黄色是通道1输出的信号(上面的波形),下面蓝色是通道2的输出信号(下面的波形)。
     下图是100KHz的信号图。


下图是200KHz的信号图。


下图是300KHz的信号图。


下图是400KHz的信号图,可以看到已经衰减了。


       下图是500KHz的信号图,可以看到已经衰减的很小了。


       下图是600KHz的信号图,可以看到通道2已经没有波形。


     下图是700KHz的信号图,可以看到通道2已经没有波形。下图是800KHz的信号图,可以看到通道2已经没有波形。


下图是800KHz的信号图,可以看到通道2已经没有波形。


3  设计实现3.1 顶层接口
      新建目录:D:\mdy_book\fir_prj。在该目录中,新建一个名为fir_prj.v的文件,并用GVIM打开,开始编写代码。
     我们要实现的功能,概括起来就是FPGA产生控制AD9709,让其中的通道A未滤波的正弦信号,让通道B输出滤波后的正弦信号。为了控制AD9709的工作模式,就要控制AD9709的MODE、SLEEP管脚;为了控制通道A,就需要控制AD9729的CLK1、WRT1、DB7~0P1管脚;为了控制通道B,就需要控制AD9729的CLK2、WRT2、DB7~0P2管脚。根据设计目标的要求,整个工程需要以下信号:
1.       使用clk连接到晶振,表示50M时钟的输入。
2.       使用rst_n连接到按键,表示复位信号。
3.       使用3位信号key,表示三位拨码开关。
4.       使用dac_mode信号连接到AD9709的MODE管脚,用来控制其工作模式。
5.       使用dac_sleep信号连接到AD9709的SLEEP管脚,用来控制其睡眠模式。
6.       使用dac_clka信号连接到AD9709的CLK1管脚,用来控制通道A的时钟。
7.       使用dac_wra信号连接到AD9709的WRT1管脚,用来控制通道A的写使能。
8.       使用8位信号dac_da连接到AD9709的DB7~0P1管脚,用来控制通道A的写数据。
9.       使用dac_clkb号连接到AD9709的CLK2脚,用来控制通道B时钟。
10.    使用dac_wrb号连接到AD9709的WRT2脚,用来控制通道B使能。
11.    使用8位信号dac_db接到AD9709的DB7~0P2脚,用来控制通道B写数据。

      综上所述,我们这个工程需要11个信号,时钟clk,复位rst_n,拨码开关的输入key,dac_mode、dac_sleep、dac_clka、dac_wra、dac_da、dac_clkb、dac_wrb和dac_db信号,其中dac_da和dac_db是8位信号,其他都是1位信号。下面表格表示了硬件电路图的连接关系。


将module的名称定义为fir_prj,代码如下:


      其中clk、rst_n是1位的输入信号,dac_da和dac_db是8位的输出信号,key是3位输入信号,dac_mode,dac_clka,dac_wra,dac_sleep,dac_clkb,dac_wrb是一位输出信号。


3.2    正弦信号设计
     假设产生的正弦信号命名为sin_data信号。sin_data是从表XX中选择出来的值,该表一共有128个点。该表的产生方法,请看案例“信号发生器和DA转换”一章的内容。


      很自然地定义一个7位的选择信号addr。我们只要控制好addr,就能方便得到sin_data。因此可以写出下面代码。















本文地址:https://www.eechina.com/thread-549976-1-1.html     【打印本页】

本站部分文章为转载或网友发布,目的在于传递和分享信息,并不代表本网赞同其观点和对其真实性负责;文章版权归原作者及原出处所有,如涉及作品内容、版权和其它问题,我们将根据著作权人的要求,第一时间更正或删除。
您需要登录后才可以发表评论 登录 | 立即注册

厂商推荐

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表