DSP课程设计FFT的DSP实现.docx

上传人:b****6 文档编号:7751086 上传时间:2023-01-26 格式:DOCX 页数:17 大小:555.24KB
下载 相关 举报
DSP课程设计FFT的DSP实现.docx_第1页
第1页 / 共17页
DSP课程设计FFT的DSP实现.docx_第2页
第2页 / 共17页
DSP课程设计FFT的DSP实现.docx_第3页
第3页 / 共17页
DSP课程设计FFT的DSP实现.docx_第4页
第4页 / 共17页
DSP课程设计FFT的DSP实现.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

DSP课程设计FFT的DSP实现.docx

《DSP课程设计FFT的DSP实现.docx》由会员分享,可在线阅读,更多相关《DSP课程设计FFT的DSP实现.docx(17页珍藏版)》请在冰豆网上搜索。

DSP课程设计FFT的DSP实现.docx

DSP课程设计FFT的DSP实现

FFT的DSP实现

简介:

快速傅里叶变换是一种高效实现离散傅里叶变换的的快速算法,是数字信号处理中最为重要的工具之一,它在声学、语音、电信和信号处理等领域有着广泛的应用。

一.设计目的:

1.加深对DFT算法原理和基本性质的理解;

2.熟悉FFT的算法原理和FFT子程序的算法流程和应用;

3.学习用FFT对连续信号和时域信号进行频谱分析的方法;

4.学习DSP中FFT的设计和编程思想;

5.学习使用CCS的波形观察窗口观察信号波形和频谱情况。

二.设计内容:

用DSP汇编语言及C语言进行编程,实现FFT运算,对输入信号进行频谱分析。

三.设计原理:

1.离散傅里叶变换DFT:

对于长度为N的有限长序列x(n),它的离散傅里叶变换(DFT)为

X(k)=

N-nk,k=0,1,2……N-1

(1)

式中,WN=e-j*2π/N,称为旋转因子或蝶形因子。

从DFT的定义可以看出,在x(n)为复数序列的情况下,对某个k值,直接按

(1)式计算X(k)只需要N次复数乘法和(N-1)次复数加法。

因此,对所有N个k值,共需要N2次复数乘法和N(N-1)次复数加法。

对于一些相当大有N值(如1024点)来说,直接计算它的DFT所需要的计算量是很大的,因此DFT运算的应用受到了很大的限制。

2.快速傅里叶变换FFT

旋转因子WN有如下的特性。

对称性:

WNk+N/2=-WNk

周期性:

WNn(N-k)=WNk(N-n)=WN-nk

利用这些特性,既可以使DFT中有些项合并,减少了乘法积项,又可以将长序列的DFT分解成几个短序列的DFT。

FFT就是利用了旋转因子的对称性和周期性来减少运算量的。

FFT的算法是将长序列的DFT分解成短序列的DFT。

例如:

N为偶数时,先将N点的DFT分解为两个N/2点的DFT,使复数乘法减少一半:

再将每个N/2点的DFT分解成N/4点的DFT,使复数乘又减少一半,继续进行分解可以大大减少计算量。

最小变换的点数称为基数,对于基数为2的FFT算法,它的最小变换是2点DFT。

一般而言,FFT算法分为按时间抽取的FFT(DIT FFT)和按频率抽取的FFT(DIFFFT)两大类。

DIFFFT算法是在时域内将每一级输入序列依次按奇/偶分成2个短序列进行计算。

而DIFFFT算法是在频域内将每一级输入序列依次奇/偶分成2个短序列进行计算。

两者的区别是旋转因子出现的位置不同,得算法是一样的。

在DIFFFT算法中,旋转因子

出现在输入端,而在DIFFFT算法中它出现在输入端。

假定序列x(n)的点数N是2的幂,按照DIFFFT算法可将其分为偶序列和奇序列。

偶序列:

x(2r)=x1(r)

奇序列:

x(2r+1)=x2(r)

其中:

r=0,1,2,…,N/2-1则x(n)的DFT表示为

式中,x1(k)和x2(k)分别为x1(r)和x2(r)的N/2的DFT

式中,x1(k)和x2(k)分别为x1(r)和x2(r)的N/2的DFT。

由于对称性,WNk+N/2=-WNk。

因此,N点DFT可分为两部分:

前半部分:

x(k)=x1(k)+WkNx2(k)k=0,1,…,N/2-1(4)

后半部分:

x(N/2+k)=x1(k)-WkNx2(k)k=0,1,…,N/2-1(5)

