DSP课程设计FFT的DSP实现.docx
- 文档编号:7751086
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:17
- 大小:555.24KB
DSP课程设计FFT的DSP实现.docx
《DSP课程设计FFT的DSP实现.docx》由会员分享,可在线阅读,更多相关《DSP课程设计FFT的DSP实现.docx(17页珍藏版)》请在冰豆网上搜索。
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的波形观察器观察波形和频谱情况。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DSP 课程设计 FFT 实现