phase4end:
; [k] = A/2
⒊ 计算所求信号的功率
由于最后所得的FFT数据是一个复数,为了能够方便的在虚拟频谱仪上观察该信号的特征,我们通常对所得的FFT数据进行处理——取其实部和虚部的平方和,即求得该信号的功率。 power:
.asg AR2,AX
.asg AR3,OUTPUT_BUF
pshm st0 pshm ar0 pshm bk
STM #d_output_addr,OUTPUT_BUF STM #K_FFT_SIZE*2-1,BRC RPTBD power_end-4 STM #fft_data,AX SQUR *AX+,A
;AR3指向输出缓冲地址
;块循环计数器设置为255
;保存寄存器的值
;带延迟方式的重复执行指令 ;AR2指向AR[0] ;A := AR2 ;A := AR2 + AI2
;将A中的数据存入输出缓冲中,
;避免输出数据过大在虚拟示波器 ;中显示错误 ;保存各个寄存器值
SQURA *AX+,A
STH A,7,*OUTPUT_BUF
ANDM #7FFFH,*OUTPUT_BUF+
popm bk popm ar0 popm st0 power_end: RET
注意,在上面的程序中将数据放回输出缓冲准备输出时使用了指令:
136
STH A,7,*OUTPUT_BUF
对acc A左移7位是为了让显示的数据值在一个合适的范围内有利于观察显示的图形,由于所有的数据都左移了7位,所以从总体上看整个波形的性质还是一样的。同时,由于有的数据太大,为了避免显示数据的溢出而导致在虚拟示波器中观察到的波形错误所以我们使用了指令:
ANDM #7FFFH,*OUTPUT_BUF+ 来取出有效的数据位数。
图6 设置探针点和断点
三、 实验内容
本实验在CCS下完成256点的实数FFT,并通过CCS的图形显示工具观察结果。其主程序为初始化,并通过探针工具读入256点方波数据(在文件fft.dat中,该数据文件可以通过程序fft_data.c修改,但注意数据的绝对值不要超过0x23ff)。FFT的实现由四个子程序代码bit_rev、fft、unpack和power代码完成。实验可以分为以下几步: (1) 启动CCS,在Project菜单相项中打开FFT目录下的fft.mak文件。
137
(2) 用鼠标展开左面项目栏,打开fft.asm源程序。
(3) 使用Bulid命令完成编译、连接,并使用Load Program将生成的fft.out装入5402片
内存储器。
(4) 将光标移动到“call get_input”行,并设置一个探针点。该行变为兰色。参见图6: (5) 将光标移动到下一行“nop”语句,使用工具
设置一个断点,该行变为洋红色。
(6) 在File菜单中打开选项“File I/O”,使用“Add File”在FFT目录下打开数据文件fft.dat,
然后修改“Address”参数为0x2300,修改“Length”参数为256。这表示程序执行到探针点时,将从fft.dat文件中读出256个数据,并将数据放入0x2300开始的存储器中。你可以选择“Wrap Around”,循环使用该数据文件。
图7 设置探针参数
(7) 选择“Add Probe Point”,将探针点与数据文件连接起来。参见图8。选择探针点, 然后在“Connect”选项中选择需要使用的数据文件名,再选择“Replace”,按确定键完成。这时将返回图7所示的对话框。你可以看到“Probe”项被自动修改为“Connected”,表示探针已经与数据文件成功相连。
(8) 完成探针设置后,可以使用F5或“Run”命令启动程序运行。程序执行到探针点时自动从数据文件读出256个点的数据放入输入缓冲0x2300。 (9)
在“View”菜单项下选择“Graph -> Time/Frequency”,打开一个图形工具以
便显示输入数据波形。将“Start Address”改为0x2300,将“Acquisition Buffer Size”改为128,将“DSP Data Type”改为“16-bit signed integer”,这样即可显示128个输入点波形。
138
(10) 调整窗口显示大小,将光标移动到源程序的“b _c_int00”这行,使用Debug中的“Run to Cursor”项,程序将执行到这行并停下。这时FFT程序已经计算完成。 (11) 再打开一个波形显示窗口,这次仅仅将“Start Address”改为0x2200,便可以显示计算完成后的谱波形。
图8 建立探针点与数据文件的连接
(12) 选择“Debug”下的“Animate”运行程序,这时程序将循环运行,不断从数据文件fft.dat中读出数据,并计算其频谱。这时你可以看到连续的输入/输出波形。 (13) 选择原始数据波形窗口,单击鼠标右键,进入“Properties”属性对话框。你可以将“Display Type”改为“FFT Magnitude”,这时输入数据将显示其频谱,对比两个图形,看看谱线的位置一样吗?
(14) 清除所有断点、探针点,关闭CCS的源程序窗口和上面的工程文件fft.mak,然后在Project菜单下打开BIOS目录下fft.mak文件。这时一个使用DSP/BIOS工具实现FFT的例子。为了使用DSP/BIOS的工具分析工具,我们将FFT的源程序做了一点修改。将FFT子程序做为一个中断函数,并在DSP/BIOS的周期模块中调用。所以在DSP/BIOS的配置文件中增加一个周期模块PRD0,并且设置每1ms执行一次,即每1ms执行一次FFT子程序。参见图9。这时的主程序仅仅完成一次数据输入,然后返回DSP/BIOS。以后DSP/BIOS将每隔1ms启动一次周期函数,完成一次FFT。
139
(15) 在File菜单中用Load Program装入BIOS目录下的demo5402.out文件。参照前面的步骤,在main函数中的“call wait_input”设置一个探针点,并建立数据文件连接。这时应该将输入数据读到0x2900开始的存储器中。在FFT子程序process中设置一个断点,启动程序运行。
(16) 程序将在将在第一次进入周期函数执行FFT子程序时停下来。使用图形工具观察输入信号波形(启始地址0x2900 )。将FFT子程序执行完,然后在使用图形工具观察FFT后的波形(启始地址0x2800)。
(17) 清除所有断点,以便程序连续运行。使用Tools菜单下的DSP/BIOS选项打开“RTA Control Panel”窗口,再打开“Execution Graph”窗口。在“RTA Control Panel”控制窗口中选择“enable SWI logging”、“enable PRD logging”和“gobal host enable”。恢复程序运行,观察FFT程序执行情况。
(18) 在Tools -> DSP/BIOS -> CPU Load Graph 窗口,观察CPU占用情况。修改周期函数的周期,重新编译、连接、装入程序并运行,看看CPU占用比有何变化?
图9 修改DSP/BIOS的配置文件
四、 思考题:
(1)考虑利用位倒序寻址方式对512个数据进行位倒序排序,应该如何编写程序代码?
140
(2)试用一般的指令改写下列并行指令:
① ST B,*AR3+ ||LD *AR2,A ② ST B,*AR2 ||SUB *AR2+0%,B ③ ST B,*PX+ ||MPY *QX+,A
(3)利用前面所讲的思想,请试编写一个128点的实数FFT程序。
(4)结合前面的FIR滤波器实验中串口中断收发程序,将本实验中的FFT程序改为实
时FFT,并用CCS的图形显示工具显示输入波形的频谱。(提示:修改串口接收程序,每接收256点数据调用一次FFT程序。)
141