《基于DSP的快速傅立叶变换(FFT)的实现(汇编语言)》由会员分享,可在线阅读,更多相关《基于DSP的快速傅立叶变换(FFT)的实现(汇编语言)(13页珍藏版)》请在金锄头文库上搜索。
1、.快速傅立叶变换(FFT)的实现一、实验目的1.了解FFT的原理及算法;2.了解DSP中FFT的设计及编程方法;3.熟悉FFT的调试方法;二、实验原理FFT是一种高效实现离散付立叶变换的算法,把信号从时域变换到频域,在频域分析处理信息。对于长度为N的有限长序列x(n),它的离散傅里叶变换为: ,称为旋转因子,或蝶形因子。 在x(n)为复数序列的情况下,计算X(k): 对某个k值,需要N次复数乘法、(N-1)次复数加法;对所有N个k值,需要次复数乘法和N(N-1)次复数加法。对于N相当大时(如1024)来说,直接计算它的DFT所作的计算量是很大的,FFT的基本思想在于:利用的周期性即: 对称性:
2、将原有的N点序列分成两个较短的序列,这些序列的DFT可以很简单的组合起来得到原序列的DFT。按时间抽取的FFTDIT FFT信号流图如图5.1所示:图5.1 时间抽取的FFTDIT FFT信号流图FFT算法主要分为以下四步。第一步 输入数据的组合和位倒序把输入序列作位倒序是为了在整个运算最后的输出中得到的序列是自然顺序。第二步 实现N点复数FFT 第一级蝶形运算;第二级蝶形运算;第三级至log2N级蝶形运算;FFT运算中的旋转因子是一个复数,可表示: 为了实现旋转因子的运算,在存储空间分别建立正弦表和余弦表,每个表对应从0度到180度,采用循环寻址来对正弦表和余弦表进行寻址。 第三步 功率谱的
3、计算 X(k)是由实部和虚部组成的复数:;计算功率谱时只需将FFT变换好的数据,按照实部和虚部求它们的平方和,然后对平方和进行开平方运算。 第四步 输出FFT结果。三、实验内容与步骤. 本实验要求使用FFT变换求一个时域信号的频域特性,并从这个频域特性求出该信号的频率值,然后使用DSP汇编语言对FFT的DSP编程。. 将计算机与DES-320PPA教学实验系统连接好,打开实验箱电源,然后运行CCS软件。2.新建fft.pjt工程文件,并输入FFT的DSP程序及命令链接文件。如下:*Radix-2,DIT,Real-input FFT Program * fft.asm *.mmregs.glo
4、bal reset,start,sav_sin,sav_idx,sav_grp .def start,_c_int00 .data DATA.space1024 .copy fft.inc N.set128LOGN.set7 sav_grp.usecttempv,3sav_sin.setsav_grp+1sav_idx.setsav_grp+2OUTPUT.usectOUTPUT,256BOS.usectstack,0FhTOS.usectstack,1 .copy twiddle1.inc .copy twiddle2.inc.text_c_int00b start nopnopstart:
5、STM#TOS,SPLD#0,DPSSBXFRCT STM #2*N,BK STM#INPUT,AR3STM#DATA,AR7MVMMAR7,AR2STM#N-1,BRCRPTBDplend-1STM #N,AR0LDM AR3,A READA *AR2+ ADD #1,AREADA *AR2+MAR*AR3+0Bplend:STM#0,BKLD#-1,ASMMVMMAR7,AR2STM#DATA+2,AR3STM #N/2-1,BRCLD*AR2,16,ARPTBDs1end-1STM#3,AR0SUB*AR3,16,A,BADD*AR3,16,ASTHA,ASM,*AR2+STB,*AR3
6、+|LD*AR2,ASUB*AR3,16,A,BADD*AR3,16,ASTHA,ASM,*AR2+0STB,*AR3+0%|LD*AR2,As1end:MVMMAR7,AR2STM#DATA+4,AR3STM#N/4-1,BRCLD*AR2,16,ARPTBDs2end-1STM#5,AR0SUB*AR3,16,A,BADD*AR3,16,ASTHA,ASM,*AR2+STB,*AR3+|LD*AR2,ASUB*AR3,16,A,BADD*AR3,16,ASTHA,ASM,*AR2+STHB,ASM,*AR3+MAR*AR3+ADD*AR2,*AR3,ASUB*AR2,*AR3-,BSTHA
7、,ASM,*AR2+SUB*AR2,*AR3,ASTB,*AR3|LD*AR3+,BSTA,*AR2|ADD*AR2+0%,ASTA,*AR3+0%|LD*AR2,As2end:STM#512,BKST#128,sav_sinSTM#128,AR0STM#TWI2,AR4STM #TWI1,AR5STM#-3+LOGN,AR7ST#-1+N/8,sav_grpSTM#3,AR6ST#8,sav_idxstage:STM#DATA,AR2LDsav_idx,AADD*(AR2),ASTLMA,AR3MVDKsav_grp,AR1group: MVMDAR6,BRCRPTBDbend-1LD*AR
8、4,TMPY*AR3+,AMACR*AR5+0%,*AR3-,AADD*AR2,16,A,BSTB,*AR2|SUB*AR2+,BSTB,*AR3|MPY*AR3+,AMASR*AR3,*AR4+0%,AADD*AR2,16,A,BSTB,*AR3+|SUB*AR2,BLD*AR4,TSTB,*AR2+|MPY*AR3+,Abend:PSHMAR0MVDKsav_idx,AR0MAR*AR2+0MAR*AR3+0BANZDgroup,*AR1-POPMAR0MAR*AR3-LDsav_idx,ASUB#1,A,BSTLMB,AR6STLA,1,sav_idxLDsav_grp,ASTLA,AS
9、M,sav_grpLDsav_sin,ASTLA,ASM,sav_sinBANZDstage,*AR7-MVDKsav_sin,AR0STM#DATA+2,AR2STM#DATA+2*N-2,AR3STM#DATA+2*N+3,AR7STM#DATA+4*N-1,AR6STM#-2+N/2,BRCRPTBDp3end-1STM#3,AR0ADD*AR2,*AR3,ASUB *AR2,*AR3,BSTHA,ASM,*AR2+STHA,ASM,*AR3+STHB,ASM,*AR6-NEGBSTHB,ASM,*AR7-ADD*AR2,*AR3,ASUB*AR2,*AR3,BSTHA,ASM,*AR2
10、+STHA,ASM,*AR3-0STHB,ASM,*AR6-NEGBSTHB,ASM,*AR7+0p3end:ST#0,*AR6-ST#0,*AR6p3test:STM#DATA,AR2STM#DATA+1,AR4STM#DATA+2*N+1,AR5ADD*AR2,*AR4,ASUB*AR2,*AR4,BSTHA,ASM,*AR2+ST#0,*AR2MVDD*AR2+,*AR5-STHB,ASM,*AR5STM#DATA+4*N-1,AR3STM#TWI2+512/N,AR4STM#TWI1+512/N,AR5STM#N-2,BRCRPTBDp4end-1STM#512/N,AR0LD*AR2
11、+,16,AMACR*AR4,*AR2,AMASR*AR5,*AR3-,ALD*AR3+,16,BMASR*AR5+0%,*AR2-,BMASR*AR4+0%,*AR3,BSTHA,ASM,*AR2+STHB,ASM,*AR2+NEGBSTHB,ASM,*AR3-STHA,ASM,*AR3-p4end:power:STM #OUTPUT,AR3;AR3指向输出缓冲地址 STM #255,BRC;块循环计数器设置为255 RPTBD power_end-1;带延迟方式的重复执行指令 STM #DATA,AR2;AR2指向AR0 SQUR*AR2+,A;A := AR2 SQURA *AR2+,A;A := AR2 + AI2 STH A,7,*AR3;将A中的数据存入输出缓冲中, ANDM#7FFFH,*AR3+;避免输出数据过大在虚拟示波器中显示错误pow