FFT的定点DSP实现

FFT的定点DSP实现
FFT的定点DSP实现

1 引言

CCS(Code Composer Studio)是TI公司的DSP集成开发环境。它提供了环境配置、源文件编辑、程序调试、跟踪和分析等工具,帮助用户在一个软件环境下完成编辑、编译链接、调试和数据分析等工作。与TI提供的早期软件开发工具相比,利用CCS能够加快软件开发进程,提高工作效率。CCS一般工作在两种模式下:软件仿真器和与硬件开发板相结合的在线编程。前者可以脱离DSP芯片,在PC机上模拟DSP指令集与工作机制,主要用于前期算法实现和调试。后者实时运行在DSP芯片上,可以在线编制和调试应用程序。

2 C语言和汇编语言的混合编程

TMS320 C5000系列的软件设计通常有三种方法:

(1) 用C语言开发;

(2) 用汇编语言开发;

(3) C和汇编的混合开发。

其中用C语言开发具有兼容性和可移植的优点,有利于缩短开发周期和减少开发难度,但是在运算量较大的情况下,C代码的效率还是无法和手工编写的汇编代码的效率相比,比如FFT运算,用汇编语言开发的效率高,程序执行速度快,而且可以合理利用芯片的硬件资源,但是开发难度较大,开发周期长,而且可读性和可移植性差。C和汇编的混合编程则可以充分利用前两者的优点,以达到最佳利用DSP资源的目的。但是,采用C和汇编语言混合编程必须遵循相关函数调用规则和寄存器调用规则,否则会给程序的开发带来意想不到的问题。

2.1 C语言和汇编语言混合编程的四种方法

(1) 独立编写汇编程序和C程序,分开编译或汇编成各自的目标代码模块,再用链接器将二者链接起来。这种方法比较灵活,但是设计者必须自己维护各汇编模块的入口和出口代码,自己计算传递的参数在堆栈中的偏移量,工作量较大,但是能做到对程序的绝对控制。

(2) 在C程序中使用汇编程序中定义的变量和常数。

(3) 在C程序中内嵌汇编语句。这种方法可以实现C语言无法实现的一些硬件控制功能,如修改中断控制寄存器。

(4) 将C语言编译生成相应的汇编代码,手工修改和优化C编译器生成的汇编代码。采用这种方法可以控制C编译器,从而产生具有交叉列表的汇编程序,而设计者可以对其中的汇编语句进行修改,然后对汇编程序进行编译,产生目标文件。

后3种方法由于在C中直接嵌入了汇编语言,易造成程序混乱,破坏C环境,甚至导致程序崩溃,而开发者又很难对不良结果进行预期和有效控制。而如果采用第一种方法,只要遵循有关C语言函数调用规则和寄存器规则,就能预见到程

序运行的结果,保证程序正确。

2.2 编程注意事项

C编译器对函数调用制定了一组严格的规则。除了特殊的运行时间支持库函数外,任何调用函数和被C函数调用的函数都必须遵守这些规则。结合作者在编程中的实际情况和切身体会,提出在编程时要注意以下几点:

(1) 必须保护任何被函数修正的专用寄存器。这些专用寄存器包

括:AR1,AR6,AR72和堆栈指针(SP)。其中,如果对SP正常使用,则不必明显的保存。换句话说,只要汇编函数在调用返回时弹出压入的对象,实际上就已经保护了SP。

(2) 中断函数必须保存其使用的所有寄存器。

(3) 从汇编函数中调用C函数时,第一个参数(最左边的)必须放入累加

器A中,剩下的参数按照自右向左的顺序压入堆栈。

(4) 如果函数有返回值,则返回值存放在累加器A中。

(5) 调用C函数时,注意C函数只保护了几个特定的寄存器,对于其他寄存器C函数是可以自由使用的。

(6) 长整数和浮点数存储在存储器中的方法是最高有效字在低位地址。

(7) 汇编语言模块不能改变由C模块产生的.cinit段,如果改变其中的内容将会引起不可预测的后果。

(8) 在汇编语言模块中,对可以从C中访问的变量和函数名需加上前缀“_”。对于仅用于汇编语言模块中的标识符,不用加下划线。而且如果仅在汇编中使用,只要不加下划线,即使与C程序中定义的对象名相同,也不会造成冲突。

(9) 任何在汇编语言模块中声明的将要从C访问或调用的对象或函数,

都必须在汇编语言中用.global伪指令声明为全局变量。同样,任何在C程序中定义而将在汇编中访问或调用的对象或函数,在汇编中也必须用.global声明。

(10) 在默认的情况下,编译器总是认为CPL为1。因此,若在汇编程序中将CPL清0,则在返回C环境时,必须将其恢复为1;在默认的情况下,编译器总是认为 OVM为0。因此,若在汇编程序中将OVM置为1,则返回C环境时,必须将其恢复为0;ARP在函数进入和返回时,必须为0,即当前辅助寄存器为AR0。函数执行时可

