2048点FFT在TMS320C240x定点DSP上的实现
摘要:针对线阵CCD输出数据的处理需要,介绍了2048点FFT在TMS320C240x定点DSP上的实现。FFT算法程序采用汇编语言编写,可通过C语言函数调用,因此具有实现简单、高效的特点,且扩展性和兼容性强,可运行于嵌入式线阵CCD光谱探测系统中。
关键词:FFT;DSP;劈分算法;位反转算法
引言
傅立叶变换是一种将信号从时域转变为频域表示的变换手段,它在信号的频谱分析以及系统的分析、设计中得到了广泛的应用。在计算机系统中,实际上是以离散傅立叶变换(DFT)的方式处理数据。由于DFT的运算量比较大,实际应用中常使用DFT的快速算法-快速傅立叶变换(FFT)。快速傅立叶变换算法有基2算法、基4算法等,还有按时间抽取(DIT)和按频率抽取(DIF)的算法。
目前,由于线阵CCD在光谱探测、光学传感等方面的广泛应用,常需要嵌入式芯片(如DSP)对CCD输出的数据进行实时分析处理。用于工业探测的线阵CCD与我们通常认识的面阵CCD有所不同。我们日常生活中出现的面阵CCD少说也有几十万像素,高的可达上千万像素,常用在数码相机等设备上。相比较而言,用于工业探测的线阵CCD像素不高,但在光谱响应范围、几何精度、动态范围有自己独特的优势。比如我们所用的TCD1208 CCD就是一款面向光谱探测用的线阵CCD,有2160像元,光谱响应范围400纳米-1100纳米,并且动态范围大,灵敏度高,稳定可靠。整个嵌入式线阵CCD光谱探测系统的结构框图如图1所示,在DSP上要完成CCD驱动、A/D转换、FFT运算、控制液晶显示等功能,其中FFT运算是重点。
考虑到CCD是2160像元,为了方便运用基2算法计算FFT,又不损失太多的像元,我们在DSP上计算2048点FFT。由于TI公司提供的FFT程序只能计算512点FFT,因此,就需要我们编写能够实现2048点FFT的程序。以FFT在嵌入式线阵CCD光谱探测系统中的应用为例,重点介绍2048点实数基2DIT-FFT在TMS320LF2407定点DSP中的实现。此程序也可实现1024点复数FFT。由于TMS320C240x系列DSP的硬件内核与汇编指令完全相同,此程序可以直接移植到所有TMS320C240x DSP上。根据此程序,可以方便地扩展至4096点FFT,用于5000像元CCD的数据处理。
1 程序介绍与实现
1.1程序流程
FFT的计算量比傅立叶变换的计算量减少了,但是FFT要做到大点数,实时运算,对于普通的单片机来说还是一件比较困难的事。一方面,FFT需要对原始自然序列进行码位倒序排列;另一方面,蝶形运算是复数运算,需要多次查表相乘运算才能实现。DSP控制器就是针对这些需求而设计的专用芯片:具有专为FFT算法而设计的反序间接寻址;可实现增/减1或增/减一个变址量的间接寻址方式,为各种查表运算提供方便;能在一个指令周期完成乘和累加操作,提高了乘法运算的速度[1]。TMS320LF2407定点DSP是一款专为工业控制、电机控制和数字信号处理等用途而设计的DSP,具备单周期乘加指令,具有FFT反序间接寻址功能,最高运行速度为40MIPS。为了充分利用DSP芯片特有的反序间接寻址等功能,FFT算法程序采用汇编语言编写,主程序采用C语言,因此程序具有良好的接口性能和可扩展性能。
一般计算N点实数FFT时,简单的把N点实数数据当作N点虚部为0的复数数据来处理,直接计算N点复数FFT。这样不仅浪费了DSP片内资源,还影响了计算的实时性,尤其是点数比较大时,这种影响更加明显。为了提高实数FFT的计算效率,利用FFT计算的特点,把N点实数数据打包成N/2点复数数据,通过计算N/2点复数FFT来获得N点实数FFT,这样可以把FFT的计算速度提高近一倍。
实数FFT的计算流程为:
1 把2048点实数数据打包成为1024点复数数据,并完成复数数据的位反转操作;
2 计算1024点基2复数FFT;
3 劈分还原计算,获得2048点实数FFT结果;
4 计算幅值的平方,获得频谱的幅度谱。
根据实际需要,还可以对数据进行加窗函数处理。
1.2具体函数介绍
根据上面的程序流程,介绍具体的函数模块。考虑到程序的效率和代码的精简,FFT算法函数全部采用汇编语言编写,但是在各子程序的入口和出口都考虑了与C语言的兼容性,使得各子程序能够直接被C语言调用。
1 汇编模块fft_brev.asm,此模块的功能是把2048点实数数据打包成为1024点复数数据,并把复数数据进行倒位序排列。在C函数中,通过FFT_brev()来调用。具体声明形式为:void FFT_brev(int *source,int *done,int size),其中指针source指向的数组存放未经倒位序排列的数据,指针done指向的数组存放倒位序排列后的数据,size是数组的大小,为了节省空间,指针source和done可以指向同一数组。
2 汇编模块fft1024c.asm,此模块的功能是计算1024点基2复数FFT。输入的数据必须是Q15格式的数据。
3 汇编模块fft2048.asm,此模块的功能是劈分1024点复数FFT的结果,得到2048点实数FFT的真正结果。
4 汇编模块fft_mag.asm,此模块的功能是计算2048点实数FFT的结果的幅值平方,得到幅度谱,输出的数据格式为Q14格式。
主函数调用示例:
void main(void)
{ ……
fft.ipcbptr=ipcb; //FFT计算缓冲区
fft.magptr=mag; //存放幅度谱
fft.init1(); //复制计算复数FFT所需的旋转因子
fft.init2(); //复制劈分复数FFT结果所需的旋转因子
fft.calc(&fft); //计算复数FFT
fft.split(&fft); //劈分复数FFT结果
fft.mag(&fft); //计算幅度谱
}
几点说明:
1 由于定点DSP的浮点计算能力有限,为了保证计算的有效性和实时性,对输入输出数据采取了定点处理,其中输入数据是Q15格式,输出的幅度谱是Q14格式。
2 在FFT计算的蝶形运算和劈分计算中,涉及到正弦和余弦计算。因此需要预先制好正弦和余弦表。
3 简单改变几个参数值和扩展一下正弦和余弦表,就可以用此程序计算4096以及更大点数的实数FFT。但需要注意扩展存储空间以及防止结果精度的降低。
1.3 抗干扰设计
为防止各种干扰使得程序不能正常运行,我们从软硬件两个方面采取抗干扰措施。从硬件方面,我们采用TI的专用电源芯片TPS7333,为DSP提供稳定电源;在集成芯片的电源与地之间放置0.01μF和0.1μF的去耦电容,并让去耦电容尽量靠近集成芯片;模拟地与数字地分开,只在一点共接等。在软件方面,为了使程序跑飞的DSP回到正常状态,加入看门狗功能。
2实验结果及分析
整个程序是在集成开发环境CC4.1下开发完成,为了方便程序运行结果的说明,用此程
图2 2048点正弦数据波形
序去计算一组2048点正弦数据,频率为1赫兹,采样频率为128赫兹。数据采用Q15格式。正弦数据波形如图2所示。一般情况下,我们只关心信号频域的幅度谱。幅度谱 的计算: ,FFT计算结果的信号幅度
谱 如图3所示。
根据快速傅立叶变换理论,N点FFT的结果是N个复数数据,这N个复数数据代表着原始数据的频域信息。当原始数据是实数时,那么FFT的结果会出现复共轭对称,即X(k)=X*(N-k)。对于信号的幅度谱 来说,N点实数FFT有用的信息就只有(N/2)+1个。根据公式f=kfs/N,f是原始信号的频率,k表示峰值出现的位置,fs是采样频率,N是FFT计算的点数,从幅度谱中看出峰值出现在k=16处,那么,f=16×128/2048=1,与原始信号的实际频率一致,说明计算结果正确。
3 小结
实验证明,此程序在TMS320LF2407定点DSP中运行良好,满足嵌入式线阵CCD探测系统数据处理的需要,并已经成功运行于该系统中。同样,此程序也适用于其它以TMS320C240x定点DSP为核心的嵌入式系统中。
|