1基于DSP的FIR数字滤波器(设计实验)一、实验目的1.了解FIR(FiniteImpulseResponse有限冲激响应)滤波器的原理及使用方法;2.了解使用MATLAT语言设计FIR滤波器的方法;3.了解DSP对FIR滤波器的设计及编程方法;4.熟悉在CCS环境下对FIR滤波器的调试方法;二、实验原理数字滤波是DSP的最基本应用,利用MAC(乘、累加)指令和循环寻址可以方便地完成滤波运算。两种常用的数字滤波器:FIR(有限冲激响应)滤波器和IIR(无限冲激响应)滤波器的DSP实现。设FIR滤波器的系数为h(0),h(1),...,h(N-1),X(n)表示滤波器在n时刻的输入,则n时刻的输出为:FIR数字滤波器的结构如图3.1所示。图3.1FIR数字滤波器的结构图1、线性缓冲区法又称延迟线法。其方法是:对于n=N的FIR滤波器,在数据存储器中开辟一个N单元的缓冲区,存放最新的N个样本;滤波时从最老的样本开始,每读一个样本后,将此样本向下移位;读完最后一个样本后,输入最新样本至缓冲区的顶部。以上过程,可以用N=6的线性缓冲区示意图来说明,如图3-2所示图3-2N=6的线性缓冲区示意图2、循环缓冲区法图3-3说明了使用循环寻址实现FIR滤波器的方法。对于N级FIR滤波器,在数据存储区开辟一个称为滑窗的具有N个单元的缓冲区,滑窗中存放最新的N个输入样本值。每次输入新的样本时,新的样本将改写滑窗中最老的数据,其他数据则不需要移动。10()()()(0)()(1)(1)(1)[(1)]NiynhixnihxnhxnhNxnNx(n)Z-1Z-1Z-1h(0)h(1)h(2)h(N-2)h(N-1)y(n)2图3-3FIR滤波器循环缓冲区存储器图三、实验内容与步骤设计一个FIR低通滤波器,通带边界频率为1500Hz,通带波纹小于1dB;阻带边界频率为2000Hz,阻带衰减大于40dB;采样频率为8000Hz。FIR滤波器的设计可以用MATLAB窗函数法进行。本实验设计一个采样频率Fs为8000Hz,输入信号频率为1000Hz和2500Hz的合成信号,通过设计的低通滤波器将2500Hz信号滤掉,余下1000Hz信号。1、MATLAB设计FIR滤波器FIR滤波器的设计可以用MATLAB窗函数法进行,选择Hamming窗,其程序为:b=fir1(16,1500/8000*2);得到FIR数字滤波器系数b为:b0=0.00000000b9=0.28342322b1=0.00482584b10=0.09725365b2=0.00804504b11=-0.02903702b3=-0.00885584b12=-0.04291741b4=-0.0429174b13=-0.00885584b5=-0.02903702b14=0.00804504b6=0.09725365b15=0.00482584b7=0.28342322b16=0.00000000B8=0.37452503在DSP汇编语言中,不能直接输入十进制小数,在MATLAB中进行如下转换:h=round(b*2^15)将系数转换为Q15的定点小数形式,为:h(0)=0h(9)=9287h(1)=158h(10)=3187h(2)=264h(11)=-951h(3)=-290h(12)=-1406h(4)=-1406h(13)=-290h(5)=-951h(14)=264h(6)=3187h(15)=158h(7)=9287h(16)=0h(8)=122722、编写FIR数字滤波器的汇编程序;一个FIR滤波器源程序fir.asm.mmregs.globalstart3.defstart,_c_int00INDEX.set1KS.set256;模拟输入数据缓冲区大小N.set17COFF_FIR.sectCOFF_FIR;FIR滤波器系数.word0.word158.word264.word-290.word-1406.word-951.word3187.word9287.word12272.word9287.word3187.word-951.word-1406.word-290.word260.word158.word0.dataINPUT.copyfirin.inc;模拟输入在数据存储区0x2400OUTPUT.space1024;输出数据在数据区0x2500COFFTAB.usectFIR_COFF,NDATABUF.usectFIR_BFR,NBOS.usectSTACK,0FhTOS.usectSTACK,1.text.asgAR0,INDEX_P.asgAR4,DATA_P;输入数据x(n)循环缓冲区指针.asgAR5,COFF_P;FIR系数表指针.asgAR6,INBUF_P;模拟输入数据指针.asgAR7,OUTBUF_P;FIR滤波器输出数据指针_c_int00bstartnopnopstart:SSBXFRCTSTM#COFFTAB,COFF_PRPT#N-1;将FIR系数从程序存储器移动MVPD#COFF_FIR,*COFF_P+;到数据存储器4STM#INDEX,INDEX_PSTM#DATABUF,DATA_PRPTZA,#N-1STLA,*DATA_P+;将数据循环缓冲区清零STM#(DATABUF+N-1),DATA_P;数据缓冲区指针指向x[n-(N-1)]STM#COFFTAB,COFF_P;FIR_TASK:STM#INPUT,INBUF_PSTM#OUTPUT,OUTBUF_PSTM#KS-1,BRCRPTBDLOOP-1STM#N,BK;FIR循环缓冲区大小LD*INBUF_P+,A;装载输入数据FIR_FILTER:STLA,*DATA_P+%RPTZA,N-1MAC*DATA_P+0%,*COFF_P+0%,ASTHA,*OUTBUF_P+LOOP:ENDBEEND.end3、编写FIR滤波器链接命令文件对应以上汇编程序的链接命令文件fir.cmd如下:fir.obj-mfir.map-ofir.outMEMORY{PAGE0:ROM1(RIX):ORIGIN=0080H,LENGTH=100HPAGE1:INTRAM1(RW):ORIGIN=2400H,LENGTH=0200HINTRAM2(RW):ORIGIN=2600H,LENGTH=0100HINTRAM3(RW):ORIGIN=2700H,LENGTH=0100HB2B(RW):ORIGIN=0070H,LENGTH=10H}SECTIONS{.text:{}ROM1PAGE0.data:{}INTRAM1PAGE1FIR_COFF:{}INTRAM2PAGE1FIR_BFR:{}INTRAM3PAGE1.stack:{}B2BPAGE1}54、实验步骤及结果(1)在CCS上建立fir工程并运行fir.out程序。建立fir工程,将fir.asm和fir.cmd添加到工程中,对汇编程序进行汇编、链接;如果有错误则进行修改、调试,当汇编、链接成功后,加载并运行fir.out程序。注意,将fir.asm、fir.cmd、firin.inc文件和fir.pjt工程文件放在同一文件夹下。(2)观察输入信号的波形及频谱。单击View→Graph→Time/Frequency命令,按照如图3-4所示改变各选项。其中,由.cmd可知输入信号的数据放在数据区0x2400开始的256个单元中。图3-4Graph属性设置窗口单击OK按钮,则显示输入信号的时域波形如图3-5所示。其波形是频率为1000Hz和2500Hz正弦信号的合成信号。图3-5输入信号的时域波形将图3-4中的DsiplayType项改为FFTMagnitude,则显示输入信号的频谱图,如图3-6所示。6图3-6输入信号的频谱图3、观察输出信号的波形及频谱。单击View→Graph→Time/Frequency命令,按照如图3-7所示改变各选项。其中,由.cmd可知输出信号的数据放在数据区0x2500开始的256个单元中。图3-7Graph属性设置窗口单击OK按钮,将显示滤波器输出信号时域波形,如图3-8所示。图3-8输出信号的时域波形7图3-9输出信号的频谱图5、系数对换FIR滤波器的实现系数对换FIR滤波器由于具有线性相位,因此应用很广。一个N=8的FIR滤波器,若h(n)=h(N-1-n),就是对换FIR滤波器,其输出方程为:总共有8次乘法和7次加法。如改写成:变成4次乘法和7次加法,乘法运算次数减少了一半,特别是当阶数较高时,利用系数对称的特点,可以明显减少运算量。(1)FIR滤波器设计在MATLAB下输入:B=fir1(15,1500/8000*2);H=round(b*2^15);将系数转换为Q15的定点小数形式则滤波器系数为:h(0)=62h(8)=11439h(1)=188h(9)=6202h(2)=86h(10)=625h(3)=-764h(11)=-1453h(4)=-1453h(12)=-764h(5)=625h(13)=86h(6)=6202h(14)=188h(7)=11439h(15)=62系数对称FIR数字滤波器汇编程序如下:.mmregs.globalstart()(0)()(1)(1)(2)(2)(3)(3)(4)(4)(5)(5)(6)(6)(7)(7)ynhxnhxnhxnhxnhxnhxnhxnhxn()(0)[()(7)](1)[(1)(6)](2)[(2)(5)](3)[(3)(4)]ynhxnxnhxnxnhxnxnhxnxn8.defstart,_c_int00KS.set256;输入样本数据个数N.set16;FIR滤波器阶数COEF_FIR.sectCOEF_FIR;FIR滤波器系数.word62.word188.word86.word-764.word-1453.word625.word6202.word11439.dataINPUT.copyfirin.inc;输入数据在数据区0x2400OUTPUT.space1024;输出数据在数据区0x2500x_new.usectDATA1,N/2x_old.usectDATA2,N/2size.setN/2.text_c_int00bstartnopnopstart:SSBXFRCT;设置FRCT(小数方式)位STM#x_new,AR2;AR2指向New缓冲区第一个单元STM#x_old+(size-1),AR3;AR3指向Old缓冲区最后一个单元STM#-1,AR0STM#INPUT,AR4;模拟输入数据指针初始化STM#OUTPUT,AR5;滤波器输出数据指针初始化STM#KS-1,BRCRPTBDLOOP-1STM#size,BK;循环缓冲区块大小BK=sizeLD*AR4+,ASTLA,*AR2FIR_FILTER:ADD*AR2+0%,*AR3+0%,ARPTZB,#size-1FIRS*AR2+0%,*AR3+0%,COEF_FIRSTHB,*AR5+MAR*+AR2(2)%MAR*AR3+%MVDD*AR2,*AR3+0%LOOP:ENDBEND9.end链接命令文件如下:fir2.obj-mfir2.map-ofir2.outMEMORY{PAGE0:ROM1(RIX):ORIGIN=0080H,LENGTH=1000HPAGE1:INTRAM1(RW):ORIGIN=2400H,LENGTH=0200HINTRAM2(RW):ORIGIN=2600H,LENGTH=0100HINTRAM3(RW):ORIGIN=2700H,LENGTH=0100HB2B(RW):ORIGIN=0070H,LENGTH=10H}SECTIONS{.text:{}ROM1PAGE0COEF_FIR:{}ROM1PAGE0.data: