DSP傅里叶变化课程设计.docx
《DSP傅里叶变化课程设计.docx》由会员分享,可在线阅读,更多相关《DSP傅里叶变化课程设计.docx(33页珍藏版)》请在冰豆网上搜索。
DSP傅里叶变化课程设计
实验五:
快速傅立叶变换(FFT)算法实验
一.实验目的
1.掌握用窗函数法设计FFT快速傅里叶的原理和方法;
2.熟悉FFT快速傅里叶特性;
3.了解各种窗函数对快速傅里叶特性的影响。
二.实验设备
1.FFT的原理和参数生成公式
公式
(1)FFT运算公式
FFT并不是一种新的变换,它是离散傅立叶变换(DFT)的一种快速算法。
由于我们在计算DFT时一次复数乘法需用四次实数乘法和二次实数加法;一次复数加法则需二次实数加法。
每运算一个X(k)需要4N次复数乘法及2N+2(N-1)=2(2N-1)次实数加法。
所以整个DFT运算总共需要4N^2次实数乘法和N*2(2N-1)=2N(2N-1)次实数加法。
如此一来,计算时乘法次数和加法次数都是和N^2成正比的,当N很大时,运算量是可观的,因而需要改进对DFT的算法减少运算速度。
根据傅立叶变换的对称性和周期性,我们可以将DFT运算中有些项合并。
我们先设序列长度为N=2^L,L为整数。
将N=2^L的序列x(n)(n=0,1,……,N-1),按N的奇偶分成两组,也就是说我们将一个N点的DFT分解成两个N/2点的DFT,他们又从新组合成一个如下式所表达的N点DFT:
一般来说,输入被假定为连续的。
当输入为纯粹的实数的时候,我们就可以利用左右对称的
特性更好的计算DFT。
我们称这样的RFFT优化算法是包装算法:
首先2N点实数的连续输入称为“进包”。
其次N
点的FFT被连续被运行。
最后作为结果产生的N点的合成输出是“打开”成为最初的与DFT相符合的2N点输入。
使用这战略,我们可以划分FFT的大小,它有一半花费在包装输入O(N)的操作和打开输出上。
这样的RFFT算法和一般的FFT算法同样迅速,计算速度几乎都达到了两次DFT的连续输入。
下列一部分将描述更多的在TMS320C54x上算法和运行的细节。
2.程序流程图
3.程序的自编函数及其功能
rfft_task();
功能:
在C语言中进行汇编调用。
三.实验步骤
1.启动CodeComposerStudio
2.新建工程FFT,建立程序BIT_REV.ASM、FFT.ASM、INITRFFT.ASM、mcbsp54.h、POWER.ASM、rfft.asm、type.h、UNPACK.ASM、VECTORS.ASM、RFFT.CMD,保存在工程目录为F:
\FFT
3.编译并下载程序
4.加入断点,指定输入数据文件
-打开工程中文件rfft.asm
-在第一个“NOP”语句上加探针(ProbePoint)
-在第二个“NOP”语句上加软件断点(BreakPoint)
-在最后一个“NOP”语句上加软件断点(BreakPoint)
5.打开观察窗口
-选择菜单“View”、“Graph”、“Time/Frequency…”进行如下设置:
-在打开的窗口中单击鼠标右键,选择“ClearDisplay”
-选择菜单“File”、“FileI/O…”;单击“AddFile”按钮,选择F:
\FFT\1.DAT文件,单击“打开”按钮;在“Adress”中输入real_fft_in,在“Length”中输入128;在“WarpAround”项前面加上选中符号;单击“AddProbePoint”按钮。
-单击“ProbePoint”列表中的“rfft.asmline34”行;在“Connect”项选择“FILEIN:
F:
\..\1.DAT”;单击“Replace”按钮;单击“确定”按钮。
-单击“确定”按钮。
-再次选择菜单“View”、“Graph”、“Time/Frequency…”进行如下设置:
-在打开的窗口中单击鼠标右键,选择“ClearDisplay”
6.按F5或选择debug菜单下的run来运行程序;当程序停止在软件断点时可在“Input”窗口中观察到输入波形,为一正弦波。
7.按F5或选择debug菜单下的run运行程序;当程序停止在软件断点时可在“Output”窗口中观察到输出波形。
8.重复第5步,将输入波形文件改为2.DAT,选择“Debug”菜单“Restart”项,程序将重新开始,再做第6,7步。
四.实验结果
输入波形为一个低频率的正弦波,输出波形为此波形经fft运算后的显示。
*步骤7实验现象图:
-输入波形时域图和频域图:
-输出波形图:
*步骤8实验现象图:
-输入波形时域图和频域图:
输出波形图:
通过观察频域和时域图,可以验证fft运算后的结果是否正确。
五.问题与思考
试选用不同点数的fft运算法则来运算。
六.参考程序
1.BIT_REV.ASM
.mmregs
.include"fft_size.inc"
.defbit_rev
.ref_real_fft_input,fft_data
.asgAR2,REORDERED_DATA
.asgAR3,ORIGINAL_INPUT
.asgAR7,DATA_PROC_BUF
.text
bit_rev:
SSBXFRCT;fractionalmodeison
STM#_real_fft_input,ORIGINAL_INPUT;AR3->1storiginalinput
STM#fft_data,DATA_PROC_BUF;AR7->dataprocessingbuffer
MVMMDATA_PROC_BUF,REORDERED_DATA;AR2->1stbit-reverseddata
STM#K_FFT_SIZE-1,BRC
RPTBDbit_rev_end-1
STM#K_FFT_SIZE,AR0;AR0=1/2sizeofcircbuffer
MVDD*ORIGINAL_INPUT+,*REORDERED_DATA+
MVDD*ORIGINAL_INPUT-,*REORDERED_DATA+
MAR*ORIGINAL_INPUT+0B
bit_rev_end:
RET;returntoRealFFTmainmodule
.end
2.FFT.ASM
.mmregs
.include"fft_size.inc"
.reffft_data,d_grps_cnt,d_twid_idx,d_data_idx,sine,cosine
.asgAR1,GROUP_COUNTER
.asgAR2,PX
.asgAR3,QX
.asgAR4,WR
.asgAR5,WI
.asgAR6,BUTTERFLY_COUNTER
.asgAR7,DATA_PROC_BUF;forStages1&2
.asgAR7,STAGE_COUNTER;fortheremainingstages
K_ZERO_BK.set0
K_TWID_TBL_SIZE.set512;Twiddletablesize
K_DATA_IDX_1.set2;DataindexforStage1
K_DATA_IDX_2.set4;DataindexforStage2
K_DATA_IDX_3.set8;DataindexforStage3
K_FLY_COUNT_3.set4;ButterflycounterforStage3
K_TWID_IDX_3.set128;TwiddleindexforStage3
.deffft
.text
;fft:
fft:
;Stage1----------------------------------------------------------------------
STM#K_ZERO_BK,BK;BK=0sothat*ARn+0%==*ARn+0
LD#-1,ASM;outputsdivby2ateachstage
MVMMDATA_PROC_BUF,PX;PX->PR
LD*PX,16,A;A:
=PR
STM#fft_data+K_DATA_IDX_1,QX;QX->QR
STM#K_FFT_SIZE/2-1,BRC
RPTBDstage1end-1
STM#K_DATA_IDX_1+1,AR0
SUB*QX,16,A,B;B:
=PR-QR
ADD*QX,16,A;A:
=PR+QR
STHA,ASM,*PX+;PR':
=(PR+QR)/2
STB,*QX+;QR':
=(PR-QR)/2
||LD*PX,A;A:
=PI
SUB*QX,16,A,B;B:
=PI-QI
ADD*QX,16,A;A:
=PI+QI
STHA,ASM,*PX+0;PI':
=(PI+QI)/2
STB,*QX+0%;QI':
=(PI-QI)/2
||LD*PX,A;A:
=nextPR
stage1end:
;Stage2----------------------------------------------------------------------
MVMMDATA_PROC_BUF,PX;PX->PR
STM#fft_data+K_DATA_IDX_2,QX;QX->QR
STM#K_FFT_SIZE/4-1,BRC
LD*PX,16,A;A:
=PR
RPTBDstage2end-1
STM#K_DATA_IDX_2+1,AR0
;1stbutterfly
SUB*QX,16,A,B;B:
=PR-QR
ADD*QX,16,A;A:
=PR+QR
STHA,ASM,*PX+;PR':
=(PR+QR)/2
STB,*QX+;QR':
=(PR-QR)/2
||LD*PX,A;A:
=PI
SUB*QX,16,A,B;B:
=PI-QI
ADD*QX,16,A;A:
=PI+QI
STHA,ASM,*PX+;PI':
=(PI+QI)/2
STHB,ASM,*QX+;QI':
=(PI-QI)/2
;2ndbutterfly
MAR*QX+
ADD*PX,*QX,A;A:
=PR+QI
SUB*PX,*QX-,B;B:
=PR-QI
STHA,ASM,*PX+;PR':
=(PR+QI)/2
SUB*PX,*QX,A;A:
=PI-QR
STB,*QX;QR':
=(PR-QI)/2
||LD*QX+,B;B:
=QR
STA,*PX;PI':
=(PI-QR)/2
||ADD*PX+0%,A;A:
=PI+QR
STA,*QX+0%;QI':
=(PI+QR)/2
||LD*PX,A;A:
=PR
stage2end:
;Stage3thruStagelogN-1----------------------------------------------------
STM#K_TWID_TBL_SIZE,BK;BK=twiddletablesizealways
ST#K_TWID_IDX_3,d_twid_idx;initindexoftwiddletable
STM#K_TWID_IDX_3,AR0;AR0=indexoftwiddletable
STM#cosine,WR;initWRpointer
STM#sine,WI;initWIpointer
STM#K_LOGN-2-1,STAGE_COUNTER;initstagecounter
ST#K_FFT_SIZE/8-1,d_grps_cnt;initgroupcounter
STM#K_FLY_COUNT_3-1,BUTTERFLY_COUNTER;initbutterflycounter
ST#K_DATA_IDX_3,d_data_idx;initindexforinputdata
stage:
STM#fft_data,PX;PX->PR
LDd_data_idx,A
ADD*(PX),A
STLMA,QX;QX->QR
MVDKd_grps_cnt,GROUP_COUNTER;AR1containsgroupcounter
group:
MVMDBUTTERFLY_COUNTER,BRC;#ofbutterfliesineachgroup
RPTBDbutterflyend-1
LD*WR,T;T:
=WR
MPY*QX+,A;A:
=QR*WR||QX->QI
MACR*WI+0%,*QX-,A;A:
=QR*WR+QI*WI
;||QX->QR
ADD*PX,16,A,B;B:
=(QR*WR+QI*WI)+PR
STB,*PX;PR':
=((QR*WR+QI*WI)+PR)/2
||SUB*PX+,B;B:
=PR-(QR*WR+QI*WI)
;||PX->PI
STB,*QX;QR':
=(PR-(QR*WR+QI*WI))/2
||MPY*QX+,A;A:
=QR*WI[T=WI]
;||QX->QI
MASR*QX,*WR+0%,A;A:
=QR*WI-QI*WR
ADD*PX,16,A,B;B:
=(QR*WI-QI*WR)+PI
STB,*QX+;QI':
=((QR*WI-QI*WR)+PI)/2
;||QX->QR
||SUB*PX,B;B:
=PI-(QR*WI-QI*WR)
LD*WR,T;T:
=WR
STB,*PX+;PI':
=(PI-(QR*WI-QI*WR))/2
;||PX->PR
||MPY*QX+,A;A:
=QR*WR||QX->QI
butterflyend:
;Updatepointersfornextgroup
PSHMAR0;preserveAR0
MVDKd_data_idx,AR0
MAR*PX+0;incrementPXfornextgroup
MAR*QX+0;incrementQXfornextgroup
BANZDgroup,*GROUP_COUNTER-
POPMAR0;restoreAR0
MAR*QX-
;Updatecountersandindicesfornextstage
LDd_data_idx,A
SUB#1,A,B;B=A-1
STLMB,BUTTERFLY_COUNTER;BUTTERFLY_COUNTER=#flies-1
STLA,1,d_data_idx;doubletheindexofdata
LDd_grps_cnt,A
STLA,ASM,d_grps_cnt;1/2theoffsettonextgroup
LDd_twid_idx,A
STLA,ASM,d_twid_idx;1/2theindexoftwiddletable
BANZDstage,*STAGE_COUNTER-;AR0=indexoftwiddletable
MVDKd_twid_idx,AR0
Fft_end:
RET;returntoRealFFTmainmodule
.end
3.INITRFFT.ASM
.include"fft_size.inc"
.deffft_data,_real_fft_input,_real_fft_in,real_fft_output,sine,cosine
.defFFT_DP,d_grps_cnt,d_twid_idx,d_data_idx,BOS,TOS
;Setstartaddressesofbuffers
.data
fft_data.space2*K_FFT_SIZE*16;fftdataprocessingbuffer
_real_fft_input.space2*K_FFT_SIZE*16;realfftinputbuffer
_real_fft_in.space2*K_FFT_SIZE*16;realfftinputbuffer
.sect"power"
real_fft_output.space2*K_FFT_SIZE*16;realfftoutputbuffer(power)
;Copytwiddletables
.sect"sin_tbl"
sine.copytwiddle1;sinetable
.sect"cos_tbl"
cosine.copytwiddle2;cosinetable
;Definevariablesforindexinginputdataandtwiddletables
FFT_DP.usect"fft_vars",0
d_grps_cnt.usect"fft_vars",1;(#groupsincurrentstage)-1
d_twid_idx.usect"fft_vars",1;indexoftwiddletables
d_data_idx.usect"fft_vars",1;indexofinputdatatable
;Setupstack
BOS.usect"stack",0Fh
TOS.usect"stack",1
.end
4.mcbsp54.h
#ifndef_MCBSP_H_
#define_MCBSP_H_
#include"regs54xx.h"
/*Bits,Bitfields,...*/
#defineMCBSP_RX1
#defineMCBSP_TX2
#defineMCBSP_BOTH3
/*CONFIGURATIONREGISTERBITandBITFIELDvalues*/
/*SerialPortControlRegisterSPCR1*/
#defineDLB_ENABLE0x01/*EnableDigitalLoopbackMode*/
#defineDLB_DISABLE0x00/*DisableDigitalLoopbackMode*/
#defineRXJUST_RJZF0x00/*ReceiveRightJustifyZeroFill*/
#defineRXJUST_RJSE0x01/*ReceiveRightJustifySignExtend*/
#defineRXJUST_LJZF0x02/*ReceiveLeftJustifyZeroFill*/
#defineCLK_STOP_DISABLED0x00/*Normalclockingfornon-SPImode*/
#defineCLK_START_W/O_DELAY0x10/*Clockstartswithoutdelay*/
#defineCLK_START_W_DELAY0x11/*Clockstartswithdelay*/
#defineDX_ENABLE_OFF0x00/*noextradelayforturn-ontime*/
#defineDX_ENABLE_ON0x01/*enableextradelayforturn-ontime*/
#defineABIS_DISABLE0x00/*A-bismodeisdisabled*/
#defineABIS_ENABLE0x01/*A-bismodeisenabled*/
/*SerialPortControlRegistersSPCR1andSPCR2*/
#defineINTM_RDY0x00/*R/XINTdrivenbyR/XRDY*/
#defineINTM_BLOCK0x01/*R/XINTdrivenbynewmultichannelblk*/
#defineINTM_FRAME0x02/*R/XINTdrivenbynewframesync*/
#defineINTM_SYNCERR0x03/*R/XINTgeneratedbyR/XSYNCERR*/
#defineRX_RESET0x00/*RorXinreset*/
#defineRX_ENABLE0x01/*RorXenabled*/
/*SerialPortControlRegisterSPCR2*/
#defineSP_FREE_OFF0x00/*Freerunningmodeisdiabled*/
#defineSP_FREE_ON0x01/*Freerunningmodeisenabled*/
#defineSOFT_DISABLE0x00/*SOFTmodeisdisabled*/
#defineSOFT_ENABLE0x01/*SOFTmodeisenabled*/
#defineFRAME_GEN_RESET0x00/*FrameSynchronizationlogicisreset*/
#defineFRAME_GEN_ENABLE0x01/*FramesyncsignalFSGisgenerated*/
#defineSRG_RESET0x