湖南工业职业技术学院电气工程学院 贺力克
湖南工业大学交通工程学院 易吉良
快速傅里叶变换(FFT)采用时间抽取或频率抽取方式大大提高了傅里叶变换的运算效率。但在旋转变压器解码和电能质量分析等应用领域,由于信号采样率很高,同时这些应用中FFT算法的运算量很大,在DSP芯片中很难实现实时处理。本文介绍一种采用TMS320F28335DSP实现高速信号采集并实时进行FFT运算的方法,为基于FFT的大运算量算法的实时应用提供一种解决方案。
以采用DSP解码的旋转变压器解码系统为例,其系统结构框图如图1所示。从图1可以看出,旋转变压器的三路信号Vc、Vs和Ve通过信号调理电路转换为满足DSP内置AD端口需要的电压信号V1~V3。
图1 旋转变压器解码系统框图
一般上述三路信号的频率为5KHz~10KHz,需要AD的采样频率为50KHz~200KHz。以10KHz信号频率和100KHz采样频率为例,若在分析数据过程中截取10周期数据,则待分析信号的时长为0.1ms。在上述条件下,若要做到实时运算,则芯片要在0.1ms内要处理完数据采样、算法运算和其他数据通信等事务。如果每次数据采样都需要CPU参与,而FFT没有高效算法的情况下,一般的DSP芯片很难做到实时性。TI公司的TMS320F28335DSP芯片设计了直接存储器访问技术(DMA),AD采样的数据直接传送到指定的数据缓冲区,不需要CPU在每个采样周期都参与数据传输,只需在完成一定量的数据采集后,才通过中断通知CPU执行相关操作。另外,该芯片的软件开发资源非常丰富,包括开发环境CCS和资源包controlSUITE,为高数据采样率和大运算量的实时应用提供了支持。
DMA提供了外设和存储器之间的一种直接硬件传输数据的方式,可以大大减少CPU的开销。为了简要描述DMA的工作原理,以ADC采样结果传输到RAM的过程为例,描述TMS320F28335的DMA如何直接将AD采样的数据传输到指定的RAM中。
图2中DMA的工作首先要分配好源地址和目的地址,在本例中,源地址就是AD采样结果寄存器,而目的地址就是存放采样结果的数据缓冲区RAM。DSP传输数据要用到数据总线,而这些总线都是共享的,也就是说只有在传输数据时才能占用。而DMA的传输触发是通过中断实现的,即AD一旦完成了采样就发出中断信号,通知DMA将结果寄存器的数据取走,这时DMA就要占用数据总线,传完数据就会自动释放总线。而当数据缓冲区填满的新的数据后,可以设置DMA发出中断,通知CPU对缓冲区的数据进行处理,这样,CPU只需在DMA中断时才提取数据,节省了大量的CPU时间。
图2 TMS320F28335DMA原理
根据上述DMA原理,使用DMA需要对相关寄存器做设置,在初始化程序中,主要利用如下几个C语言函数:(1)DMACH1AddrConfig( ):该函数用来配置DMA的源地址和目的地址。(2)DMACH1BurstConfig( ):该函数用于配置每帧DMA传输的数据量,以及每次传输源地址和目标地址改变的步长。(3)DMACH1TransferConfig( ):该函数用于配置传输帧数量,以及帧地址步长。(4)DMACH1Wrap-Config( ):该函数用于定义进行循环传输,以及相应的源地址和目的地址与步长。(5)DMACH1ModeConfig( ):这个函数有10个参数需要配置,关系到DMA的中断使能和工作模式等。每个参数的具体含义需结合数据手册中的DMA工作流程加以理解,限于篇幅,不再赘述。
在DMA完成DMACH1TransferConfig( )函数定义的数据帧后,就需要产生中断,执行interrupt void local_DINTCH1_ISR( )中断函数,在该函数中执行FFT等算法程序。
FFT是很多应用中的算法。在DSP中实现FFT有两种方案,一种是直接根据FFT的定义编写程序;另一种是利用TI的FFT库函数实现。作者对两种方案进行了测试,发现库函数有更高的运算效率,下面主要介绍库函数的应用方法。
库函数利用压缩算法实现FFT,使得计算效率得到了很大提高。其实整个库函数除了FFT外,还有求IFFT和求幅值等函数。库函数的源码在controlSUITE目录下可以找到,基本都是采用汇编语言编写。库函数的详细的使用方法可以从TI公司官网下载文档C28x-FPU-LIB-UG.pdf进行了解。这里主要介绍在使用库函数过程中需要注意一些细节,如输入数据是否对齐、处理结果存放在哪些缓冲区等。
使用库函数只要在CCS工程中添加C28x_FPU_Lib.lib库文件和FPU.h头文件,然后就可以直接调用FFT相关函数,包括:(1)CFFT_f32( ):该函数用于计算FFT,注意该函数的参数是复数格式,在DSP中需要用两个单元分别存放实部和虚部,且实部在前,虚部在后。(2)ICFFT_f32( ):该函数用于计算IFFT,其参数要求与CFFT_f32( )一样。(3)abs_SP_CV_2( ):该函数用于求复数的幅值,三个参数分别是存放幅值结果,输入的复数和数据长度。
图3 CCS调试界面
在使用库函数求FFT时对数据存放的存储单元有特殊要求,即对齐某个地址,这就需要在存储器分配文件*.cmd中对相应数据变量进行说明。*.cmd文件中用到两条分配存储单元,即指令MEMORY和SECTIONS。其中MEMORY用于说明系统中有哪些可用的存储器,而SECTIONS用于将定义的变量分配到可用的存储器中。为了满足FFT库函数的要求,在SECTIONS指令中需要用到如下说明:
该语句的含义是将FFTRAML3s数据段定位到数据空间PAGE1的RAML3存储器中,当然PAGE1和RAML3是在MEMORY指令中定义好的。同时可以注意到,该指令后面还有ALIGN(512)的说明,它是保证FFTRAML3s对齐512个存储单元,对齐的意思是该数据段的起始地址应保证最低的N位为0,N要满足:2N≥512。这样CCS给FFTRAML3s分配的地址最低9位就是0。这样做的目的是满足DSP芯片的高效寻址方式,以使FFT算法快速执行。
采用TMS320F28335开发板进行测试,系统时钟频率位150MHz,利用DMA技术高速采样,采样频率100kHz。利用库函数计算128点FFT,测得需要机器周期为5926,如图3所示。可以算出做128点的FFT时间为:5926×6.67ns=0.039766ms,而128数据时间为0.128ms,因此,在上述条件下能够实现FFT的实时运算。
综上所述,利用TMS320F28335的DMA技术和FFT库函数,能够实现数据的高频采集和FFT算法的快速运算,满足对信号采集和频谱分析的实时性要求极高的应用场合。