使用CCS进行DSP编程--fft
- 格式:pdf
- 大小:490.59 KB
- 文档页数:14
使⽤CCS进⾏DSP编程--fft使⽤CCS进⾏DSP编程(⼆)——实现FFTpacificxu现在讨论使⽤TI公司的CCS进⾏DSP编程,⾸先假定读者对CCS的使⽤已经⽐较了解,如果读者还不太了解,请参阅《使⽤CCS进⾏DSP编程(⼀)——CCS编程⼊门》及其他CCS的学习⽂档。
作数字信号处理的同志们总是喜欢⽤FFT来对信号处理系统做检验,下⾯⽤闻亭公司的C6xP板、C6xPa板硬件实现FFT算法,本算法对其他的C6x板同样实⽤(只是硬件资源稍微有差异),并通过闻亭公司的PCI仿真器对⽬标板加载运⾏,运⾏结果在CCS中可视化显⽰。
⾸先启动CCS Setup,对仿真器硬件进⾏设置,本⼈使⽤的是闻亭公司PCI 的仿真器⾃带的驱动wtxds6xxxpci.dvr,设置画⾯如下:下⾯就可以运⾏CCS了,在CCS中,创建⼀个新的Project,我的⼯程⽂件放置在如下的⽬录中,读者可以放在⾃⼰喜欢的⽬录下:双击“+”展开fft.mak,可以看到整个⼯程⽂件是空的,我们需要把*.c、*.cmd、*.lib⽂件添加到⼯程⽂件中,⾸先是*.c⽂件,本例中是test.c⽂件,同样的⽅法可以⽤来添加其他的⽂件。
双击⼯程中的源⽂件,会在右边的窗⼝中看见原码:如果*.c⽂件不存在,可以在CCS集成开发环境中⽣成,本例中test.c的主程序源代码如下:调⽤的⼦程序有三个:从上⾯的源程序可以看到,使⽤CCS 的C 语⾔编程跟普通的C 语⾔编程没有太⼤的区别,这正是TI 所追求的,兼容的ANSI C 标准和如此的编译⾼效率也正是TI 的领先之处。
读者可以不必学习烦琐的汇编和线性汇编,直接对数字信号处理的算法进⾏研究,同时享受⾼速的处理速度,只有在对速度要求极严的条件下,不得不使⽤汇编和线性汇编,那时读者已经有了⼀定的基础,再学习汇编语⾔已是⽔到渠成。
⽽使⽤C 语⾔编程是⼤势所趋。
如果有⼈对算法本⾝感兴趣,请参阅胡⼴书⽼师的《数字信号处理—理论、算法与实现》第5章快速傅⽴叶变换,这⾥不在对算法进⾏展开讨论。
数字信号处理实验实验1 快速傅里叶变换FFT 算法实验一、实验目的:1、加深对离散信号的DFT 的理解和FFT 算法的运用。
2、学会用mtalab 求解信号的频谱图。
3、学会用DSP 硬件进行频谱分析。
二、实验设备计算机,ccs3.3软件,DSP CPU 挂箱,DSP 仿真器,导线三、实验原理N 点序列的DFT 和IDFT 变换定义式如下:10[][]N kn N n X k x n W-==∑, 101[][]N kn N k x n X k W N --==∑ 利用旋转因子2j nk knN N W e π-=具有周期性,可以得到快速算法(FFT )。
在MATLAB 中,可以用函数X=fft (x ,N )和x=ifft (X ,N )计算N 点序列的DFT 正、反变换。
四、实验内容:1、利用MATLAB 编程完成计算,绘出下式时域图形,并用FFT 求取其傅里叶变换画出相应的频谱图,并分析、说明实验结果。
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t);采样频率fs=100Hz ,采样点数为128点。
2、运行ccs 软件,对给定的语音信号进行采集,并应用DSP 挂箱分析该信号的频谱。
相应的实验步骤(1)安装仿真器TDS510驱动(位置在f 盘根目录下).(2)仿真器参数设置打开setup ccstudio 从Familly 中查找C55xx 系列,然后选择C5509 TDS510并将其拖到到左侧窗口。
右键C5509打开属性装载仿真器的配置参数CCstudio_v3.3//cc//bin/TDS510.cgf.(3)打开ccs3.3链接仿真器与电脑点击Debug —connect ;打开已建立的项目点击project—open—fft.pjt;装载编译好的程序fft.out,file--load program—fft.out。
在k++处设置断点,观察采集到的语音信号。
DSP程序:CCS环境下的FFT程序(以8点的为例做了详细解析)2009-11-04 09:35********************************************************************* N(8-1024) points FFT Program *********************************************************************.title "fft.asm".mmregs.copy "coeff.inc".def _c_int00sine: .usect "sine",512cosine: .usect "cosine",512fft_data: .usect "fft_data",2048d_input: .usect "d_input",2048fft_out: .usect "fft_out",1024STACK .usect "STACK",10K_DATA_IDX_1 .set 2K_DATA_IDX_2 .set 4K_DATA_IDX_3 .set 8K_TWID_TBL_SIZE .set 512K_TWID_IDX_3 .set 128K_FLY_COUNT_3 .set 4*** N points FFT ***K_FFT_SIZE .set 16 ;N=8K_LOGN .set 4 ;LOG(N)=LOG(8)=3.bss d_twid_idx,1.bss d_data_idx,1.bss d_grps_cnt,1.sect "fft_prg" ;*** Bit Reversal Routine ***.asg AR2,REORDERED.asg AR3,ORIGINAL_INPUT.asg AR7,DA TA_PROC_BUF.text_c_int00:SSBX FRCTSTM #STACK+10,SPNOP ;put a probe,input 2N data into d_input(dm) ;include Re and ImSTM #sine,AR1 ;move sine1(512) into sine(dm)RPT #511 ;MVPD sine1,*AR1+STM #cosine,AR1 ;move cosine1 into cosine RPT #511 ;MVPD cosine1,*AR1+STM #d_input,ORIGINAL_INPUTSTM #fft_data,DATA_PROC_BUFMVMM DATA_PROC_BUF,REORDERED ;RECORDERED point fft_data too STM #K_FFT_SIZE-1,BRCRPTBD bit_rev_end-1STM #K_FFT_SIZE,AR0 ;this is double words orderMVDD *ORIGINAL_INPUT+,*REORDERED+ ;Bit ReversalMVDD *ORIGINAL_INPUT-,*REORDERED+MAR *ORIGINAL_INPUT+0Bbit_rev_end:* * * * FFT Code * * * * *.asg AR1,GROUP_COUNTER.asg AR2,PX.asg AR3,QX.asg AR4,WR.asg AR5,WI.asg AR6,BUTTERFL Y_COUNTER.asg AR7,STAGE_COUNTER* * * stage 1 * * *STM #0, BK ;why not=16?LD #0, ASM;LD #-1, ASM ;protect flowover ,all output/2STM #fft_data,PXLD *PX,16,A ;AH:=Re[x(0)]STM #fft_data+K_DATA_IDX_1,QX ;QX point Re[x(4)]STM #K_FFT_SIZE/2-1,BRC ;stage 1 is N/2-1RPTBD stage1end-1STM #K_DA TA_IDX_1+1,AR0SUB *QX,16,A,B ;BH=Re[x(0)]-Re[x(4)]ADD *QX,16,A ;AH=Re[x(0)]+ Re[x(4)]STH A,ASM,*PX+ST B,*QX+||LD *PX,ASUB *QX,16,A,B ;BH=Im[x(0)]-Im[x(4)]ADD *QX,16,A ;AH=Im[x(0)]+Im[x(4)]STH A,ASM,*PX+0ST B,*QX+0% ;BK=0 why here circle access ?||LD *PX,Astage1end:* * * Stage 2 * * *STM #fft_data,PXSTM #fft_data+K_DATA_IDX_2,QXSTM #K_FFT_SIZE/4-1,BRCLD *PX,16,A ;AH=Re[x(0)]+ Re[x(4)],AH=1RPTBD stage2end-1STM #K_DA TA_IDX_2+1,AR0;1st butterflySUB *QX,16,A,B ;BH={Re[x(0)]+ Re[x(4)]}-{Re[x(2)]+ Re[x(6)]},BH=0ADD *QX,16,A ;AH={Re[x(0)]+ Re[x(4)]}+{Re[x(2)]+ Re[x(6)]},AH=2STH A,ASM,*PX+ST B,*QX+||LD *PX,ASUB *QX,16,A,B ;BH={Im[x(0)]+ Im[x(4)]}-{Im[x(2)]+ Im[x(6)]},BH=0ADD *QX,16,A ;AH={Im[x(0)]+ Im[x(4)]}+{Im[x(2)]+ Im[x(6)]},BH=0STH A,ASM,*PX+STH B,ASM,*QX+;2nd butterflyMAR *QX+ADD *PX,*QX,A ;AH=+,=1SUB *PX,*QX-,B ;BH=-,=1STH A,ASM,*PX+SUB *PX,*QX,A ;AH=-,=-1,note:subST B,*QX||LD *QX+,B ;very important, " BH= {Re[x(2)]- Re[x(6)]} ",=1******************************************************************************** **********ST A,*PX ; right!!!||ADD *PX+0%,A ; note:this order include BHST A,*QX+0% ;||LD *PX,A***************** my modify***************************************************************; ST A,*PX; ||ADD *PX+0%,B; ST B,*QX+0%; ||LD *PX,A******************************************************************************** *********stage2end:* * * Stage 3 through Stage logN * * *STM #K_TWID_TBL_SIZE,BKST #K_TWID_IDX_3,d_twid_idxSTM #K_TWID_IDX_3,AR0STM #cosine,WRSTM #sine,WISTM #K_LOGN-2-1,STAGE_COUNTERST #K_FFT_SIZE/8-1,d_grps_cntSTM #K_FL Y_COUNT_3-1,BUTTERFL Y_COUNTERST #K_DATA_IDX_3,d_data_idxstage:STM #fft_data,PXLD d_data_idx,A ;A:=8ADD *(PX),A ;A:=2008STLM A,QX ;this time QX piont what?;my thought:point the eighth space(ccs test);may relocate QX pointerMVDK d_grps_cnt,GROUP_COUNTERgroup:MVMD BUTTERFLY_COUNTER,BRCRPTBD butterflyend-1LD *WR,T ;T:=1,cos0MPY *QX+,A ;A=000001FFFCMACR *WI+0%,*QX-,A ;T=0,sin0,WI next piont 0.707,-1 ADD *PX,16,A,B ;B=0000040000,0000010000ST B,*PX ;the first ouput:1/8*||SUB *PX+,B ;B=0000000000,0000010000ST B,*QX ;||MPY *QX+,A ;A=0000000000,000000B504 MASR *QX,*WR+0%,A ;T=0 ,WR next piont 0.707,0;SFTL A,4,AADD *PX,16,A,B ;B=0000000000,OVB=1ST B,*QX+||SUB *PX,B ;B=0000000000 ,00FFFE0000LD *WR,T ;T:=0.707,0ST B,*PX+ ;||MPY *QX+,A********************************************************* butterflyend:; Update pointers for next groupPSHM AR0MVDK d_data_idx,AR0MAR *PX+0MAR *QX+0BANZD group,*GROUP_COUNTER-POPM AR0MAR *QX-;Update counters and indices for next stageLD d_data_idx,A ;A:=8SUB #1,A,B ;B:=7STLM B,BUTTERFL Y_COUNTER ;butterfly_counter:=7 STL A,1,d_data_idx ;d_data_idx:=4LD d_grps_cnt,A ;A:=0(8/8-1)STL A,ASM,d_grps_cnt ;d_grps_cnt=A/2LD d_twid_idx,A ;A:=128STL A,ASM,d_twid_idx ;d_twid_idx=A/2BANZD stage,*STAGE_COUNTER- ;stage_counter:=0 MVDK d_twid_idx,AR0fft_end:* * * Compute the power spectrum * * *STM #fft_data,AR2STM #fft_out,AR4STM #K_FFT_SIZE-1,BRCNOPRPTB power_end-1SQUR *AR2+,ASQURA *AR2+,ASTL A,-1,*AR4+power_end:nophere: B here.end。
使用CCS进行DSP编程(四)——实现Host和DSP通信pacificxu首先对题目进行一下解释,之所以取这个名字,是为了与前面三篇文章相对应,连成一个系列,这里不仅仅涉及使用CCS进行DSP编程,主机端的程序便是用Visual C++实现的。
通信包括许多手段:中断、mailbox、直接数据传输等等,这里并不一一列举。
现在讨论实现Host和DSP通信。
假定读者对CCS的使用已经比较了解,并有了一定的CCS编程经验。
如果读者还不太了解,请参阅《使用CCS进行DSP 编程(一)—— CCS编程入门》、《使用CCS进行DSP编程(二)——实现FFT》、《使用CCS 进行DSP编程(三)——实现DMA和Interrupt》及其他CCS的学习文档。
下面用闻亭公司的C6xP板硬件和闻亭公司的PCI仿真器为例,来实现Host 和DSP 通信。
对于‘ C6Xpa板同样有效。
闻亭公司的C6xP板是一款具有PCI接口的高速信号处理EVM板,接口芯片是AMCC 的S5933,兼容PCI Local Bus Revision 2.1 协议。
PCI 接口比较适合用来进行Host和DSP的高速大数据量数据交换。
主机通过HPI接口可直接访问DSP的所有存储空间,允许主机初始化DSP,可以从主机加载程序。
前面几篇文章所讲的都是从JTAG接口加载程序,这样比较适合于程序的开发调试,对于实际的系统来说,大部分都是系统自己从EEPROM或Flash加载,现在我们可以从主机通过应用程序来加载,基于此,许多耗时的算法PC机不能实时完成的可以由DSP来完成。
这个过程可以这样来描述:PC机执行应用程序,加载算法到DSP端,并将需要处理的数据传送到DSP,DSP计算完成后将数据传回PC,整个过程由PC 来控制启动、工作、完成,使用起来比较方便。
当然,DSP算法还需要首先用仿真器通过JTAG接口调试好才行。
接下来看看实现这个功能的一个典型系统框图:在这个框图里,我简化了主机PC执行程序的其他部分,突出了与DSP进行通信有关的内容。
使用CCS进行DSP编程(三)——实现DMA和Interruptpacificxu现在讨论在CCS进行DSP编程来实现DMA和Interrupt功能。
假定读者对CCS的使用已经比较了解,并有了一定的CCS编程经验。
如果读者还不太了解,请参阅《使用CCS进行DSP编程(一)——CCS编程入门》、《使用CCS进行DSP编程(二)——实现FFT》及其他CCS的学习文档。
下面用闻亭公司的C6xPa板硬件和闻亭公司的PCI仿真器为例,来实现DSP 的DMA传输和硬件Interrupt功能。
首先来描述一下使用的硬件资源。
闻亭公司的C6xPa板有两路独立的最高采样率为40MHz精度为12bit的A/D,它与DSP的EXT_INT7相连,可以产生外部中断信号,通过FPGA的逻辑可以控制A/D的采集和采集多少数据产生一次中断,采集的数据放在DPRAM中(0x1400000开始的地址空间),通过DMA 传输到DSP芯片上的存储器中(0x80000000开始的地址空间)。
在C语言环境中使用DMA和Interrupt功能,需要包含两个头文件<dma.h>和<intr.h>,同时要用到相应的运行时库文件“csl6201.lib”和“dev6x.lib”。
对这两组头文件和运行时库文件,我们深入研究一下,看一看我们比较关心的函数有哪些。
下一次用到这些函数时,别忘了带上相应的运行时库文件%*&^*&^喔。
在dev6x.lib库文件中,直接与实现DMA和Interrupt功能相关的函数有如下几个:dma_initdma_global_initdma_resetintr_resetintr_initintr_hookintr_mapintr_isnintr_get_cpu_intrisr_jump_table在csl6201.lib库文件中,直接与实现DMA功能相关的函数有如下几个: DMA_AllocGlobalRegDMA_GetEventIdDMA_GBL_PRIV ATEDMA_OpenDMA_StartDMA_HCHA0DMA_HCHA1DMA_HCHA2DMA_HCHA3DMA_WaitDMA_SetGlobalRegDMA_ConfigADMA_ConfigBDMA_StopDMA_AutoStartDMA_PauseDMA_ResetDMA_GetGlobalRegDMA_SetAuxCtlDMA_CloseDMA_FreeGlobalRegDMA_InitDMA_GetStatus我们只需其中的一部分便可以实现DMA和Interrupt功能。
使用CCS进行DSP编程(一)——CCS编程入门pacificxuTI公司提供了高效的C编译器和集成开发环境Code Composer Studio,学习‘C6X的编程应该从学习CCS的使用开始。
首先安装CCS,CCS的安装有详细的说明,并配有简短的Quick Time的多媒体介绍,对于没有购买CCS的用户,可以从TI处得到30天的试用版(没有硬件仿真功能)。
使用CCS前需要对CCS进行设置,以Simulator为例,运行Setup CCS C6000 1.20,安装Device Driver,对于有硬件支持的仿真器,可以选择配套的CCS驱动,设置完成的画面如下图所示:用户的界面大致相同。
接下来就可以运行CCS了,CCS提供了比较好的例子,对于初学者,仔细学习这些例子,会起到事半功倍的效果。
在CCS的Help菜单的Tutorial子菜单下,给出了四个教程,分别是:Code Composer Studio Tutorial、Advanced DSP/BIOS Tutorial、Compiler Tutorial和RTDX Tutorial,用户可以从简单的CCS功能开始,如创建一个工程文件Project,到创建一个完善的用户程序一步一步的进行。
下面是Code Composer Studio Tutorial的例子:分别从生成一个简单的“Hello World”程序,到使用DSP/BIOS功能,到程序的调试,实时分析,I/O操作等分6课来讲解,可以领略TI的CCS的强大功能。
下面以“Hello World”程序为例讲一下CCS的使用。
首先打开一个Project文件这些文件的路径如下图所示:打开hello.mak,会看到如下图所示的界面。
将File View栏中的“+”号都打开,会看到整个项目工程中的所有资源。
其中*.c文件和*.h文件与普通的C语言编程中是一致的(TI编译器支持ANSI C标准)。
需要指出的是三个文件:HELLO.CMD、RTS6201.LIB、VECTORS.ASM。
摘要本次课程设计主要运用CCS这一工具实现快速傅里叶变换(FFT)。
CCS(Code Composer Studio)是一种针对TM320系列DSP的集成开发环境,在Windows操作系统下,采用图形接口界面,提供环境配置、源文件编辑、程序调试、跟踪和分析等工具,可以帮助用户在一个软件环境下完成编辑、编译、链接、调试和数据分析等工作。
CCS有两种工作模式,即软件仿真器和硬件在线编程。
软件仿真器工作模式可以脱离DSP芯片,在PC上模拟DSP的指令集和工作机制,主要用于前期算法实现和调试。
硬件在线编程可以实时运行在DSP芯片上,与硬件开发板相结合进行在线编程和调试应用程序。
关键词:CCS; 快速傅里叶变换(FFT);目录第1章概述 (2)1.1设计任务 (2)1.2设计要求 (3)第2章快速傅里叶变换FFT的原理 (3)2.1离散傅里叶变换DFT (3)2.2.快速傅里叶变换FFT (4)第3章方案设计 (7)3.1设计程序流程图 (7)3.2在CCS环境下加载、调试源程序 (8)第4章主要参数 (13)4.1N的参数设置 (13)4.2CMD源文件代码: (13)4.3C文件源码: (14)第五章实验结果及分析 (19)5.1作图得到输入信号的功率图谱 (19)5.2FFT变换结果图 (19)5.3改变信号的频率可以再做次实验 (20)课程设计体会 (21)参考文献 (22)第1章概述1.1设计任务1)用DSP汇编语言及C语言进行编程;2)实现FFT运算、对输入信号进行频谱分析。
1.2设计要求1). 研究FFT原理以及利用DSP实现的方法;2). 编写FFT程序3). 调试程序,观察结果。
第2章快速傅里叶变换FFT的原理快速傅里叶变换(FFT)是一种高效实现离散傅里叶变换(DFT)的快速算法,是数字信号处理中最为重要的工具之一,它在声学,语音,电信和信号处理等领域有着广泛的应用。
2.1 离散傅里叶变换DFT对于长度为N 的有限长序列x(n),它的离散傅里叶变换(DFT )为1,1,0,)()(10-==∑-=N k W n x k X n n nkN (1)式中,Nj N e W /2π-= ,称为旋转因子或蝶形因子。
DSP集成开发环境中的混合编程及FFT算法的实现摘要:实现了一种全集成可变带宽中频宽带低通滤波器,讨论分析了跨导放大器-电容(OTA—C)连续时间型滤波器的结构、设计和具体实现,使用外部可编程电路对所设计滤波器带宽进行控制,并利用ADS软件进行电路设计和仿真验证。
仿真结果表明,该滤波器带宽的可调范围为1~26 MHz,阻带抑制率大于35 dB,带内波纹小于0.5 dB,采用1.8 V电源,TSMC 0.18μm CMOS工艺库仿真,功耗小于21 mW,频响曲线接近理想状态。
关键词:Butte1 引言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和汇编语言混合编程必须遵循相关函数调用规则和寄存器调用规则,否则会给程序的开发带来意想不到的问题。
CCS上FFT的C语言实现在C语言中实现FFT(快速傅里叶变换)需要以下步骤:1.导入需要的库函数:```c#include <stdio.h>#include <stdlib.h>#include <math.h>```2.定义复数结构体:```ctypedef structfloat real;float imag;```3.定义FFT函数及其辅助函数:```creturn recursiveFFT(x, N);if(N == 1)X[0]=x[0];return X;}for(int k=0; k<N/2; k++)X_even[k].imag + factor.imag}; X_even[k].imag - factor.imag}; }free(X_even);free(X_odd);return X;for(int m=2; m<=N; m *= 2)for(int k=0; k<N; k += m)for(int j=0; j<m/2; j++)u.imag + t.imag};u.imag - t.imag};w = multiply(w, wm);}}}return X;for(int i=0; i<N; i++)int j = i;int k = 0;for(int b=0; b<log2(N); b++)k<<=1;k,=(j&1);j>>=1;}X[k]=x[i];}return X;```4.用例演示:```cint mainint N = 8; // 采样点数{4,0},{5,0},{6,0},{7,0}};for(int i=0; i<N; i++)printf("X[%d] = %f + %fi\n", i, X[i].real, X[i].imag);}free(X);return 0;```上述代码实现了一个基于C语言的FFT算法,对包含8个采样点的信号进行了快速傅里叶变换。
使用CCS进行DSP编程(二)
——实现FFT
pacificxu
现在讨论使用TI公司的CCS进行DSP编程,首先假定读者对CCS的使用已经比较了解,如果读者还不太了解,请参阅《使用CCS进行DSP编程(一)——CCS编程入门》及其他CCS的学习文档。
作数字信号处理的同志们总是喜欢用FFT来对信号处理系统做检验,下面用闻亭公司的C6xP板、C6xPa板硬件实现FFT算法,本算法对其他的C6x板同样实用(只是硬件资源稍微有差异),并通过闻亭公司的PCI仿真器对目标板加载运行,运行结果在CCS中可视化显示。
首先启动CCS Setup,对仿真器硬件进行设置,本人使用的是闻亭公司PCI 的仿真器自带的驱动wtxds6xxxpci.dvr,设置画面如下:
下面就可以运行CCS了,在CCS中,创建一个新的Project,
我的工程文件放置在如下的目录中,读者可以放在自己喜欢的目录下:
双击“+”展开fft.mak,可以看到整个工程文件是空的,
我们需要把*.c、*.cmd、*.lib文件添加到工程文件中,
首先是*.c文件,本例中是test.c文件,
同样的方法可以用来添加其他的文件。
双击工程中的源文件,会在右边的窗口中看见原码:
如果*.c文件不存在,可以在CCS集成开发环境中生成,
本例中test.c的主程序源代码如下:
调用的子程序有三个:
从上面的源程序可以看到,使用CCS的C语言编程跟普通的C语言编程没有太大的区别,这正是TI所追求的,兼容的ANSI C标准和如此的编译高效率也正是TI的领先之处。
读者可以不必学习烦琐的汇编和线性汇编,直接对数字信号处理的算法进行研究,同时享受高速的处理速度,只有在对速度要求极严的条件下,不得不使用汇编和线性汇编,那时读者已经有了一定的基础,再学习汇编语言已是水到渠成。
而使用C语言编程是大势所趋。
如果有人对算法本身感兴趣,请参阅胡广书老师的《数字信号处理—理论、算法与实现》第5章快速傅立叶变换,这里不在对算法进行展开讨论。
程序的结构本身很简单,使用过C语言的朋友一看就明白,不需要再做进一步的说明,需要指出几点,
1. 本程序中的math.h与Visual C++中的math.h是不同的,TI的CCS专门
为数学计算作了运行时库,是利用硬件对计算作加速的,与Visual C++
中的速度是不可同日而语的。
因此如果我们需要用到相应的“头文件”,
就应该在TI的目录中查找,同时要包含相应的运行时库(*.lib)文件,
我一直在强调这一点,初学者往往忽略这一点而出现许多编译链接错误。
下面的演示中还会看到这一点。
2. 本例是以定点DSP芯片‘C6201为例的。
如果对定点运算还不太熟悉,
只好找些文档来学习一下了,这里也不再展开。
在浮点DSP芯片‘C6701
中本程序可以不加修改地运行,但浮点DSP芯片中可以直接进行有硬件
支持的浮点运算,速度会更快。
3. CCS的C语言中的数据类型是与硬件相关的,使用时需要注意。
char 8 bits
bits
short 16
int 32 bits
bits
long 40
bits
float 32
double 64 bits
TMS320C6000 Online Programmer's Guide (SPRH048) Copyright?2000 Texas Instruments
接下来继续进行,向工程中添加*.cmd文件。
读者现在应该会执行这个操作了,如果没有就自己造一个吧,也可以拿别人的来改造一下。
其中有些不太明白也没有关系,但是在与具体的硬件相关的地方还是要搞明白。
首先要搞明白目标板“target”上到底有多少存储空间,包括DSP芯片内部有多大空间,目标板上有多少外部存储器(SDRAM、SBSRAM、双口RAM),以及它们的其始地址和长度,以我使用的闻亭公司‘C6Xpa板为例,
存储器类型起始地址存储器大小结束地址SDRAM 0x2000000 4M*32bit (0x400000*4) 0x3000000 SBSRAM 0x400000 128k*32bit (0x20000*4) 0x480000
0x1404000 DPRAM 0x1400000 4k*32bit (0x1000*4)
在这里还要强调一点,是“*32bit”,因此SDRAM的结束地址是0x2000000 + 0x400000*4 = 0x3000000
而不是
0x2000000 + 0x400000 = 0x2400000
其他存储空间也是如此。
许多同志们忽略了这一点,在使用数组、指针及对空间地址操作时造成“不可理解”的错误,“我往仫个地址写数怎么找不到,#%^#&^%%^———坏了!”,好好研究一下,就不好意思这么快下结论了。
下面是我用的*.cmd文件的源代码,需要的话可以拿去用喔。
里面“.vec、.text ….”的东西可以先不考虑,留给CCS去处理好了。
只要保证定义的空间在物理上存在就可以了。
心急的朋友会开始编译了,
又会出现下面的结果,
“$%*^&^,又忘了加运行时库!”。
(下次再忘就不应该了!)。
这里展开一点,有些朋友说:“我包含了头文件<intr.h>,调用中断函数intr_hook()时怎么也编译链接通不过,去掉这一句就通过了。
”大家现在就应该知
道怎么处理这个问题了吧?熟悉C语言编程的同志都知道“*.lib”的实质,中断函数intr_hook()在“dev6x.lib”里。
加上这个库问题估计该解决了吧! TI的运行时库都有具体的说明,如果大家实在懒得去看,又不想知其所以然,有一个绝招在此:“Find all *.lib in TI目录”一个一个试一下好了。
我们的问题解决了,接下来看一看能不能运行,执行对不对。
装入“fft.out”文件,
然后运行程序(F5)(热键、工具条、菜单都可以用啦),看一下结果对不对,顺便体验一下CCS提供的“Very Good”功能:
弹出对话框,设置一下吧,
会出现下面的画面,
修改一下属性,
下面好看多了,
里面的三个谱峰看起来跟信号里造的三个频率的信号好象是对应的吧。
在源文件
里进行些修改,例如将信号频率改为两个,
重新编译、链接、执行、显示,中间的谱线不见了。
好象我们成功了!(哗哗哗哗哗┉┉)
总结:在这里演示了使用CCS的C语言实现FFT程序,仅仅是实现而已。
一个实际的系统,需要做许多优化处理,对核心算法进行详细的分析、规划,初学时可以先不考虑这些,等熟悉后在进行深入研究。