基于DSP的FIR数字滤波器设计毕业设计论文.docx
《基于DSP的FIR数字滤波器设计毕业设计论文.docx》由会员分享,可在线阅读,更多相关《基于DSP的FIR数字滤波器设计毕业设计论文.docx(33页珍藏版)》请在冰点文库上搜索。
基于DSP的FIR数字滤波器设计毕业设计论文
《DSP技术》课程论文
题目基于DSP的FIR数字滤波器设计
一概述2
1.1数字滤波器的研究现状2
1.2论文主要完成的工作2
二系统硬件设计3
2.1系统设计方案3
2.2主控模块6
2.3显示模块7
三系统软件设计10
3.1软件整体设计10
3.2测量模块10
四系统测试结果与总结11
4.1硬件调试中要注意到的问题11
4.2软件调试中要注意到的问题11
4.3结果11
4.4总结12
五参考文献13
六附件14
基于DSP的FIR数字滤波器设计
一、概述
1.1数字滤波器的研究现状
滤波器的主要分类有以下几种:
(1)按处理信号类型分类,可分为模拟滤波器和离散滤波器两大类。
其中模拟滤波器又可分为有源、无源、异类三个分类;离散滤波器又可分为数字、取样模拟、混合三个分类。
(2)按选择物理量分类,滤波器可分为频率选择、幅度选择、时间选择(例如PCM制中的话路信号)和信息选择(例如匹配滤波器)等四类滤波器。
(3)按频率通带范围分类,滤波器可分为低通、高通、带通、带阻、全通五个类别,而梳形滤波器属于带通和带阻滤波器,因为它有周期性的通带和阻带。
为适应各种需要,出现了一批新型滤波器,这里介绍几种已得到广泛应用的新型滤波器:
(1)电控编程CCD横向滤波器(FPCCDTF):
电荷耦合器(CCD)固定加权的横向滤波器(TF)在信号处理中,其性能和造价均可与数字滤波器和各种信号处理部件媲美。
这种滤波器主要用于自适应滤波;P-N序列和Chirp波形的匹配滤波;通用化的频域滤波器及相关积运算;语音信号和相位均衡;相阵系统的波束合成和电视信号的重影消除等均有应用。
当然,更多的应用有待进一步开拓。
总之,FPCCDTF是最有希望的发展方向。
(2)晶体滤波器:
它是适应单边带技术而发展起来的。
在20世纪70年代,集成晶体滤波器的产生,使它的发展产生一个飞跃。
近十年来,晶体滤波器致力于下面一些研究:
实现最佳设计,除具有优良的选择外,还具有良好的时域响应;寻求新型材料;扩展工作频率;改造工艺,使其向集成化发展。
它广泛应用于多路复用系统中作为载波滤波器,在收发信中,单边带通信机中作为选频滤波器,在频谱分析仪和声纳装置中作为中频滤波器。
(3)声表面滤波器:
它是理想的超高频器件。
它的幅频特性和相位特性可以分别控制,以达到要求,而且它还有体积小,长时间稳定性好和工艺简单等特点。
通常应用于:
电视广播发射机中作为残留边带滤波器;在彩色电视接收机中调谐系统的表面梳形滤波器。
此外,在国防卫星通信系统中已广泛采用。
声表面滤波器是电子学和声学相结合的产物,而且可以集成,所以,它在所有无源滤波器中最有发展前途的。
我国现有滤波器的种类和所覆盖的频率已基本上满足现有各种电信设备。
从整体而言,我国有源滤波器发展比无源滤波器缓慢,尚未大量生产和应用。
从下面的生产应用比例可以看出我国各类滤波器的应用情况:
LC滤波器占50%;晶体滤波器占20%;机械滤波器占15%;陶瓷和声表面滤波器各占1%;其余各类滤波器共占13%。
从这些应用比例来看,我国电子产品要想实现大规模集成,滤波器集成化仍然是个重要课题。
随着电子工业的发展,对滤波器的性能要求越来越高,功能也越来越多,并且要求它们向集成方向发展。
我国滤波器研制和生产与上述要求相差甚远,为缩短这个差距,电子工程和科技人员负有重大的历史责任。
1.2论文主要完成的工作
本课题主要应用MATLAB软件设计FIR数字滤波器,并对所设计的滤波器进行仿真:
应用DSP集成开发环境—CCS调试汇编程序,用TMS320C5402来实现了FIR数字滤波。
主要完成的工作有:
(1)对FIR数字滤波器的基本理论进行了分析和探讨;
(2)采用MATLAB软件来学习数字滤波器的基本知识,计算数字滤波器的系放,研究算法的可行性,对FIR低通数字滤波器进行前期的设计和仿真;
(3)系统介绍了TI公司TMS320C54x系列数字信号处理器的硬件结构、性能特点和DSP的集成开发环境CCS;应用DSP集成开发环境-℃CS调试汇编程序,用TMS320C5402来实现了FIR数字滤波。
(4)用窗函数法实现FIR滤波器,通过调用四种窗口函数,截取不同的带通与低通滤波原型,满足以下性能要求:
带通滤波器:
下阻带边缘:
,
;下通带边缘:
,
,上通带边缘:
,
;上阻带边缘:
,
,低通滤波器:
,
;
,
;
(5)研究DSP的结构特点,了解TI公司的TMS3205410DSP器件,掌握DSP系统的构成及软硬件设计方法和CCS软件的调试方法;并以TI公司的TMS3205410DSP为核心处理器,在DSP上实现FIR滤波器系统。
二、系统硬件设计
2.1系统设计方案
通常一个典型的DSP系统如图1所示。
图2.1典型的DSP系统
上图是一个用DSP做信号处理的典型框图。
由于DSP是用来对数字信号进行处理的,所以首先必须将输入的模拟信号变换为数字信号。
于是先对输入模拟信号进行调整,输出的模拟信号经过A/D变换后变成DSP可以处理的数字信号,DSP根据实际需要对其进行相应的处理,如FFT、卷积等;处理得到的结果仍然是数字信号,可以直接通过相应通信接口将它传输出去,或者对它进行D/A变换将其转换为模拟采样值,最后再经过内插和平滑滤波就得到了连续的模拟波形模拟信号。
一般来说DSP的设计过程应遵循一定的设计流程,如图2示。
图2.2DSP基本设计流程
在数字信号处理系统中,常常要用到FIR数字滤波器,这是因为用FIR滤波器可以逼近任意幅频特性的滤波器,并获得很好的性能。
故我们将设计基于DSP的FIR数字滤波器。
本次数字滤波器的实现采用线性缓冲区法。
利用线性缓冲区法实现一个K阶数字FIR滤波器的计算时,除在存储空间中定义一个长度为K的存储去用于存放滤波器的系数外,还需要专门定义一个长度为K的存储区域用来存放K个输入数据,该区域称为循环缓冲区。
在开始计算前,先给循环缓冲区中所有单元全部赋值为0,开始计算后,每来一个新的输入数据,将其按顺序写入循环缓冲区,并将循环缓冲区数据于滤波器系数按相应的规则进行K次乘法累加计算,产生一个输出数据。
直到循环缓冲区被填满,下一个输入数据到来时,用其替换循环缓冲区中最早的那个数据点,并相应地进行K次循环累加运算,产生相应的滤波输出。
如此循环直到输入数据序列计算结束。
这样在循环缓冲中读取数据时总是在这一段地址范围内循环读数,因此将这一算法称为循环缓冲区法。
循环缓冲区法的数据寻址示意图如下图4所示:
初始状态n时刻的输入采样更新一个数据后
图2.3循环缓冲区法执行过程图
循环缓冲区法的具体步骤如下:
(1)定义两个长度为K的数组,一个用来存放滤波系数h[n],另一个用来存放输入数据a[n];
(2)将滤波系数存放到h[n]中,将a[n]的所有元素赋值为0;
(3)将要处理的第一个数据存于a[0]中;
(4)进行K次乘法累加运算,得出一个滤波输出;
(5)将新的输入数据值存入a[K]中,以替代最旧的一个数据重复第(4)步,计算新的滤波器输出,如此循环至所有的输入数据处理结束。
循环缓冲区法实现的数字滤波器结构比较紧凑,占用存储资源较少,结合DSP的循环寻址方法可以方便、高效的实现FIR数字滤波器。
总的设计框图3如下:
观察输入输出波形
CCS
MATLAB滤波器设计工具FDATOOL设计系数
图2.4系统设计框图
2.2主控模块
TMS3205402是16位的定点处理器,所以在进行汇编程序设计时,FIR滤波器系数要采用Q15格式,即必须将上述系数转化为Q15格式,这只要将滤波器各系数乘以2
即可。
用DSP实现Z
算法是十分方便的,常用的方法有两种:
线性缓冲区法和循环缓冲区法。
在本文中采用的是循环缓冲法,循环缓冲区法的特点是:
(1)对于N阶的FIR滤波器,在数据存储器中开辟一个也称为滑窗的N个单元的缓冲区,滑窗中存放最新的N个输入样本;
(2)每次移入新的样本时,以新样本改写滑窗中老的数据,而滑窗中的其他数据不需要移动;
(3)利用片内BK(循环缓冲区长度)寄存器对滑窗进行间接寻址,循环缓冲区地址首尾相邻。
FIR滤波器的核心算法是计算输入信号与滤波器系数的卷积。
设x(n)为输入信号,h(n)为FIR滤波器的冲击响应,n=0,…,N-1,则FIR滤波器的输出y(n)就是x(n)与h(n)的卷积,即:
由于卷积是数字信号处理中最常用到的算法,因此几乎所有的DSP芯片中都设有专门的指令支持卷积运算。
在TMS3205410中可以用macd指令完成卷积。
macd指令的形式如下:
macd(Smem,pmad,src);
在macd指令中,Smem是间接寻址参数,它是指令中指向数据存储器的单地址。
Pmad是表示程序存储器地址的16位常数。
Src表示累加器,可以是A累加器或是B累加器。
这条指令在执行时,先把指令中的pmad常数送到程序地址寄存器的PAR中,然后将Smem地址中的数据用PAR地址在程序存储器中读取的数据相乘,并将乘积结果累加到由Src指定的累加器中。
在指令执行时,Smem地址中的内容被同时复制到T寄存器和Smem低中之后的下一个地址单元中。
若采用repeat指令重复执行macd指令,则在执行指令的最后,PAR寄存器自动加1,这样当macd再次执行时就直接用PAR中的地址读取程序存储器中的数据。
通常情况下,macd指令执行时需要三个周期。
但是若用repeat指令执行macd,进入流水线后只要一个周期就可以执行一次macd指令。
由此可见,该指令同时完成了乘累加和数据延迟(移位)的功能,这正是卷积算法所要求的。
对于输入序列,它在两个循环缓冲器里的存储情况如下,要建立缓冲区首先将循环缓冲区大小寄存器的值设为N/2辅助寄存器AR4指到缓冲区1(Bufferl)的顶部AR5指到缓冲区2(Buffer2)的底部,新来一个样本存储到缓冲区1中时,应先将缓冲区1顶部的数据移到缓冲区2底部,处理器然后进行乘加运算,滤波程序每步运算后AR4指向数据移到的下一个窗口,而AR5则指向下一个输入数据,对于下一步运算AR4指向地址1,AR5指向地址N/2。
如下图所示。
图2.5FIR系数存储格式示意图
考虑到在执行macd指令时是将低地址的数据复制到高地址来完成延迟功能,所以在用macd指令计算卷积时,先计算x(n-N+1)与h(N-1)的乘积,最后才计算x(n)与h(0)的乘积。
因此在程序中,FIR滤波器的系数在程序存储器中按倒序存储。
2.3显示模块
本系统的具体硬件方案框图如下图:
图2.6硬件方案框图
在本系统设计中采用了TI的TMS320VC5402作为其核心处理单元。
TMS320VC5402为低功耗定点数字信号处理器,其运算速度最快可达532MIPS。
它采用先进的修正哈佛结构,片内共有8条总线(1条程序存储器总线、3条数据存储总线和4条地址总线)。
其CPU采用并行结构设计,使其能在一条指令周期内,高速地完成多项算术运算。
TMS320VC5402的丰富的片上外围电路(通用I/O引脚,定时器,时钟发生器,HPI接口,多通道缓冲串行口McBSP)使其与外部接口方便[2]。
TMS320VC5402的片上包含两个McBSP(多通道缓冲串行口)接口,可以将这两个通道
模仿实现SPI的时序,因此本设计中采用了SPI接口器件实现数据的模数转换和数模转换。
在本数字滤波器系统中选择了TI公司的TLV1570芯片作为模数转换器件,8通道10位2.7到5.5V低电压模数转换芯片。
TLVl570在3V电压下的采样频率为625KSPS,输入信号最高频率不能超过300K[3]。
其功能时序图如下:
图2.7TLV1570的功能时序图
从功能时序图可以看出该器件包含8通道输入多路复用器、高速的10位ADC、内部的电压参考源和高速的串行接口。
其高速串行接口包含五根信号线:
SCLK串行时钟输入、SDIN串行数据输入、SDOUT串行数据输出、FS帧同步信号、CS#片选信号。
其中每个取样和转换过程需要16个系统工作时钟。
由于模数转换选择了10位器件,为了简化程序代码,减少DSP的运算工作量,在本数字滤波器系统中选择了TI公司的TLV5608芯片,它是一款8通道10位2.7到5.5V低电压数模转换芯片[4]。
如下图所示:
图2.8TLV5608的功能时序图。
三、系统软件设计
3.1软件整体设计
系统软件设计由Matlab辅助DSP实现FIR,其总体过程为在DSP中编写处理程序;在Matlab中利用滤波器设计、分析工具(FDATool),根据指定的滤波器性能快速设计一个FIR,然后把滤波器系数以头文件形式导人CCS中,头文件中含滤波器阶数和系数数组,在Matlab中调试、运行DSP程序并显示、分析处理后的数据。
使用该方法,便于采用语言来实现程序。
头文件名不变,当Matlab中设计的滤波器系数改变时,相应头文件中系数也改变,方便了程序调试、仿真。
软件整体设计流程如下图所示:
图3.1软件整体设计流程图
3.2测量模块
测量模块设计流程图如下图所示:
图3.2测量模块设计流程图
四、系统测试与总结
4.1硬件调试中要注意到的问题
在本系统的硬件调试中主要测试步骤如下:
①首先测量电路板的电源和地是否有短路现象,电路板上所采用器件多为小封装器件,管脚间距小,容易出现短路现象,焊接完成后要认真检查。
②系统上电检测,上电前应该首先检查电源的正负极性及输入电压的幅度,然后上电。
上电后应快速检测电路板上主要电源芯片的输出电压和DSP内核电压,以免损坏电路板上器件。
③检测系统的复位信号是否工作正常,系统在复位后部分器件会检测自身的工作状态。
④用示波器查看系统中主要的时钟信号的波形,包括DSP输入时钟信号、DSP输出时钟信号、ADC和DAC的系统时钟信号及帧同步时钟信号(需要结合DSP的开发环境和仿真器进行测试)。
⑤测量所准备的测试信号源的工作电压和工作频率是否在系统的允许范围内。
4.2软件调试中要注意到的问题
利用TMS320VC5402实现FIR的程序中应注意以下几点:
1.数据定标。
输入数据和滤波器系数均小于1,以Q15表示,将FRCT标志置1,输入数据与滤波器系数乘完后结果自动左移一位,和累加器并取高16位输出。
2.数据存放要求。
输入数据块和系数块都放在双寻址数据存储区,起始地址为m位地址边界(2m>N)。
3.循环寻址的使用。
为了使用循环寻址,还要设置BK为块长N。
由于使用了循环寻址,数据和系数的指针在操作后以循环的方式增1。
4.数据的初始化。
输入数据块要初始化为全0。
利用TMS320VC5402的FIRS指令和循环寻址,可以更简洁的方法实现对称抽头的FIR滤波器。
4.3结果
当给系统送入一个包含lk,3k,5k的正弦波模拟信号源作为系统的输入信号源,并将
MATLAB仿真得到的低通数字滤波器的系数带入所编写的程序代码中,编译运行后
循环执行滤波程果符合预期结果。
程序设置断点运行后,设置观察图形窗口变量及参数为:
采用双踪观察启始地址分别为x和y,长度为256的单元中数值的变化,数值类型为32位浮点型变量,这两个数组中分别存放的是经A/D转换后的输入混叠信号(输入信号)和对该信号进行FIR滤波的结果;单击“Animate”运行程序,调整观察窗口并观察滤波结果,如下图示。
图4.1测试结果
4.4个人总结
本课题的主要工作是应用MATLAB软件设计FIR数字滤波器,并对所设计的滤波器进行仿真;应用DSP集成开发环境一CCS调试汇编程序,用TMS320C5416来实现了FIR数字滤波。
在本次是软件设计过程中,我所出现的问题以及需要注意的是:
(1)在FIR.m中的采样频率的设置要和开始设置时的采样频率一致,否则结果会出现偏差。
(2)在CCS中未定义标号,程序运行错误。
(3)在.h文件中未把coeff顶格写,编译时出现错误。
(4)未将fir.h和input.dat文件考入工程文件中。
(5)在间接寻址过程中,程序中丢失。
(6)在View的Graph中单击Time/frequency出现graphpropertydialog框,未修改抽样点数,导致显示的图形出现差异。
在本次课程设计的过程中,我发现自己的知识面非常的狭隘,以至于,我不得不借阅大量的书籍来零时抱佛脚。
在实际操作过程中,一开始发现自己的汇编语言知识严重缺乏,只好改用C语言,然而许久没用C语言的我,对于C语言程序的编写,依然有些陌生的感觉了,好在学过的东西,在回忆还不算太难。
其次就是在硬件设计的时候遇到了不少的麻烦,只能大量的查阅书本或者上网寻找相应的资料。
五、参考文献
[1]陈后金.数字信号处理.北京:
高等教育出版社,2004
[2]SanjitK.MitraDigitalSignalProcessing:
AComputer-BasedApproach.
McGraw—HillCompanies,Inc.2005.424—426
[3]周利清,苏菲.数字信号处理基础.北京:
北京邮电大学出版社,2005
[4]程佩清.数字信号处理教程(第二版).北京:
清华大学出版社,2001
[5]王世一.数字信号处理.北京:
北京理工大学出版社,2006
[6]丁玉美.数字信号处理.西安:
西安电子科技大学出版社,‘2001
[7]胡广书.数字信号处理.理论、算法与实现.北京:
清华大学出版社,1997
[8]张贤达.现代信号处理.北京:
清华大学出版社,1996
[9]支长义,程志平等.DSP原理开发应用.北京:
航空航天大学出版社,2006.1.2
[10]陈亚勇.MATLAB信号处理详解.北京:
人民邮电出版社,2001
[1l]王宏.MATLAB6.5及其在信号处理中的应用.北京:
清华大学出版社,2004
[12]朱铭铭.基于模糊的DSP系统设计.北京:
电子工业出版社,2000
[13]TMS32054xDSP应用程序设计教程.北京:
机械工业出版社,2004
[14]TMS32054xDSP硬件开发教程.北京:
机械工业出版社,2003
[15]张雄伟.DSP芯片的原理与开发应用(第二版).北京:
电子工业出版社,2000
[l6]彭宗启.DSP技术原理及应用.北京:
电子工业出版社,1998
六、附录
FIR的DSP实现程序
C1:
FIR.c
/******************************************************************************
TheprogrammeoftheFIRfilter.
UsingINT2togettheinputsignal.
ArrayxistheinputsignalfromA/D,thelengthis256,32-bitfloatingpoint.
Arrayyisthesignaloutoffilter,thelengthis256,32-bitfloatingpoint.
ArrayhisthecoefficientoftheFIRfilter,thelengthis101,101orderfilter.
*******************************************************************************
#pragmaCODE_SECTION(vect,"vect")
#include"stdio.h"
#include"math.h"
#definepi3.1415927
#defineIMR*(pmem+0x0000)
#defineIFR*(pmem+0x0001)
#definePMST*(pmem+0x001D)
#defineSWCR*(pmem+0x002B)
#defineSWWSR*(pmem+0x0028)
#defineAL*(pmem+0x0008)
#defineCLKMD0x0058/*clockmodereg*/
#defineLen256
#defineFLen101
doublenpass,h[FLen],x[Len],y[Len],xmid[FLen];
voidfirdes(doublenpass);
unsignedint*pmem=0;
ioportunsignedcharport8001;
intin_x[Len];
intm=0;
intintnum=0;
doublexmean=0;
inti=0;
intflag=0;
doublefs,fstop,r,rm;
inti,j,p,k=0;
voidcpu_init()
{//asm("nop");
//asm("STM#0,CLKMD");
//asm("STM#0,CLKMD");
//asm("rpt#0ffffh");
//asm("nop");
//asm("STM#0x97ff,CLKMD");
*(unsignedint*)CLKMD=0x0;//switchtoDIVmodeclkout=1/2clkin
while(((*(unsignedint*)CLKMD)&01)!
=0);
*(unsignedint*)CLKMD=0x27ff;//switchtoPLLX10mode
PMST=0x3FA0;
SWWSR=0x7fff;
SWCR=0x0000;
IMR=0;
IFR=IFR;}
interruptvoidint2()
{in_x[m]=port8001;
in_x[m]&=0x00FF;
m++;
intnum=m;
if(intnum==Len)
{
intnum=0;
xmean=0.0;
for(i=0;i{
xmean=in_x[i]+xmean;
}
xmean=1.0*xmean/Len;
for(i=0;i{
x[i]=(double)(in_x[i]-xmean);
}
for(i=0;i{
for(p=0;p{
xmid[FLen-p-1]=xmid[FLen-p-2];
}
xmid[0]=x[i];
r=0;
rm=0;
for(j=0;j{
r=xmid[j]*h[j];