以为其他值。

3 编程实例

3.1 FFT算法简介

FFT是一种高效实现离散傅立叶变换的算法,在数字信号处理系统中,FFT 作为一个非常重要的工具,甚至成为DSP运算能力的一个考核因素。如何将FFT 算法很好的应用到DSP系统中对于DSP系统的设计具有重要的意义。

一个优化的实数FFT算法是一个组合以后的算法。该算法主要分为以下几步,首先将输入的2N点实序列进行位倒序组合成一个N点的复序列,之后对复序列进行N 点的FFT运算,最后再由N点的复数输出拆散成2N点的复数序列,这2N点的复数序列与原始的2N点的实数输入序列的DFT输出一致。(详细的算法介绍可参考相关信号处理书籍)。

3.2 C主程序

#include "stdlib.h"

extern void fft(); // FFT运算函数

int DisData[256]; // 输出结果

int SimData[256]={

0,6270,11585,15137, 16384, 15137, 11585,6270,

0, -6270, -11585,-15137,-16384,-15137,-11585,-6270,

……

0,6270,11585,15137,16384,15137,11585,6270,

0,-6270,-11585,-15137,-16384,-15137,-11585,-6270

};

// 输入数据

int main()

{

rfft();

// 调用FFT函数

while(1) ;

}

本程序中FFT运算所用到的数据是通过matlab仿真产生的,然后通过全局数组进行传值,这种方式的优点是数据的通用性强,方便对数据进行其他相关处理; 也可通过其他C程序产生然后保存到一个文本文件中,再由汇编程序将该数据文件拷到数据存储器中参与FFT运算。这种方式的优点是程序的可读性强,缺点是当输入数据修改后,必须进行重新编译、汇编和链接。

3.3 汇编程序

.mmregs

.global sav_sin,sav_idx,sav_grp,_rFFT,_DisData

.data

DATA .space 1024 ;数据缓冲区

INPUT .set 0x9000 ;输入数据起始地址

N .set 128 ;复数点数

LOGN .set 7 ;碟形运算级数

sav_grp .usect "tempv",3 ;定义组变量值

sav_sin .set sav_grp+1 ;定义旋转因子表

sav_idx .set sav_grp+2

.copy "twiddle1.inc" ;正弦表系数

.copy "twiddle2.inc" ;余弦表系数

.text

_rfft:

SSBX TC

SSBX C

RSBX OVA

RSBX OVB

LD #0,DP

RSBX CPL

SSBX XF

SSBX SXM

LD #00,ASM

SSBX FRCT

……

本程序主要是对输入的256点实数作FFT运算,通过修改N和LOGN可以完成16-1024点的FFT运算。在编写汇编程序的时候要注意以下几个方面:

(1) 由于采用循环寻址来对旋转因子表寻址,因此每张表的开始地址必须是10个LSB位为0的地址。如:正弦表系数可以放在0400h开始的地址,余弦表系数可以放在0800h开始的地址;

(2) 在汇编程序的入口处要注意设置好汇编程序所需要的运行环境(见前述程序),如果此处按照编译器默认的环境将得不到正确的结果。详细的汇编程序可参考TI公司提供的例程。

3.4 运算结果

输入正弦信号的频率为f=16Hz,幅值为1(单位),采样长度为2N=256点,采样频率为fs=256Hz。CCS提供了很多方法将程序产生的数据画图显示,包括时域/频域波形显示等。可通过查看相关图像来检验FFT运算的正确性。由链接命令文件可以知道输入信号存储在程序存储区0900h开始的256 个单元中,经程序计算得到的信号幅值谱存放在数据存储区0200h开始的256个单元中。在CCS中选择View——>Graph——> Time/Frequency命令,相关设置可参考图1:

图1 FFT运算结果查看选项设置参考输入信号的时域波形见图2。

点击看原图

图2 输入信号的时域波形

; 经FFT运算后得到的信号幅值谱图见图3。

点击看原图

图3 信号幅值谱图

将输入信号通过Matlab仿真进行验证。输入信号的时域波形见图4。

点击看原图

图4 输入信号的时域波形

经FFT运算后得到的信号幅值谱图见图5。

点击看原图

图5 信号幅值谱图

通过比较CCS中的输出图形和Matlab中的仿真输出图形, 可以看到二者是一致的,说明本程序的结果是正确的。

4 结束语

本文通过实例,说明了TMS320 C5000系列DSP芯片的混合编程方法,利用混合编程达到了提高程序的可读性与编程效率的目的,是开发DSP软件的常用方法。本文介绍的混合编程方法不但适用于TI C5000系列DSP芯片,同样也适用于TI其他系列的DSP芯片,如C2000系列、C6000系列,甚至对其他芯片,如51系列单

片机等,实现混合编程也有很大参考价值。

相关主题
相关文档
最新文档