实验报告
实 验 名 称
FFT 的实现
FIR 数字滤波器的实现
课 程 名 称
高速 DSP 原理与应用
任 课 老 师
姓
学
班
日
名
号
级
期
刘建国
魏文鹏
2009300827
03040901
2012 年 5 月
1
一、实验目的
学习和掌握 FFT 的定点 DSP 实现原理及 C28X 编程的技巧,并通过 CCS 的图形显
示工具,观察输入/输出信号波形以及它们的频谱变化。
二、实验要求
在 CCS 环境中用汇编语言,编写实现 FFT 的程序及连接器命令文件,编译调试程
序,并通过 CCS 的图形显示工具观察输入/输出信号波形以及频谱变化。
三、实验原理
(1) 位反转
(2) 蝶形运算
在 DIF-FFT 蝶形运算结构中,输出 X(k)按正常顺序存放在存储单元中,即按 X(0)、
X(1)、X(2)、…X(6)、X(7)的顺序排列,输入 x(n)是按 x(0)、x(4)、x(2) …x(3)、
x(7)的顺序进行寻址。反转实现用“*BR0++”寻址方式即可。
如果蝶形运算的两个输入相距 B 个点,应用原位运算,则
)(
JX
WBJ
)(
J
X
X
)
(
L
1
L
L
1
P
N
BJX
)
(
L
X
)(
J
X
(
L
1
L
1
WBJ
)
P
N
式中,第 L 级的旋转因子指数
p
J
2
LM
,
J
2...2,1,0
L
1
1
,
L=1,2, …, M=log2N, B=
(3) 基 2DIT-FFT 运算流图
12 L
2
(3)算法流程图
四、实验环境
软件环境:CCS3.1
硬件环境:无
本实验需要使用 C28X 汇编语言来实现 FFT,并通过 CCS 的图形显示工具观
察输入\输出信号波形以频谱的变化。实验步骤如下:
五、实验过程、数据记录、处理及结论
1、实验步骤
(1) 启动 CCS,通过 project 创建工程文件。
(2) 编写 CMD 文件和汇编源程序。
(3) 编译、连接、单步执行,检查程序的语法错误,检查程序逻辑错误。
(4) 完成编译、连接。然后选择 File/Load Program 命令将 OUT 文件装入。点 RUN 启
动程序运行。
3
(5) 借助 view/Graph 设置观察波形,并记录。
2、波形记录
输入单频正弦波,起始地址 FirstIn。波形图一所示,他的频谱如图二所示
图一
图二
4
输出单频正弦波频谱,起始地址 VAR_FIRST,波形如图三所示
3、实验结论
输入单频正弦波结果输出脉冲波形很好的验证了 FFT 程序的逻辑和代码编程
图三
的正确性。
六、讨论
通过这次编程实验,我进一步掌握了 FFT 的算法。它具有原位运算、蝶形运算、
位倒序的特点。编程中发现了自己对 DSP 编码并不熟练,且存在许多问题,错误。完
成后,自我感觉学到了很多,也有一种成就感。
var_x:
;输入 X 矩阵 VAR_FIRST 和 VARZ_END
七.附录(原程序代码)
;;fft.asm 文件
.sect ".xn"
.copy "VAR.asm"
.data
.global mystart,_c_int00
.byte 00h
.byte 9h
.word 00h
.word 00h
.word 00h
.word 00h
M:
L:
B:
J:
p1:
K:
SAVE_Y:
;FirstIn 和 LastIn 分别为输入的起始值和终止值
.copy "FFT_Input.txt"
YINZI:
; 旋转因子矩阵 XZ 为起始值
.copy "YINZI.txt"
.text
5
_c_int00:
mystart:
N .set 1024
YZ .set 512
C28OBJ
C28ADDR
.c28_amode
;movw dp,#FirstIn
movl xar2,#FirstIn
movl xar3,#VAR_FIRST;;倒序处理
mov @ar0,#N
mov ar1,#N-1
nop*,arp2
setc amode
.lp_amode
loop: mov al,*++,arp3
mov *br0++,al,arp1
xbanz loop,*--,arp2;倒序之后
loop1: mov @@L,#1
;add ar1,#1
mov al,#2 ;;b=2l-1
mov t,@@L-1
lsl al,t
mov @@B,al
loop2: mov @@J,#0 ;;j xunhuan
mov al,@@M
sub
al,@@L
mov t,al
mov al,#2
lsl al,t
mov t,al
mpy acc,t,@@J;;与 add ar4,#1 相关
movl @@p1,acc
loop3: mov al,@@J
mov @@K,al
;;乘加法运算
movl xar3,#VAR_FIRST
movl xar1,@@K
mov al,*+xar1[ar1] ;;al 存 x(k)
mov ah,@@K
add ah,@@B
mov ar1,ah
6
;;修改 VAR_FIRST 偏移量指向 x(k+B)
mov ah,#0
;;movl xar3, #VAR_FIRST
movl xar0,@@p1
movl xar2,#YINZI
mov t ,*+xar2[ar0]
mpy p,t,*+xar3[ar1] ;;与因子相乘结果存 p
subl acc,p
;;修改指针使指回到 x(k)
;;x(k)存入
mov *+xar3[ar1],acc ;;a(k+B)存入
mov al,ar1
sub al,@@B
mov ar1,al
mov acc,@p
addl *+xar3[ar1],acc
;;乘法结束,第一层循环修改
mov ah,@@B
lsl ah,#1
add @@K,ah
mov ah,@@K
cmp ah,@@N-1
b loop3,leq
;第二层循环修改
add @@J,#1
mov al,@@J
cmp al,@@B-1
b loop2,leq
;;第三层循环修改
mov al,@@L
add al,#1
cmp al,@@M
b loop1,leq
.end
CMD 文件
-e _c_int00t
MEMORY
{
/*设置入口地址 */
PAGE 0 : PROG(R)
PAGE 1 : XN(RW)
PAGE 1 : RAM(RW)
PAGE 1 : RAM1(RW)
}
: origin = 0x3f8000, length = 0x10000
: origin = 0x000100, length = 0x0400 /* 为循环寻址定义一段地址*/
: origin = 0x002000, length = 0x02000
: origin = 0x004000, length = 0x02000
7
SECTIONS
{
.text
: > PROG,
PAGE = 0
.xn
: > RAM1, PAGE = 1
.data
: > RAM, PAGE=1
}
8