FIR滤波器设计与实现课程设计.docx
《FIR滤波器设计与实现课程设计.docx》由会员分享,可在线阅读,更多相关《FIR滤波器设计与实现课程设计.docx(27页珍藏版)》请在冰点文库上搜索。
郑州航空工业管理学院电子通信工程系
DSP原理及应用课程设计报告
设计题目:
基于TMS320F2812DSP处理器的FIR滤波器的设计与实现
姓名 王 泳
学号:
091307229
专业:
通信工程
设计日期:
2012年6月15日
指导老师:
赵 成 张松炜
基于TMS320F2812 DSP处理器的FIR滤波器的设计与实现
一.引言
数字信号处理是电路系统从模拟时代向数字时代前进的理论基础,为数字信号处理的应用而专门设计的可编程处理器,即数字信号处理器也应运而生。
在当今信息时代数字信号处理已成为一门极其重要的学科。
数字信号处理在通信、语音、图像等众多相关领域得到了广泛的应用。
数字信号处理(DSP)包括两重含义:
数字信号处理技术(DigitalSignal Processing)和数字信号处理器(Digital Signal
Processor)。
数字信号处理(DSP)是利用计算机或专用处理设备,以数值计算的方法、对信号进行采集、滤波、增强、压缩、估值和识别等加工处理,借以达到提取信息和便于应用的目的,其应用范围涉及几乎所有的工程技术领域。
目前FIR滤波器的实现方法大致可分为三种:
利用单片通用数字滤波器集成电路、DSP器件或者可编程逻辑器件实现。
其中以使用通用DSP芯片实现方式较为简单,是一种实时、快速、特别适合于实现各种数字信号处理运算的微处理器,借助于通用数字计算机按滤波器的设计算法编出程序进行数字滤波计算。
由于它具有丰富的硬件资源、改进的哈佛结构、高速数据处理能力和强大的指令系统而在通信、航空、航天、雷达、工业控制、网络及家用电器等各个领域得到广泛应用
二.设计目的
1、掌握用窗函数法设计FIR滤波器的原理及方法,熟悉线性纤维
FIR滤波器的
幅频特性和相频特性及其图像。
2、掌握使用matlab编程的基本方法,学会利用fdatool 工具来快速设计满足需要的滤波器。
3、掌握TMS320F2812DSP处理器开发的程序框架结构,学习驱动TMS320F2812DSP处理器程序编写并能使其正常工作。
实习驱动ADC模块实现信号的实时采集与模数转换
4、掌握使用TMS320F2812DSP处理器实现FIR数字低通滤波器的设计方法,并能够实时采集输入信号并滤除高频信号再通过SCI串口传输到计算机显示。
三.设计要求
1、利用Matlab软件的FDATool工具设计FIR滤波器,并提取滤波器参数;
2、在CCS集成开发环境下,利用第1步得到的滤波器参数,利用窗函数法设计FIR滤波器程序,观察输入信号及滤波后得到的输出信号的时域波形及FFTMagnitude波形;
3、利用TMS320F2812的ADC片内外设的外围电路实时采集的混频信号数据,使用1个51阶的FIR低通滤波器,在CCS中设计FIR滤波器程序实现滤波,观察相关波形及滤波效果,通过SCI接口将数据传送到计算机上;
四、总体设计
4.1利用Matlab软件的FDATool工具设计FIR滤波器
4.1.1有限冲击响应数字滤波器的基础理论
滤波器就是在时间域或频域内,对已知激励产生规定响应的网络,使其能够从信号中提取有用的信号,抑制并衰减不需要的信号。
滤波器的设计实质上就是对提出的要求给出相应的性能指标,再通过计算,使物理可实现的实际滤波器频率响应特性逼近给出的频率响应特性。
FIR数字滤波器系统的传递函数为:
H(z)=Y(z)
X(z)
N-1
å
= b(n)z-n
n=0
(1)
由此得到系统的差分方程:
y(n)=b(0)*x(n)+b
(1)*x(n-1)+××××××+b(N-1)*x(n(N-1))
(2)
若FIR数字滤波器的单位冲激响应序列为h(n),它就是滤波器系数向量b(n)。
传统的滤波器分析与设计均使用繁琐的公式计算,改变参数后需要重新运算,从而在分析与设计滤波器尤其是高阶滤波器时工作量特别大。
这里应用MATLAB 设计FIR滤波器,根据给定的性能指标设计一个H(z),使其逼近这一指标,进而计算并确定滤波器的系数b(n),再将所设计滤波器的幅频响应、相频响应曲线
作为输出,与设计要求进行比较,对设计的滤波器进行优化。
设计完成之后将得到FIR滤波器的单位冲激响应序列h(n)的各个参数值。
4.1.2利用Matlab软件的FDATool设计FIR滤波器
(1) 首先在命令窗口键入FDAtool命令,启动滤波器设计分析器,调出FDAtool界面,如下图所示。
FDATool界面
(2)在FilterType选项中选Lowpass,在DesignMethod中选择FIR滤波器,接着在FIR中选择Window(窗函数)法。
(3)然后在FilterOrder中选择SpecifyOrder(为指定阶数),输入数值为“51”;在Opitions框中选中“Scale
Passband”;在窗类型(Window:
)下拉框选择“Blackman”。
(4)在FrenquencySpecification选项中,将fs(为采样频率)、fc(为通带截止频率)中分别键入250000Hz和
20000Hz。
(5) 点击“DesignFilter”按钮,完成滤波器的设计。
(6)通过菜单选项Analysis来分析滤波器的幅频响应和相频响应特性。
点击Analysis中的MagnitudeResponse和PhaseResponse对幅频和相频响应进行分析。
如下图所示
(7) 在FDATool 中,选择Targets -> Generate CHeader...,单击Generate按钮,选择路径,即可输出前一步设计出的 FIR滤波器的系数表。
(默认的系数表文件为fdacoefs.h。
如下图所示。
(8) 在Matlab中打开得到的fdacoefs.h的文件,如下图所示
从Matlab中打开的fdacoefs.h文件
4.1.3提取滤波器参数
取系数表中的数据小数点后3位有效值,得到如下内容:
ConstfloatB[52]={0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
0.001,0.003,0.004,0.004,0.003,0,-0.006,-0.013,-0.019,-
0.021,-0.017,-0.005,0.018,0.048,0.083,0.116,
0.143,0.158,0.158,0.143,0.116,0.083,0.048,0.018,-0.005, -
0.017,-0.021,-0.019,-0.013,-0.006,0,0.003,0.004,0.004,
0.003,0.001,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000
}
4.2CCS环境下FIR滤波器的设计及软件仿真
4.2.1程序流程图
初始化
输入低通滤波器各频率参数
构建滤波器频域特性波形
使用FDATool提取滤波器参数或用FIR滤波器计算程序计算得到滤波器参数
构建FIR滤波器进行滤波
无限循环
4.2.2在CCS集成开发环境下新建FIR滤波器工程
(1)实验准备
设置软件仿真模式,启动CCS。
(2)建立工程
建立一个文件夹,存放在D:
\FIR,将D:
\课程设计\FIR滤波器\Fir源程序文件夹下的工程全部复制到D:
\FIR,在CCS中打开
D:
\FIR\fir\fir.pjt工程,打开的CCS集成开发环境如下图所示。
4.2.3观察滤波前后的信号的时域波形及FFTMagnitude波形
(1)编译工程文件生成fir.out文件,并通过File->Load
Program…装载该文件。
(2)设置波形时域观察窗口。
选择菜单View→Graph→Time/Frequency… ,分别进行如下图所示进行设置以便观察输入/输出时域波形。
输入数据时域波形观察 输出数据时域波形观察选择菜单View→Graph→Time/Frequency… ,分别进行如下
图所示进行设置以便观察输入/输出频域波形。
输入数据频域波形观察 输出数据频域波形观察
(3)设置断点。
在程序fir.c中,有注释断点的语句上设置软件断点。
(4)运行并观察结果。
选择Debug菜单的Run项,或按F5
键运行程序。
观察到的图形如下图所示。
左上角:
输入数据时域图(StartAddress:
input)
右上角:
输入数据频谱(DisplayType:
FFTMagnitude)左下角:
输出数据时域图(StartAddress:
output)
右下角:
输出数据频谱(DisplayType:
FFTMagnitude)
4.2.4程序清单
fir.c程序
//#include"DSP281x_Device.h" //DSP281xHeaderfileIncludeFile
//#include "DSP281x_Examples.h" // DSP281x ExamplesIncludeFile
//#include"f2812a.h"#include"math.h"#defineFIRNUMBER52
//#define
SIGNAL1F
1000
//#define
SIGNAL2F
4500
//#define
SAMPLEF
10000
#definePI3.1415926floatInputWave();floatFIR();
floatfHn[FIRNUMBER]={0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,
0.001,0.003,0.004,0.004,0.003,0,-0.006,-0.013,-0.019,-
0.021,-0.017,-0.005,0.018,0.048,0.083,0.116,
0.143,0.158,0.158,0.143,0.116,0.083,0.048,0.018,-0.005, -
0.017,-0.021,-0.019,-0.013,-0.006,0,0.003,0.004,0.004,
0.003,0.001,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000
};
floatfXn[FIRNUMBER]={0.0};
floatfInput,fOutput;floatfSignal1,fSignal2;
floatfStepSignal1,fStepSignal2;floatf2PI;
inti;
floatfIn[256],fOut[256];intnIn,nOut;
main(void)
{
nIn=0;nOut=0;f2PI=2*PI;
fSignal1=0.0;fSignal2=PI*0.1;fStepSignal1=2*PI/30;fStepSignal2=2*PI*1.4;while
(1)
{
fInput=InputWave();fIn[nIn]=fInput;nIn++;nIn%=256;
fOutput=FIR();fOut[nOut]=fOutput;
nOut++;
if(nOut>=256)
{
nOut=0; /*请在此句上设置软件断点*/
}
}
}
floatInputWave()
{
for(i=FIRNUMBER-1;i>0;i--)
fXn[i]=fXn[i-1];fXn[0]=sin(fSignal1)+cos(fSignal2)/6.0;fSignal1+=fStepSignal1;
if(fSignal1>=f2PI) fSignal1-=f2PI;fSignal2+=fStepSignal2;
if(fSignal2>=f2PI) fSignal2-=f2PI;return(fXn[0]);
}
floatFIR()
{
floatfSum;fSum=0;
for(i=0;i{
fSum+=(fXn[i]*fHn[i]);
}
return(fSum);
}
fir.cmd 程序
-lrts2800_ml.lib
-stack400h
-heap100MEMORY
{
PAGE0:
PROG(R) :
origin=0x80000,length=0x10000
PAGE0:
BOOT(R) :
origin=0x3FF000,length=
0xFC0
PAGE0:
RESET(R) :
origin=0x3FFFC0,length=
0x2
/*PAGE0:
VECTORS(R) :
origin=0x3FFFC2,length=0x3E*/
PAGE1:
M0RAM(RW) :
origin=0x000000,length=
0x400
PAGE
1:
M1RAM(RW) :
origin
=
0x000400,
length
=
0x400
PAGE
1:
L0L1RAM(RW):
origin
=
0x008000,
length
=
0x2000
PAGE1:
H0RAM(RW) :
origin=0x3F8000,length=0x2000
}SECTIONS
{
/*22-bitprogramsections*/
.reset :
>RESET, PAGE=0
/*vectors:
>VECTORS,PAGE=0*/
.pinit :
>PROG, PAGE=0
.cinit :
>PROG, PAGE=0
.text :
>PROG, PAGE=0
/*16-Bitdatasections*/
.const :
>L0L1RAM,PAGE=1
.bss :
>L0L1RAM,PAGE=1
.stack :
>M1RAM,PAGE=1
.sysmem :
>M0RAM,PAGE=1
/*32-bitdatasections*/
.ebss :
>H0RAM,PAGE=1
.econst :
>H0RAM,PAGE=1
.esysmem:
>H0RAM,PAGE=1
4.3对实时采样信号进行滤波的FIR滤波器的实现
4.3.1程序清单
#include "DSP281x_Device.h" // DSP281x HeaderfileIncludeFile
#include "DSP281x_Examples.h" // DSP281x ExamplesIncludeFile
#include#definepi3.1415927intpx[256];
intpy[256];
doublenpass,h[51],x,y,xmid[51];intm=50;
intn=256;
//Prototypestatementsforfunctionsfoundwithinthisfile.
interruptvoidadc_isr(void);
//Globalvariablesusedinthisexample:
Uint16LoopCount;
Uint16ConversionCount;
voidfirdes(intm,doublenpass)
{
intt;
for(t=0;t<=m;t++)
{
h[t]=sin((t-m/2.0)*npass*pi)/(pi*(t-m/2.0));
}
if(t=m/2)h[t]=npass;
}
voidmain(void)
{
intxm,ym;
doublefs,fstop,r,rm;inti,j,p,k;
//PLL,WatchDog,enablePeripheralClocks
// This example function is found in theDSP281x_SysCtrl.cfile.
InitSysCtrl();
//Forthisexample,setHSPCLKtoSYSCLKOUT/6(25Mhzassuming150MhzSYSCLKOUT)
EALLOW;
SysCtrlRegs.HISPCP.all = 0x3; // HSPCLK =
SYSCLKOUT/6
EDIS;
//DisableCPUinterruptsDINT;
//InitializethePIEcontrolregisterstotheirdefaultstate.
InitPieCtrl();
//DisableCPUinterruptsandclearallCPUinterruptflags:
IER=0x0000;IFR=0x0000;
//InitializethePIEvectortablewithpointerstotheshellInterrupt
//ServiceRoutines(ISR).
InitPieVectTable();
// Interrupts that are used in this example are re-mappedto
//ISRfunctionsfoundwithinthisfile.
EALLOW;//ThisisneededtowritetoEALLOWprotectedregister
PieVectTable.ADCINT=&adc_isr;
EDIS; //ThisisneededtodisablewritetoEALLOW
protectedregisters
InitAdc(); //Forthisexample,inittheADC
//EnableADCINTinPIEPieCtrlRegs.PIEIER1.bit.INTx6=1;
IER|=M_INT1;//EnableCPUInterrupt1
EINT; //EnableGlobalinterruptINTM
ERTM; //EnableGlobalrealtimeinterrupt
DBGM
LoopCount=0;
ConversionCount=0;
//ConfigureADCAdcRegs.ADCTRL1.bit.SEQ_CASC=1;
AdcRegs.ADCMAXCONV.all=0x0000; //Setup2conv'sonSEQ1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x4; // SetupADCINA0as1stSEQ1conv.
AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1; // EnableEVASOCtostartSEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1; //EnableSEQ1interrupt(everyEOS)
//ConfigureEVA
//AssumesEVAClockisalreadyenabledinInitSysCtrl();
EvaRegs.T1CMPR=0x0380; //SetupT1comparevalue
EvaRegs.T1PR=0x07FF; //Setupperiodregister
EvaRegs.GPTCONA.bit.T1TOADC = 1; // EnableEVASOCinEVA
EvaRegs.T1CON.all=0x1042; //Enabletimer1compare(upcountmode)
//WaitforADCinterruptk=0;
fs=250000;
fstop=20000;npass=fstop/fs;
for(i=0;i<=m;i++)
{
xmid[i]=0;
}
for(;;)
{
firdes(m,npass);
for(i=0;i<=n-1;i++)
{
xm=px[i];
x=xm/1023.0;
for(p=0;p<=m;p++)
{
xmid[m-p]=xmid[m-p-1];
}
xmid[0]=x;r=0;
rm=0;
for(j=0;j<=m;j++)
{
r =xmid[j]*h[j];rm=rm+r;
}
y=rm;
ym=(int)(1023.0*y);py[i]=ym;
}
k++; //加断点,观察波形
}
}
interruptvoid adc_isr(void)
{
px[ConversionCount]=AdcRegs.ADCRESULT0>>4;