从式(4)和式(5)可以看出,只要求出0~N/2-1区间x1(k)和x2(k)的值,就可求出0~N-1区间x(k)的N点值。

以同样的方式进行抽取,可以求得N/4点的DFT,重复抽取过程,就可以使N点的DFT用上组2点的DFT来计算,这样就可以大减少运算量。

基2DIFFFT的蝶形运算如图(a)所示。

设蝶形输入为X1(K)和X2((K),输出为x(k)和x(N/2+K),则有

x(k)=x1(k)+WkNx2(k)(6)

x(N/2+k)=x1(k)-WkNx2(k)(7)

在基数为2的FFT中,设N=2M,共有M级运算,每级有N/2个2点FFT蝶形运算,因此,N点FFT总共有MN/2个蝶形运算。

 

图(a)基2DIFFFT的蝶形运算

例如:

基数为2的FFT,当N=8时,共需要3级,12个基2DITFFT的蝶形运算。

其信号流程如图(b)所示。

x(0)x(0)

1.WN0

x(4)x

(1)

-1

WN0

x

(2)x

(2)

-1

WN0WN2

x(6)x(3)

-1-1

WN0

x

(1)x(4)

-1

WN0WN1

x(5)x(5)

-1-1

WN0WN2

x(3)x(6)

-1-1

WN0WN2WN3

x(7)x(7)

-1-1-1

图(b)8点基2DIFFFT蝶形运算

从图(b)可以看出,输入是经过比特反转的倒位序列,称为位码倒置,其排列顺序为x(0),x(4),x

(2),x(6),x

(1),x(5),x(3),x(7)。

输出的是按自然顺序排列,其顺序为x(0),x

(1),x

(2),x(3),x(4),x(5),x(6),x(7).

四.FFT算法的DSP实现过程:

DSP芯片的出现使FFT的实现方法变得更为方便。

由于大多数DSP芯片都具有在单指令周期内完成乘法—累加操作,并且提供了专门的FFT指令,使得FFT算法在DSP芯片实现的速度更快。

FFT算法可以分为按时间抽取FFT和按频率抽取FFT两大类,输入也有实数和复数之分,一般情况下,都假定输入序列为复数。

(一)FFT运算序列的存储分配

FFT运算时间是衡量DSP芯片性能的一个重要指标,因此提高FFT的运算速度是非常重要的。

在用DSP芯片实现FFT算法时,应允许利用DSP芯片所提供的各种软、硬件资源。

如何利用DSP芯片的有限资源,合理地安排好所使用的存储空间是十分重要的。

(二)FFT运算的实现

用TMS320C54x的汇编程序实现FFT算法主要分为四步:

1.实现输入数据的比特反转

输入数据的比特反转实际上就是将输入数据进行码位倒置,以便在整个运算后的输出序列是一个自然序列。

在用汇编指令进行码位倒置时,使用码位倒置可以大大提高程序执行速度和使用存储器的效率。

在这种寻址方式下,AR0存放的整数N是FFT点的一半,一个辅助寄存器指向一个数据存放的单元。

当使用位码倒置寻址将AR0加到辅助寄存器时,地址将以位码倒置的方式产生。

2.实现N点复数FFT

N点复数FFT算法的实现可分为三个功能块,即第一级蝶形运算、第二级蝶形运算、第三级至

级蝶形运算。

对于任何一个2的整数幂

,总可以通过M次分解最后成为2点的DFT计算。

通过这样的M次分解,可构成M(即

)级迭代计算,每级由N/2个蝶形运算组成。

3.功率谱的计算

用FFT计算想x(n)的频谱,即计算

X(k)=

X(k)一般是由实部

(k)和虚部

(k)组成的复数,即

X(k)=

(k)+j

(k)

因此,计算功率谱时只需将FFT变换好的数据,按照实部实部

(k)和虚部

(k)求它们的平方和,然后对平方和进行开平方运算。

但是考虑到编程的难度,对于求FFT变换后数据的最大值,不开平方也可以找到最大值,并对功率谱的结果没有影响,所以在实际的DSP编程中省去了开方运算。

4.输出FFT结果

(三)汇编语言程序

程序主体由rfft-task、bit-rev、fft和power四个子程序组成。

rfft-task:

主调用子程序,用来调用其他子程序,实现统一的接口。

bit-rev:

位码倒置子程序,用来实现输入数据的比特反转。

fft:

FFT算法子程序,用来完成N点FFT运算。

在运算过程中,为避免运算结果的溢出,对每个蝶形的运算结果右移一位。

fft子程序分为三个功能块:

第一级蝶形运算、第二级蝶形运算、第三级至至

级蝶形运算。

(四)正弦系数表和余弦系数表:

正弦系数表和余弦系数表可以由数据文件coeff.inc给出,主程序通过.copy汇编命令将正弦和余弦系数表与程序代码汇编在一起。

在本例中,数据文件coeff.inc给出1024复数点FFT的正弦、余弦系数各512个。

利用此系数表可完成8~1024点FFT的运算。

(五)FFT算法的模拟信号输入:

FFT算法的模拟信号输入可以采用C语言编程来生成一个文本文件sindata,然后在rfft-task汇编程序中,通过.copy汇编命令将生成的数据文件复制到数据存储器中,作为FFT算法的输入数据参与FFT运算。

这种方法的优点是程序的可读性强,缺点是当输入数据修改后,必须重新编译、汇编和链接。

五.设计步骤:

1.启动CCS,在CCS中建立一个C源文件和一个命令文件,并将这两个文件添加到工程,再编译并装载程序:

阅读Dsp原理及应用中fft用dsp实现的有关程序。

2.双击

,启动CCS的仿真平台的配着选项。

选择C5502Simulator。

3.启动ccs2后建立工程文件FFT.pjt

4.建立源文件FFT.c与链接文件FFT.cmd

5.将这两个文件加到FFT.pjt这个工程中。

6.创建out文件

7.加载out文件

8.加载数据

9.观察输入输出波形

输入波形(时域)

输出图形(频域)

10.改变信号的频率可以再做次实验。

也可作512点或更多点的FFT.

六.实验程序:

.title"rfft_task.asm"

.mmregs

.copy"coeff.inc"

.defrfft_task

sine:

.usect"sine",512

cosine:

.usect"cosine",512

fft_data:

.usect"fft_data",2048

d_input:

.usect"fft_data",2048

fft_out:

.usect"fft_out",1024

;d_input:

.copysindata

STACK:

.usect"STACK",10

K_DATA_IDX_1.set2

K_DATA_IDX_2.set4

K_DATA_IDX_3.set8

K_FLY_COUNT_3.set4

K_TWID_TBL_SIZE.set512

K_TWID_IDX_3.set128

K_FFT_SIZE.set32

K_LOGN.set5

.bssd_twid_idx,1

.bssd_data_idx,1

.bssd_grps_cnt,1

.sect"rfft_prg"

rfft_rask:

SSBXFRCT

STM#STACK+10,SP

STM#sine,AR1

RPT#K_TWID_TBL_SIZE-1

MVPDsine1,*AR1+

STM#cosine,AR1

RPT#K_TWID_TBL_SIZE-1

MVPDcosine1,*AR1+

CALLbit_rev

CALLfft

CALLpower

RET

************************位码倒置程序bit_rev*******************

.asgAR2,REORDERED

.asgAR3,ORIGINAL_INPUT

.asgAR7,DATA_PROC_BUF

.sect"rfft_prg"

;bit_rev:

STM#d_input,ORIGINAL_INPUT

STM#fft_data,DATA_PROC_BUF

MVMMDATA_PROC_BUF,REORDERED

STM#K_FFT_SIZE-1,BRC

RPTBDbit_rev_end-1

STM#K_FFT_SIZE,AR0

MVDD*ORIGINAL_INPUT+,*REORDERED+

MVDD*ORIGINAL_INPUT-,*REORDERED+

MAR*ORIGINAL_INPUT+0B

;bit_rev_end:

RET

;***********************FFT算法子程序fft**********************;

.asgAR1,GROUP_COUNTER

.asgAR2,PX

.asgAR3,QX

.asgAR4,WR

.asgAR5,WI

.asgAR6,BUTTERFLY_COUNTER

.asgAR7,STAGE_COUNTER

.sect"rfft_prg"

fft:

;***********第1级蝶形运算stage1**************:

STM#0,BK

LD#-1,ASM

STM#fft_data,PX

LD*PX,16,A

STM#fft_data+K_DATA_IDX_1,QX

STM#K_FFT_SIZE/2-1,BRC

RPTBDstage_end-1

STM#K_DATA_IDX_1+1,AR0

SUB*QX,16,A,B

ADD*QX,16,A

STHA,ASM,*PX+

STB,*QX+

||LD*PX,A

SUB*QX,16,A,B

ADD*QX,16,A

STHA,ASM,*PX+0

STB,*QX+0%

||LD*PX,A

;stage1_end:

;***********第2级蝶形运算stage2**************;

STM#fft_data,PX

STM#fft_data+K_DATA_IDX_2,QX

STM#K_FFT_SIZE/4-1,BRC

LD*PX,16,A

RPTBDstage2_end-1

STM#K_DATA_IDX_2+1,AR0

SUB*QX,16,A,B

ADD*QX,16,A

STHA,ASM,*PX+

STB,*QX+

||LD*PX,A

SUB*QX,16,A,B

ADD*QX,16,A

STHA,ASM,*PX+

STHB,ASM,*QX+

MAR*QX+

ADD*PX,*QX,A

SUB*PX,*QX-,B

STHA,ASM,*PX+

SUB*PX,*QX,A

STB,*QX

||LD*QX+,B

STA,*PX

||ADD*PX+0%,A

STA,*QX+0%

||LD*PX,A

;stage2_end:

;***********第3级蝶形运算stage3**************;

STM#K_TWID_TBL_SIZE,BK

ST#K_TWID_IDX_3,d_twid_idx

STM#K_TWID_IDX_3,AR0

STM#cosine,WR

STM#sine,WI

STM#K_LOGN-2-1,STAGE_COUNTER

ST#K_FFT_SIZE/8-1,d_grps_cnt

STM#K_FLY_COUNT_3-1,BUTTERFLY_COUNTER

ST#K_DATA_IDX_3,d_data_idx

;stage:

STM#fft_data,PX

LDd_data_idx,A

ADD*(PX),A

STLMA,QX

MVDKd_grps_cnt,GROUP_COUNTER

;group:

MVMDBUTTERFLY_COUNTER,BRC

RPTBDbutterfly_end-1

LD*WR,T

MPY*QX+,A

MACR*WI+0%,*QX-,A

ADD*PX,16,A,B

STB,*PX

||SUB*PX+,B

STB,*QX

||MPY*QX+,A

MASR*QX,*WR+0%,A

ADD*PX,16,A,B

STB,*QX+

||SUB*PX+,B

LD*WR,T

STB,*PX+

||MPY*QX,A

;butterfly_end:

PSHMAR0

MVDKd_data_idx,AR0

MAR*PX+0

MAR*QX+0

BANZDgroup,*GROUP_COUNTER-

POPMAR0

MAR*QX-

LDd_data_idx,A

SUB#1,A,B

STLMB,BUTTERFLY_COUNTER

STLA,1,d_data_idx

LDd_group_cnt,A

STLA,ASM,d_group_cnt

LDd_twid_idx,A

STLA,ASM,d_twid_idx

BANZDstage,*STAGE_COUNTER-

MVDKd_twid_idx,AR0

;fft_end:

RET

;***********************//功率谱计算子程序power//***********************;

.sect"rfft_prg"

;power:

STM#fft_data,AR2

STM#fft_out,AR4

STM#K_FFT_SIZE*2-1,BRC

RPTBpower_end-1

SQUR*AR2+,A

SQURA*AR2+,A

STHA,*AR4+

;power_end:

RET

.end

链接命令文件rfft_task.cmd清单:

vector.obj

rfft_task.obj

-orfft_task.obj

-mrfft_task.map

-erfft_task

MEMORY{

PAGE0:

EPROM:

org=0E000Hlen=1000H

VECS:

org=0FF80Hlen=0080H

PAGE1:

SPRAM:

org=0060Hlen=0020H

DARAM:

org=0400Hlen=0600H

RAM:

org=8000Hlen=1400H

}

SECTIONS{

sine1:

>EPROMPAGE0

cosine1:

>EPROMPAGE0

fft_prg:

>EPROMPAGE0

.bss:

>SPRAMPAGE1

sine:

align(512){}>DARAMPAGE1

cosine:

align(512){}>DARAMPAGE1

d_input:

>RAMPAGE1

fft_data:

>RAMPAGE1

fft_out:

>RAMPAGE1

STACK:

>SPRAMPAGE1

.vectors:

>VECSPAGE0

}

七.心得体会:

通过这次DSP课程设计,加深对DFT算法原理和基本性质的理解,熟悉了FFT的算法原理和FFT子程序的算法流程和应用,掌握了DSP中FFT的设计和编程思想,以及用FFT对连续信号和时域信号进行频谱分析的方法,和使用CCS的波形观察器观察波形和频谱情况。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1