版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章DSP应用系统软件设计7.1程序设计基本要素7.2主要DSP硬件模块编程举例7.3应用系统软件设计举例7.4一般DSP应用系统软件设计考虑7.5小结
7.1程序设计基本要素
DSP 是一种高性能的特殊单片机,它的程序设计和单片机有一些相似之处,那就是程序代码自身必须具有完整系统的特性,这个完整系统不是要求具备全面的功能,而是要求具备完成某个(或某些)功能的完备程序结构。
对于一个常见系统的软件设计,必须掌握的程序的基本要素包括:常用指令和伪指令组成的汇编代码,用于接口、实时信号处理和控制;C语言代码及库函数,用于软件接口、人机接口和数值计算;链接控制命令文件,用于执行代码的生成。这三者组成了程序的基本结构——工程项目。汇编语言的“库”仍是一些汇编范畴的文件,不具备常见库的特征,不能算是真正的库。
而程序设计中,需要一些像旋转因子、滤波系数等的常数数据段,因此,如何用 Matlab生成系数,直至程序调用文件的方法,在举例中也得到了体现。7.1.1常用伪指令
1.段定义伪指令
段定义伪指令(DirectivesThatDefineSections)将定义程序中的一些段,包括数据段和代码段,这些段可能是既定内容,也可能是预留空间。段定义是为了方便地将它们安排到程序空间或数据空间。这个安排由cmd文件指定,在链接时完成。注意,数据段可安排到程序空间,特别是程序执行运算中要用到的系数或常数。段定义伪指令的符号及功能详见表7.1。
2.初始化常数伪指令
初始化常数伪指令(DirectivesThatInitializeConstants(DataandMemory))用来定义一些常数,这些常数可以根据需要按照不同的格式表示,如整数、浮点数、字符串等。由于TMS320'C2000为定点运算,因此非定点数在汇编程序中要用程序处理后才能使用。初始化常数伪指令的符号及功能详见表7.2。
3.安置段程序计数器伪指令
安置段程序计数器伪指令(DirectivesThatAligntheSectionProgramCounter)用来设置段边界位置,这种设置对像FFT那样的算法是很必要的,因为位反转寻址中地址的运算要以长度N/2为基础,N为FFT点数。如果没有这种功能,cmd中的资源设置及配置要繁杂些。安置段程序计数器伪指令的符号和功能详见表7.3。
4.设置列表输出格式伪指令
设置列表输出格式伪指令(DirectivesThatFormattheOutputListing)用来控制源程序的打印格式,目的是为了保证打印文件的可读性和美观性。设置列表输出格式伪指令的符号及功能详见表7.4。
5.调用说明伪指令
调用说明伪指令(DirectivesThatReferenceOtherFiles)用来声明模块可以被调用, 或说明要调用的模块,以便让汇编器和链接器正常地工作。调用说明伪指令的符号及功能详见表7.5。
6.条件汇编伪指令
条件汇编伪指令(ConditionalAssemblyDirectives)主要是考虑到代码的重用性,根据不同的条件,将相应的源代码汇编成目标代码,这样既解决了源代码的多功能性问题,又解决了目标代码要求的高效唯一性问题。使用条件汇编需要一定的编程经验和熟练程度。条件汇编伪指令的符号及功能详见表7.6。
7.汇编时符
汇编时符(Assembly-TimeSymbols)是为了编程方便使用的一种中间助记符号,将数据或符号用一种具有意义的字符串表达,便于记忆和编程。汇编完成后,这些符号将被还原成数据或程序代码,链接中已再找不到,因此得名。它和标号、段名等不一样,标号、段名等链接后仍可找到踪影,并为符号调试带来便利。汇编时符的符号及功能详见表7.7。
8.有关宏的伪指令
从源程序上看,宏汇编和子程序调用有着类似的地方,但二者存在根本的区别。调用子程序实际上是将程序指针PC转移到子程序所在的位置去执行,因而有保存断点的过程;宏调用则是复制一段代码,由汇编器而不是DSP本身完成调用过程。使用宏,一是为了简化编程,二是为了程序具有更好的可读性,三是为了保证程序的执行速度。有关宏的伪指令(MiscellaneousDirectives)的符号及功能详见表7.8。下面以“求两数的最小值并将结果放在ACCL中”为例说明如何定义和调用宏以及宏中的标号如何处理,详见表7.9。
这里,xadr为直接地址。宏定义方法1使用带“?”号的标号是为了在多次调用宏时不至于出现标号重复的错误,而宏定义方法2使用宏内局部标号来保证在多次调用宏时不至于出现标号重复的错误。这两种用法都是标准的。
9.其它伪指令
其它伪指令包括程序必须用到的像程序结束“.end”和存储器映射寄存器符号说明“.mmregs”等,详见表7.10。
10.宏汇编语言源程序的建立
编制汇编语言源程序,除要了解DSP相应指令集和伪指令外,还应该掌握一定的编程方法和树立良好的编程风格。模块化、结构化的编程风格往往会起到事半功倍的效果,这实际上是让代码模块具有可重用性。
一般,将常用的变量、符号、数据段等设计成公用部件,同时将常用算法、控制过程等设计成宏或子程序模块,这样以后遇到类似情况,可以直接调用。宏和子程序均有利于程序的逻辑性和可读性,但这两种用法却有不同的特点。宏调用实际上是用符号(一条假指令)替代一块代码,这样编程和阅读都方便;而子程序调用则需将程序指针转移到子程序所在位置去执行,为了能正确返回,还必须保护现场,而且程序指针的转移还会破坏流水线,因此这种方法会花费更多的程序执行时间,速度相对较慢。
宏调用快速,但多次调用时,由于多次复制代码段,造成占用程序存储空间较大。而子程序调用时,由于代码模块只存在于一个地方,因此尽管速度有所减缓,但占用存储空间较少。因此,在要求速度的实时场合应使用宏,以简化编程并保持高速度,在存储容量有限的场合,应牺牲速度(对时间不敏感的慢速情况),采用子程序调用的方法,以降低存储器的占用量。
良好的编程方法和风格靠积累得到,不同种类间的编程可以相互借鉴,对提高编程能力不无好处。7.1.2链接控制命令文件的修改
链接控制命令文件(LinkerCommandFiles, .cmd)也称链接器命令文件,是将由汇编语言和C语言源程序经过汇编和编译生成的目标文件( .obj)按一定的格式组织起来,形成可以被开发系统,如XDS510硬件仿真器和CCS,加载到DSP随机存储器,或固化到DSP非易失存储器的公共目标文件格式(CommonObjectFileFormat,COFF)的“可执行”文件( .out),这个文件也可以被转化为其它二进制文件格式,以便将代码固化于片外非易失存储器中。TI公司提供了像DSPHEX(格式:dsphex[–options]filename)这样的转换工具。
1.汇编语言的段
段(sections)是指连续占用存储空间的一个数据块和代码块。程序按段组织,每行汇编代码都从属于一个段,由段伪指令指明该段的属性。
目标文件COFF至少包含以下三个默认段:代码段( .text),通常包含可执行代码;常数/系数数据段(.data),通常包含初始化后的数据;变量/保留数据段(.bss),通常为未初始化变量保留空间。
而段的类型有初始化段和非初始化段两种。初始化段包含数据或代码,包括 .text段、 .data段以及自定义段 .sect等。非初始化段用于为未初始化变量保留存储空间,包括 .bss段和 .usect自定义段。通常非初始化段被分配到RAM区。汇编程序时,汇编器要对段进行处理。伪指令 .text、 .data和 .sect告诉汇编器停止汇编当前的段,而开始汇编进入指定的段。但 .bss和 .usect伪指令不终止当前的段而开始一个新段,它们只是简单地临时离开当前的段。 .bss和 .usect伪指令可出现在初始化段的任何地方,而不会影响相互之间的内容安排。
“段”通过一个安置过程建立起来,如图7.1所示。例如,当汇编器第一次遇到一个 .data伪指令时,.data段是空的。跟在第一个 .data伪指令后的指令被汇编进 .data段,直到遇到 .text、.sect或 .asect伪指令。如果汇编器在后面还遇到 .data伪指令,则将跟在这些 .data伪指令后面的语句汇编进已经存在的 .data段。这样就形成了单个可被连续分配到存储器中的 .data段。图7.1“段”的安置过程
2.C语言的段
C语言有7个定义好的段,没有了汇编语言中的 .data段,详见表7.11。
表7.11中描述了C语言经编译器编译后,生成的汇编语言对应的段,这些段要在链接控制命令文件中加以正确的配置。其中,“0页”指的是程序空间, “1页”指的是数据空间。 特别地,对 .cinit段, 若“编译选项” 中 “自动初始化(Autoinitialization)”选用了 “-c” 选项(-coption), 设置成“ROMModel”模式,那么,目标文件中的 .cinit段通过下载器加载(固化)到存储器的初始化表中,运行时由引导例程(bootroutine)将其转移到 .bss段空间中;而“-cr”选项(-croption)则是“RAMModel”模式,这时,目标文件中的 .cinit段通过下载器直接加载到存储器的 .bss段空间中。
3.链接控制命令文件的修改
在链接控制命令文件( .cmd)中要设置三项内容,即链接参数指定、存储资源说明和存储资源配置。链接参数指定即指定输入输出文件,以及像C语言中堆栈大小的设置等参数;存储资源说明即可利用的全部存储器资源的说明;存储资源配置则是段在存储资源中的具体定位(配置)。
在CC或CCS中,默认的输入文件是集成环境中编译汇编成的目标文件( .obj),默认的输出文件则是链接好的COFF格式“可执行”文件( .out),以工程项目名称命名。当然,重写一次输入文件也是允许的。如果链接中用到其它输入文件,则可直接列出其(路径)名称;如果要生成其它输出文件,则可直接列出其(路径)名称;其它基本参数的设置情况详见表7.12。这实际上就是CC或CCS中的链接设置选项。存储资源说明由伪指令MEMORY完成,每个存储资源包括存储块所属页(PAGE)、名称、起始地址和长度这几个参数。页分为程序页PAGE0、数据页PAGE1和I/O页PAGE2;名称可根据含义自定;起始地址以ORG(ORIGIN)表示,长度用LENGTH表示,十六进制数可表示成像“0x8000”或“0f000h”的形式。
存储资源配置用伪指令SECTIONS完成,和MEMORY一样,采用统一的格式,将“段”指向存储资源中的相应名称,即可完成配置过程。
为了增强可读性,.cmd文件也需要设置注释,注释符用C语言的格式“/*……*/”。一个典型的 .cmd文件示例如下:7.1.3程序基本结构
程序基本结构就是CC或CCS中的工程项目的结构。一个典型的工程项目包括源程序文件、链接控制命令文件和库函数文件三个组成部分。由于源程序文件中,一般将常用的说明、定义和专用常数等设计成独立的文件存放,以便日后经常性地使用,因此又多出了一个包含文件部分。库函数文件则是经过汇编、编译后,可以直接用于链接的功能程序模块的集合,在完全汇编语言程序中一般不用,而在C语言程序中则常常是必须要加以调用的。在实时采集、处理和控制等要求速度的场合,一般采用单纯的汇编语言( .asm)程序,以求程序的执行效率;在大运算量、高精度处理场合,则采用C语言( .c)程序,以求编程效率;对于两者均有要求的时候,混合编程(.c+.asm)则是明智的选择。
1.汇编语言源程序
用汇编语言编写源程序代码,结构似乎非常简单,它是将零散的、只有原始单一功能的汇编语句(机器语言的助记符)有机地结合成具有一定目标功能的程序。
以下是一段程序举例。上面文件IIR4.ASM是一段实现4阶IIR滤波器的程序,完成256个输入数据的低通滤波功能,截止频率为
/4,对应200kHz采样率时为25kHz。256个输入数据信号用Matlab生成,计算输出y(n)的差分方程式为(7.1)4阶IIR滤波由宏指令IIR4实现。宏指令中,存储器的结构和滤波运算的流程在图7.2中清楚地展示了出来。计算输出y(n)的差分方程见式(7.1),反复调用这个宏指令IIR4可实现一个数据流的滤波处理(上例中调用256次)。但由于每次调用宏均会复制一段代码,因此调用次数过多将会导致存储容量的不足。采用循环措施可解决此问题,只是这样做会增加程序执行时间。图7.24阶IIR滤波器实现方框图
IIR4宏里使用了乘累加及数据移动指令macd和单指令重复指令rpt。每次计算y(n)时,首先将累加器ACC和乘积寄存器P清零,以清除随机初值造成的错误,然后连续进行10次乘累加及数据移动操作,从u(n-4)*b4开始到y(n-1)*a4结束的9次乘累加是必要的,最后一次是为了把第九次乘积P的值累加进取而设,而这次的成绩是作废的。这样,在ACC中即得y(n),同时u(n)和y(n)均被移位(延时),即分别变成了u(n-1)和y(n-1)。
程序中的包含文件将在7.1.4节中讲述。链接控制命令文件(IIR4.cmd)如下:实际操作中,首先打开“SetupCC‘C2000”,将工作环境设置为软件仿真模式,然后运行CC’C2000,在命令菜单栏中选择“Project”,新建一个工程(“New”),取名IIR4,再按前述新建一个源文件“IIR4.asm”,保存至工程项目所在目录中,并将其添加到工程项目中(“AddFilestoProject”)。用同样的方法建立“IIR4.cmd”。编译(“Project\Rebuildall”)无误后,下载(“File\LoadProgram”)程序(工程项目所在目录中的“IIR4.out”)到仿真环境中调试执行。程序生成出错是因为Project选项BuildOptions的输出模组OutputModule未选中AbsoluteExecutable,以及CInitialization选项未选中NoAutoinitialization。CC编译环境默认为C语言(混合)编程环境,纯汇编时要特别声明。否则,在复位向量处应以_c_int0命名(将start换成_c_int0)。
另外,如果建立过程中出现找不到DSPA等程序的情况,那是因为没有指出其路径,可用Windows的环境设置指向其程序所在路径(默认安装路径为C:\tic2xx\c2000\cgtools\bin),或者简单地将其拷贝到CC的执行路径中(默认安装路径为C:\tic2xx\cc\bin)。选中“Debug\Run”直接执行程序,然后用“Debug\Halt”停止执行,这时使用视图功能“View”菜单中的图形调试选项“Graph”的“时间波形/频率特性”功能“Time/Frequency”进行波形和频谱分析。在图形属性的对话框(“GraphPropertyDialog”)中的显示类型(“DisplayType”)选项中选中双时域波形(“DualTime”)功能,修改图的上半部分起始地址(“StartAddress–upperdisplay”)为“0x200”、下半部分起始地址(“StartAddress-lowerdisplay”)为“0x300”、采集缓冲区大小(“AcquisitionBufferSize”)为“256”、显示数据区大小(“DisplayDataSize”)为“256”、DSP数据类型(“DSPDataType”)选择“16-bitsignedinteger”,其它保持默认状态,则可显示出图的上半部分为输入信号波形,下半部分为滤波后的信号波形,如图7.3所示。图7.34阶IIR滤波器效果可见,在滤波器设计时设计得很好的效果,在实际实现过程中则差得多。原因何在?主要是IIR滤波器的字长效应,在运算过程中将乘累加的32位结果变成了输出的16位结果,而这16位是要参与反馈运算的。
比较好的解决办法是采用二阶节级联,这样会减轻字长效应。将图7.2中的4阶IIR滤波器实现方框图去掉输入、输出的最后两个延时,就变成了二阶节的形式。为了对比,这里给出两个二阶节级联的源程序IIR4_cas.asm。链接控制命令文件IIR4_cas.cmd如下:上述程序执行结果示于图7.4中。与图7.3对比,级联两个IIR二阶节的滤波效果比4阶IIR直接型滤波器的效果好得多。这两个例子的完整程序已放置于光盘中。图7.4级联两个IIR二阶节滤波效果
2.C语言源程序
用纯粹的C语言编写的源程序,过程非常简单,但是这样做带来的后果是执行速度的降低。建立一个完整工程项目的方法和纯汇编的方式大体相同,只是要添加一个库函数文件rts2xx.lib(在CC的安装目录下的\c2000\cgtools\lib路径中)。程序设计完全按C语言的标准和要求进行,如程序中有且仅有一个含有main()函数的源文件等。
下面给出一个C语言编程的例子,产生一个混叠1~4kHz四种正弦波信号的多谐波数据,源程序为SineWave.c,链接控制命令文件为SineWave.cmd,编译环境用CC默认情况即可,结果如图7.5所示,程序在SineWave_C工程目录中。图7.5C语言程序产生叠加正弦波的多谐波信号
3.C和汇编混合编程
为了兼顾编程效率和代码效率,常采用C和汇编的混合编程模式。在混合编程模式下,汇编语言程序完成硬件接口和高速运算的功能,C语言程序完成通常的计算、总体程序结构和繁杂的事务管理等功能。
混合编程模式中的汇编语言程序常以子程序的形式出现,即构成了C函数,因此编程中要符合C的风格参数传递和结构要求。
在C语言中插入单句汇编语句的方法仅完成简单的功能,一般只用在DSP中特定硬件部件的定式初始化中,而非变量式的控制上。如果用这种方法对存储器或寄存器进行操作,可能会破坏C工作环境中的变量及数据。说明符asm完成该功能,语法格式为
asm(“assemblertext”);标准应用是将汇编模块设计成标准C函数。事实上,TI公司对TMS320'C2000系列DSP提供了极为丰富的用常用汇编语言设计成的子程序或标准C函数模块,速度比直接使用C编程快得多,注册用户可以免费下载使用。如谱分析模块(C24xFastFourierTransform[FFT]Library.zip)、数字滤波模块(C24xFilterLibrary.zip)、定点数学运算模块(C24xFixed-PointMathLibrary.zip)、信号发生器模块(C24xSignalGeneratorLibrary.zip)和软件测试平台模块(C24xSoftwareTestBench(STB)Library.zip)等。而对于控制应用,也有一套完整的子程序或标准C库函数(GeneralTools&SoftwareforTMS320LF240xControllers)供使用。
TMS320‘C2000大类中的TMS320’C28xx系列DSP,由于其32位的结构,TI提供了对应的另外一套程序模块套件。
很多应用中,需要开发者自己设计专用的C函数模块,因此需要搞清楚被调用的汇编C函数与调用者之间的必要交接和参数传递。
C语言程序调用汇编语言写成的函数,其相关操作如图7.6所示。现以软件低通滤波为例,举例说明如下。图7.6C语言程序调用汇编语言程序的相关操作设C语言调用函数为
[b0,b1,b2,…,bn]=func(a0,a1,a2,…,an);
这里,[b0,b1,b2,…,bn]用于函数返回结果,也可为一个结构体,为了便于书写,故意写成伪码形式。func(a0,a1,a2,…,an)为汇编语言写成的被调函数,a0,a1,a2,…,an为实际传递参数。
调用函数时,首先是完成软堆栈的一系列操作,然后是下一语句对应的首条汇编指令地址(对应PC值)入栈(8级硬栈),接着交由汇编函数执行。软堆栈的堆栈指针SP由AR1担任,函数帧的帧指针FP则由AR0担任。这两个指针均针对地址增量方向增量修改。函数帧是指每个函数体使用的软堆栈集合。
软堆栈的一系列操作包括函数传递参数。当程序交由汇编函数执行时,已完成了堆栈的操作,此时堆栈指针SP指向一个空闲的地址单元。SP减1后指向参数传递区,这个区域按倒序依次存放着a0、a1、a2、…、an等参数。如果参数是长整型等32位数值,则高位字在低地址,而低位字在高地址。软堆栈的一系列操作也包括函数返回结果(结构体)空间预留,设置在调用函数帧中。对于几个返回值的情况,首个返回值b0置于ACC中,其余返回值则在参数之前的堆栈位置,按倒序依次存放为b1、b2、…、bn。对于结构体返回值的情况,实际上是将结构体的地址作为参数传递中的最后一个参数(附加参数)传递给被调函数,因此被调函数可以直接赋值给结构体。由于硬件堆栈只有8级,每次调用函数或发生中断必然保存断点,结果均会占用至少一个堆栈单元,这样很容易造成堆栈溢出,导致程序运行混乱,因此有必要采用软堆栈来缓冲。同时,为了C代码的正常返回和原现场(程序执行的状态环境等)的正常恢复,原来函数帧的帧指针和堆栈指针以及必要的现场状态须加以保护。
这样,接下来的软堆栈的操作如下:
(1)把返回地址从硬件堆栈中弹出到软件堆栈;
(2)保存AR0(FP)和AR1(SP)寄存器;
(3)保存状态寄存器ST1和ST0;
(4)如果汇编代码用到了AR6和AR7寄存器,则应该保存这两个寄存器;
(5)执行用户的汇编代码(实际函数体功能);
(6)根据上面的返回信息返回结果(如果有的话);
(7)重设AR1为当前辅助寄存器,然后按(4)到(1)的步骤反向执行这几步操作;
(8)函数返回。
程序执行结果如图7.7所示,实际程序(在Cca工程目录中)如下。图7.7C语言程序调用汇编语言函数结果波形图●汇编语言函数其中,包含文件IIR4COEF.h内容如下:
Coefb4.sect“Coefb4”
.word119,24,173,24,119,1874,-7379,12459,-10534
● C语言主函数●链接控制命令文件
C语言中保留了4个内核寄存器AR0、AR1、AR6、AR7(AR6、AR7保留用于关键字register或优化使用),以及两个状态寄存器ST0、ST1,在汇编函数中使用时必须加以保护,而AR1则是绝对不可用于函数功能代码中的。
顺便指出,在调试程序中,有些常见错误并不容易被发现,特别是汇编语言程序中,如编程中错误地使用了中文符号,将标号置于第1列(行首)后面,将指令(或伪指令)置于第1列(行首)的位置,文件路径包含有中文字符等。这是由软件开发工具的基本要求或版本局限造成的,开发者只能适应。7.1.4Matlab生成系数的方法
7.1.3小节中IIR4程序中的两个包含文件可用Matlab生成。其中,“INPUT.inc”是数据输入文件,在实际操作中应该是实际采样数据,这里暂时采用软件仿真的方式来作为入门练手,可用人工产生数据的办法。下面是生成两个30kHz和50kHz正弦波叠加的Matlab程序,采样频率为200kHz,生成的数据文件为“INPUT.inc”。这个例子生成的数据比较简单,实际上Matlab有很丰富的函数,可生成雷达、通信以及医学电子等各种领域的确知或随机仿真信号。
而滤波系数文件的生成相对复杂些,因为实际上这是一个滤波器设计过程,要涉及到数字信号处理原理的内容,就是常说的“算法”。不过由于Matlab的完备性,这项工作并不困难。
以下是一个设计直接型四阶IIR滤波器的Matlab程序,生成“IIR4COEF.h”系数文件。由于直接型IIR滤波器对字长极为敏感,实际应用中大多采用二阶节级联型结构。以下是一个将直接型四阶IIR滤波器设计转换为两个二阶节的Matlab程序,生成“IIR4_cas.h”系数文件。需要注意的是,在Matlab中,同样不能使用汉字或加减号作为程序文件或命令名,否则将找不到该文件或命令。
7.2主要DSP硬件模块编程举例
7.2.1几个特殊I/O引脚编程举例
TMS320‘C2000系列DSP中有几个特殊I/O引脚,它们是XF、BIO、IO3~IO0等,在TMS320’C24xx中还有PORTA~PORTF等6个通用I/O端口。这些端口对DSP在控制领域中的应用提供了极大的方便。
1.XF、BIO、IO3~IO0的使用
基于TMS320F206的XF、BIO、IO3~0的简单应用类似于第6章的图6.7(使用F206EVM实验模板),按键控制BIO引脚电平进行状态切换,IO2接红色、XF接绿色发光二极管显示状态变化。编制汇编程序描述如下:上述程序见于CDROM的程序路径,子目录工程名称为Peripheral_IO,包含文件init.h具有常用的说明定义参数,包含文件vector.h则给出了中断向量的定义,程序中中断返回部分使用的标号就是在向量包含文件给出的。链接控制命令文件和前面的例子类似。该程序执行结果是当监测到按键K100按下接通时,BIO为低,红绿灯齐亮;松开时,BIO为高,则交替发亮一段时间。程序只对BIO检测一次,可方便地修改为连续检测的方式,这时交替次数和延时可适当减少。
应注意到,当需要使用源程序调试时,可以设置BuildOptions中Assembler的g参数,即选中EnableSourceLevelDebugging选项;而只需反汇编调试时,则禁止。
PORTA端口的使用
TMS320LF2407具有4个8位通用IO端口PORTA/B/C/E、1个1位通用IO端口PORTD和1个7位通用IO端口PORTF,它们与其它片内外设复用IO引脚,默认情况下连接于通用IO端口。下面PORTA为例,说明IO端口的使用方法。
其实IO端口的使用极为简单,硬件电路可以这样连接,将IOPA4~IOPA7作为输入,分别通过4个10kΩ电阻上拉到电源VCC,并且分别通过4个按键接地;将IOPA0~IOPA3作为输出,以灌电流方式分别将4个150Ω电阻和4个发光二极管LED串联,端接于IOPA0~IOPA3和电源VCC之间。当有键按下时,相应的IOPA4~IOPA7口被置低,程序检测后设置对应IOPA0~IOPA3位为低,相应的LED被点亮。7.2.2中断编程举例
DSP的中断具有复用的特点,在‘C2xx中,和
复用一个管脚/,而INT2和INT3则共用一个屏蔽位和中断向量。因此,实际应用中,除设置全局中断屏蔽位INTM、中断屏蔽寄存器IMR外,还要通过中断控制寄存器ICR的MODE、MINT2、MINT3位进一步区分和以及INT2和INT3的禁止特性。同样地,ICR中的FINT2、FINT3位辅助中断标志寄存器IFR判别INT2和INT3的中断标志。下面给出一个实际汇编语言编程的例子。按图6.6中的F206EVM实验板的外中断连接电路接法,用跳线帽接通J101第二行(外部INT1中断口),并通过接口J100送入一个TTL电平的方波信号,作为INT1的中断触发信号。方波频率选用10~50Hz。程序设计成接收中断后由异步串行口UART发送一个字符,其输出再经过如图6.21所示的RS232电平转换电路后向PC机传输。在PC机一端则可使用像串口大师(ComMaster)一类的调试程序接收数据。使用10Hz方波信号,采用单独下降沿触发模式,5秒内可收到50个字符(ASIIC字符“5”或二进制35h);采用上升沿/下降沿双沿触发模式,5秒内则可收到100个字符。该程序见于第2章2.5节最后的程序举例。注意,这是一个并不完善的串行发送程序,在程序中,不管UART的发送寄存器是否为空,只要有中断,就发送数据。当中断速度较快时,可造成后面的发送字符覆盖前面发送字符的错误,导致接收字符异常。
将输入TTL电平方波信号频率改为1Hz,一个C语言程序见光盘Interrupt_C子目录,主程序和链接控制命令文件如下。程序执行结果是:LED 灯随外部输入信号闪烁,而 PC机可接收串行信号,显示字符“6”。
C语言主程序:链接控制命令文件:
在‘C24xx中,中断源的数量增加了很多,各种外设产生的中断源通过外设中断扩展控制器(PeripheralInterruptExpansionController,PIE)连接到核心中断请求端INT1~INT6上。图7.8给出了TMS320’C24xx外设中断扩展原理方框图。
实际上,这些中断源几乎为片内外设占用了,留下的几个不多的独立外部中断源为复位RESET、非屏蔽中断NMI和两个扩展外部中断XINT1、XINT2以及用于功率控制如电机控制的功率驱动保护PDPINTA、PDPINTB等。图7.8TMS320'C24xx外设中断扩展原理方框图因此,TMS320'C24xx上中断初始化设置和中断响应相关的寄存器增加了2个扩展中断控制寄存器XINT1CR和XINT2CR,1个外设中断向量寄存器PIVR,3个外设中断请求寄存器PIRQR0、PIRQR1和PIRQR2,3个外设中断响应寄存器PIACKR0、PIACKR1和PIACKR2。编程中要注意这些寄存器的正确设置和使用。7.2.3中断向量在单片系统调试中的处理
作为实验系统,一般都会设置片外存储器扩展,这时调试程序很方便,因为程序可以加载到片外RAM上而无须烧写,这对固定地址位置的中断向量和非固定地址位置的中断服务程序而言是极其重要的。
对于一般的应用系统,很多时候无须设置片外存储器扩展,以单片系统方式工作,这时程序一般是安放在片上的Flash中。但是Flash的烧写次数非常有限,在调试过程中经常性地修改程序,无限制地对Flash进行烧写,势必导致Flash的永久性损坏。解决这个问题的办法就是使用片内RAM,但是片内RAM的地址定位不含中断向量区,因此对复位和中断的使用就会出问题。
首先研究一下TMS320'C24xx中断响应过程的特点。当响应中断时,首先通过主向量段进行第1次跳转,这是硬件完成的。然后,由程序计算外中断向量位置,即由先前定义的中断源决定PIVR的值——外中断向量偏移量,加上外中断向量段基址,就得到了外中断向量地址,这样完成了第二次跳转。最后,由外中断向量跳转到实际中断服务程序,实现实际的中断过程。详见图7.9所示。更多资料参阅TI文档SPRU357B。图7.9TMS320'C24xx中断向量转移示例当然,如果中断源不是很多的话,可以把重要的、实时性高的中断单独安排,这样可以省掉后两个跳转的过程。
图7.9中,只有主向量段的位置是固定的,即程序空间地址00h~3Fh,其它地址可以任意决定。因此可以考虑只固化这段Flash空间来解决调试问题。
调试过程中,中断向量的巧妙处理可以解决前面的这一矛盾,即可以考虑采用主向量段中插入一个固定跳转的办法来解决这个问题。首先按正常方式设置中断向量,但是向量处的跳转语句的目的地址不是程序计算外中断向量位置或中断服务程序,而是一个固定地址,这个地址是安放程序的片上RAM的某个位置,如8000h,这个位置可以称为二级向量,然后再从这个二级向量跳转到程序计算外中断向量位置或中断服务程序。调试时只烧写中断向量的部分到Flash上,程序的其它部分则通过程序装载(LoadProgram)的办法加载到片内RAM中,具体做法如图7.10所示。下面给出主程序的关键字段和实际向量段以及链接控制命令文件的关键语句,完整程序见光盘中的Flash_for_Programming(用于程序固化)和SRAM_for_Debug(用于调试)子目录。图7.10中断向量的巧妙处理示例图调试中,用于固化的向量包含文件“vectors.h”,向量通过8000h中转。这样,链接后中断主向量段相当于位于8000h,子向量段相当于位于8040h。在用SRAM进行程序加载调试时,可以不加改变。调试完成后,真正工作时的固化向量用分号“;”后的真实标号即可。
用于固化中断向量于Flash的链接控制命令文件包含如下语句:而用于加载程序于SRAM的链接控制命令文件包含如下语句:
COMMAND资源说明段:中断向量的巧妙处理便于调试而又不伤及Flash,是一个“曲线救国”的办法。但实际应用中不能每次都使用仿真器加载程序来执行,因此要把程序写入到Flash中。
系统调试好以后,可以纠正增加跳转的中断方式,按正常方法重新设置中断向量。即向量处的跳转语句的目的地纠正为程序计算外中断向量位置或中断服务程序。
使用链接控制命令文件建立*.OUT文件,然后使用Flash固化工具将该*.OUT文件烧写到Flash非易失存储器中。这时程序工作区虽不是SRAM区,但仍可以进行在线调试,只是代码不能靠加载修改而已。烧写后无须再加载程序,但为了调试方便,可以加载符号。这种方法对TMS320F206同样适用。但是,在TMS320F206中会更加简单。因为那里没有更多的中断源,并且没有子向量段重定位的问题。
对于如何固化(Flash烧写),在第5章中已有所谈及。为了便于操作,这里再给出一个简单的过程描述。
1) TMS320F206烧写
要烧写Flash,只能在Windows95或Windows98系统中进行,因为其程序是基于DOS的版本。如果不修改TI默认的编程代码,要求使用20MHz的主时钟频率,即注意时钟模式和时钟频率,保证CLKOUT1频率为20MHz,周期为50ns。
(1)在Windows98上拷贝TI原版TMS320C2xx的DOS开发包目录,在dbg目录下工作;
(2)执行BT0.BAT和BT1.BAT对JTAG接口及目标DSP的连接情况进行测试;
(3)执行BC0.BAT和BC1.BAT对0区和1区Flash清除(置0);
(4)执行BE0.BAT和BE1.BAT对0区和1区Flash擦除(置1);
(5)执行命令“BP18K0被烧写文件完整路径名1”或“BP18K1被烧写文件完整路径名2”对Flash进行编程。
2) TMS320F240烧写
TMS320F240的烧写要求同F206,如果不修改TI默认的编程代码,要求使用外部时钟或晶振必须是10MHz,否则需调整算法延时值。闻亭公司对TI原版工具略做了修改,可以使用,方法如下:
(1)在Windows98系统上安装WinTechepp24x,得到C:\Tdsepp24x\flash24x目录;
(2)执行BTEST.BAT对JTAG接口及目标DSP的连接情况进行测试
(3)执行BC0.BAT对Flash清除(置0),BC0.BAT包括如下两个命令:
C:\TDSEPP24X\Flash24X\prg2xxpp-p378-m0x0006-w6-s0x4000-e–o
C:\TDSEPP24X\Flash24X\c2xx_bcX.out
(4)执行BE0.BAT对Flash擦除(置1),BE0.BAT包括如下两个命令:
C:\TDSEPP24X\Flash24X\prg2xxpp-p378-m0x0006-w6-s0x4000-e-o
C:\TDSEPP24X\Flash24X\c2xx_beX.out
(5)执行命令“BP8K被烧写文件完整路径名”或“BFLW0被烧写文件完整路径名”,对Flash进行编程。BP8K.bat和BFLW0.bat分别包括如下命令:这里的%1为批处理命令参数,代表“被烧写文件完整路径名”。而378为计算机标准并行口SPP或增强并行口EPP的实际设置使用端口基地址。
另一种简便方法是使用安装于Windows98桌面的“TDSEPP24x”文件夹,执行“并口检测”、“调试”等快捷图标命令,和“F24x编成”文件夹下的“清除”、“擦除”、“编程”命令,编程时可选择被烧写文件完整路径。对于TMS320LF2407A,由于作为TI的主流产品,在具有很好的性能价格比的同时,TI公司给出了其Flash编程插件,最新版本为c2000flashprogsw_v112,它支持TMS320LF2407/LF2407a/LF2401及其它相关的TMS320LF240x系列,可以在TI的官方网站上免费下载,建议使用该版本。光盘中也放进了该烧写程序。
3) TMS320LF2407A烧写
工作电压VCC为3.3V,编程电压VCP为5V,方法如下:
(1)先解压c2000flashprogsw_v112插件,再执行setup.exe安装,安装过程中要选择TMS320‘C2000的工作路径。
(2)运行CC中,在tools命令图标下出现上述烧写工具。运行该烧写工具,按提示进行相应的操作即可。执行烧写操作时,要注意如下问题:
(1)关于Flash时钟的选择。此烧写工具默认最高频率进行Flash的操作。根据目标系统的工作主频,要重新进行PLL设置,方法是:先在advanceoptions下面的ViewConfigfile中修改倍频,存盘后,在相应的目录(tic2xx\algos\相应目录)下运行buildall.bat,就可以自动完成修改更新了。
若所选频率不是最高频率40MHz,则还需要设定自已的timings.xx来代替系统默认最高频率的timings.xx。例如TMS320LF2407A的默认文件是timings.40。Timings.xx可以利用include\timings.xls的Excel工作表来生成,然后在advanceoptions下面的ViewConfigfile中修改相应的配置。存盘后,在相应的目录下运行buildall.bat就可以完成修改了。
(2)加密功能考虑。对于TMS320‘LF240XA系列还应注意:由于这些DSP的Flash具有加密功能,加密地址为程序空间的0x40~0X43H,程序禁止写入此空间,如果写了,此空间的数据被认为是加密位,断电后进入保护Flash状态,使Flash不可重新操作,从而使DSP报废。产品开发完成,烧写完毕后,一定要进行Programpasswords的操作,如果不做加密操作,就默认最后一次写入加密位的数据为密码。
(3)与以前TMS320'C2xx版本不同。TMS320'2407A与以前TMS320'C2xx版本从内核的角度看是一致的,但Flash结构不同,增加了加密功能,编程方法不再兼容。因此不能用DOS下的烧写软件烧写,必须用c2000flashprogsw_v112软件烧写。
(4)对TMS320LF2407A使用的一些建议:
①一般调试时,在RAM中进行;
②程序烧写时,避开程序空间0x40~0x43H加密区,程序最好小于32k;
③每次程序烧写完毕后,将word0,word1,word2,word3分别输入自己的密码,再点击Programpassword,如果加密成功,提示Programisarrayed,如果0x40~0x43h中写入的是ffff,则认为处于调试状态,Flash不会加密;
④断电后,下次重新烧写时需要往word0~word3输入已设的密码,再unlock,成功后可以重新烧写了(调试状态不需要);⑤VCPP管脚接在 +5V上,即编程电压VCP是直接加上的,中间不应串接电阻;
⑥具体事宜请阅读相应目录下的readme1、readme2帮助文件;
⑦注意*.cmd文件编写时应该避开40~43H单元,否则会把Flash加密,造成器件永久性不能使用。
使用硬件仿真器调试或固化程序时还要注意以下几点:
(1)CC和XDS510PP或XDS510USB的相应驱动可在Windows98/Windows2000/windowsXP系统中运行。但现在某些计算机对并行口的支持存在问题,或USB接口不是全面兼容,因此当出现仿真器不能正常复位或找不到目标DSP器件时,应首先换一台并行口或USB接口正常的计算机再试。
(2)调试中若全部使用片外程序存储器,则可极方便地通过JTAG口下载并调试程序。若使用片内SRAM,则需注意其定位不是从0开始,因此其中断向量问题必须处理好。前述二次定位向量的办法可行。
(3)使用片内RAM之前,应通过寄存器编辑来设置ST1的D12(CNF)=1和/或存储器编辑(实际是I/O空间)来设置(IS@FFE4h)的D1(PON)=1,从而定义程序存储器,以保证硬件仿真中存储器的逻辑存在。
(4)使用片外程序RAM之前,应通过存储器编辑(实际是I/O空间)来设置PMST(IS@FFE4h)的D0(MP/MC)=1来定义外部程序存储器,设置WSGR(IS@FFFCh)来定义外部程序存储器等待状态。
(5)在工具栏OPTION选项中的MemoryMAP要设置好。7.2.4定时器编程举例
TMS320‘C2000系列DSP的定时器中,当主计数器周期寄存器PRD与预定标计数器周期寄存器TDDR的内容不同时为0时,其溢出率或中断速率由下式确定:(7.2)式中,tc(CO)为CLKOUT1的周期。当PRD=TDDR=0时,定时器的溢出率或中断速率固定为(7.3)由于计数器采用减法计数模式,因此TMS320‘C2000系列DSP定时器的使用变得简单。第2章的2.5.2节给出了TMS320F206汇编语言的编程举例,详细文档见光盘中的Peripheral_Timer子目录。程序可在F206EVM实验板上执行,运行后定时器每隔204.8μs产生一次中断,可见LED灯快速闪烁。
同样功能的C语言程序描述如下,详细文档见光盘中的Peripheral_Timer_C子目录。对于TMS320‘LF24xx,由于片内定时器较多,并且增加了看门狗,其编程考虑和F206有较大的差异。为了便于使用,这里再给出一个C语言编程实例。
通用定时器1产生1s定时中断的程序举例:外部输入时钟为10MHz,经过DSP的内部锁相环1倍频后还是10MHz,通用定时器1的预分频因子为64,可计算出周期寄存器的值为3D08h。详细文档见光盘中的Peripheral_2407Timer_C子目录。7.2.5UART编程举例
异步串行口具有独立的波特率发生器,只要设定波特率除数寄存器BRD的值,即可决定波特率的大小。特殊情况,当BRD为0时,异步串行口将停止工作,不再接收和发送任何数据。复位时BRD为0001H,波特率因子是16,因此主时钟CLKOUT1频率一定时,波特率与BRD值的关系式如下:(7.4)一个TMS320F206的异步串行口程序举例如下。程序从串口读入一个数据后加1,然后再发送出去。数据采用8个数据位加1个停止位格式。波特率设置为2400波特,以中断方式收发字符。详细文档见光盘中的Peripheral_Uart子目录。
该程序可在F206EVM模板上运行,用PC机进行调试。首先加载并运行DSP程序,然后用串口调试程序发送、接收字符。可以逐个操作,也可以成批操作(定时发模式,要与波特率配合,速度不能过快)。结果是收到的字符总是发送值加1。
TMS320'C240x的串行通信接口(SCI)即异步串行口,波特率因子为8。SYSCLK为系统时钟,即经过锁相环后的频率值。串行口波特率的计算公式如下:(7.5)其中,BRR为波特率选择寄存器的值,16位。当BRR=0时,其作用和BRR=1完全相同。这点与TMS320F206完全不同。一个典型应用举例如下。本例使用双机通信,以中断方式收发数据,发送一个字符串,接收若干数据,但只保存最近接收到的10个字符。程序完整文档见光盘中的Peripheral_2407Uart_C子目录。7.2.6SPI编程举例
TMS320F206的SPI编程将在7.3.2节F206EVM实验系统板编程举例的综合应用中给出,这里只描述TMS320LF2407A的SPI编程情况。
TMS320LF2407A中集成了一个4引脚的串口外设接口(SPI) ——同步串行口。SPI是一个高速、同步串行接口,它以同步方式发送和接收串行位流(字符),位流(字符)长度1~16位可编程,传输速度可编程。SPI通常用于DSP与片外设备(器件)以及其它处理器之间的近距离通信。SPI基本情况已在2.6.5节中介绍。实际使用中要设置SPI的工作模式(主/从)、字符长度、波特率等参数,通过配置控制寄存器SPICCR、控制寄存器SPICTL、波特率设置寄存器SPIBRR实现。通过状态寄存器SPISTS检查其工作情况。
这里介绍一个简单的实验电路,TMS320LF2407A与数字电位器MAX5400采用SPI接口,TMS320LF2407A以主模式工作,完整程序见光盘中的Peripheral_2407SPI_C子目录。程序编制如下:7.2.7PWM编程举例
TMS320‘C24xx包括两个事件管理模块EVA和EVB,每个事件管理器模块均可产生PWM波,而PWM是控制中极为常见的功率驱动方式,因此TMS320’C24xx在控制领域应用相当广泛。在3.7节中已给出了PWM波形产生的C语言编程举例,而综合应用则将在7.3.3节的基于TMS320LF2407的雷达天线控制系统编程举例中给出,在此不再赘述。7.2.8ADC编程举例
TMS320LF2407A的模数转换模块ADC在2.6.3节已经有所介绍,这里再做一些补充。
10位模数转换模块ADC具有16个模拟输入通道(ADCIN0~ADCIN15),内置采样/保持(S/H)功能。各通道可按自动扫描方式工作。一次扫描过程可执行最多16个通道的自动转换,而每次要转换的通道都可以通过编程来选择。两个独立的最多可选择8个模拟转换通道的扫描排序器可以独立工作在双排序器模式,或者级联之后工作在一个最多可选择16个通道的排序器模式。在给定的排序方式下,4个排序器决定了模拟通道转换的顺序。可单独访问的16个结果寄存器(RESULT0~RESULT15)用来存储转换结果。多个触发源可以启动ADC,包括软件启动、事件管理器启动和外部启动等三种。灵活的中断控制允许在每一个转换或每个一个序列转换结束时产生中断请求。排序器可以工作于启动/停止模式,允许多个按时间排序的触发源去同步模数转换。EVA和EVB可分别独立地触发SEQ1和SEQ2。采样/保持采集时间窗具有独立的预定标控制能力。模块具有标定模式。
1.连续自动排序模式
ADC排序器由两个独立的8态排序器SEQ1和SEQ2组成,它们也可以级联成16态排序器SEQ。这里说的“态”是指排序器能完成的自动转换的数目。单排序器(级联16态)模式和双排序器(两个独立的8态)模式分别示于图7.11和图7.12中。
SEQ1和SEQ2分别在一次排序过程中对多达8个的任意通道进行排序转换,每次转换结果被保存到8个结果寄存器中,SEQ1的结果寄存器为RESULT0~RESULT7,SEQ2的结果寄存器为RESULT8~RESULT15。图7.11级联工作方式下自动排序ADC结构图图7.12双排序工作方式下自动排序ADC结构框图需要注意的是,在双排序器工作模式下,“未被激话”的排序器的A/D启动请求会在“被激活”的排序器完成采样之后自动开始执行,即当SEQ1启动一个触发信号后,而SEQ2正在执行操作,那么AD转换器会在SEQ2的操作完成后立即响应SEQ1的请求。
例如,需要使用SEQ1来完成8个通道的转换,这8个通道是1、2、3、5、6、7、10、15,则在最大转换通道寄存器MAXCONV1中设置7,然后设置选择排序控制寄存器CHSELSEQn的转换顺序(在MAXCONV中填入0x07,在CHSELSEQ1中填入0x5321,在CHSELSEQ1中填入0xFA76)。转换结果存放于ADC转换结果缓冲寄存器RESULTn中。
2.排序器启动/停止模式
除了连续自动排序模式外,任何一个排序器(SEQ1、SEQ2或SEQ)都可工作在启动/停止方式。在该模式下可以实现单独和多个启动信号触发源同步,与连续的自动排序模式不同的是该模式下排序器完成第一个转换后中断不需要被复位,但是ADC控制寄存器1(ADCTRL1)的连续执行位CONTRUN(Bit6)必须被设置为0。例如,需要完成6个通道(通道1,2,3,5,6,7)的转换,但是一个触发源可以启动3个自动转换,则首先需要在MAXCON1中设置2,然后再设置选择排序控制寄存器CHSELSEQn的转换顺序(在MAXCONV中填入0x02,在CHSELSEQ1中填入0x5321,在CHSELSEQ1中填入0x0076)。设置完后,当第一个触发源到来时,触发ADC转换,通道CONV00(I1)、CONV01(I2)、CONV02(I3)被选中执行;当第二个触发源到来时,再次触发ADC转换,通道CONV03(V1)、CONV04(V2)、CONV05(V3)被选中执行;当第二个触发源转换结束之后,SEQ1在当前还是保持等待状态,直到第三个触发源的来临,用户也可以通过软件复位SEQ1。
ADC转换结果缓冲寄存器(RESULTn)的地址范围在70A8h~70B7h,结果存放格式如图7.13所示。转换结果数据与输入电压和参考电压有关,见式(7.5)。参考电压为外部输入,分上参考电压Vrefhi和下参考电压Vreflo两部分。(7.6)图7.13ADC转换结果缓冲寄存器(RESULTn)
3.ADC模块编程举例
下面介绍一个ADC模块数据采集程序。该程序用EVA的定时器2作为采样定时时间来触发ADC转换的启动。ADC采用级联模式,一次做0、1通道的两个转换。转换完成后,在ADC中断服务子程序中将转换结果读出,然后复位排序器使排序器指针指到CONV00,直到满足采样512个点。汇编语言完整程序见光盘的Peripheral_2407ADC_ASM子目录,C语言完整程序见光盘的Peripheral_2407ADC_C子目录。
汇编语言主程序如下:
C语言主程序如下:
7.3应用系统软件设计举例
前面采用软件仿真或硬件仿真的方法已就‘C2000系列DSP的相对独立功能或片内部件的使用进行了编程,这种程序往往不具备系统特性,因此本章从系统的角度,讨论应用程序的编制、调试和代码加载方式等,以达到离开仿真系统后DSP应用系统能脱机独立运行的目的。
7.3.1TMS320LF2407最小应用系统编程举例
第6章给出了TMS320LF2407最小应用系统的硬件设计方法,这里对在该系统上实现的IIR滤波器、FIR滤波器以及基于FFT的谱分析的系统软件设计方法进行描述。
1.TMS320C2000上IIR滤波器设计
IIR滤波程序在7.1.3节的程序基本结构中已经做了较为详细的介绍,在设计方法和仿真上这里不再重复。程序详细内容参见光盘中的MinSYS_2407_IIR_Sim子目录。
而对于实际采集信号的处理,一般有两种方法,即分段采集处理和逐点采集处理两种。分段采集处理就是先采集一段时间的数据,然后像静态数据一样用类似前面仿真执行的方法进行处理。这种处理方法对周期性信号、缓变(慢速)信号能达到实时处理的要求,当然对实时性要求不高的场合也适用。一个例子是采集2kHz方波信号,然后滤除高次谐波得到正弦波的过程,采样频率是30kHz,结果如图7.14所示,上半部分波形为采集到的方波,下半部分波形则为低通滤波后的正弦波信号。程序详细内容参见光盘中的MinSYS_2407_ADC_IIR子目录。其它信号则需采用逐点采集处理方案。图7.14实际采集滤波处理结果逐点采集处理则是一边采样、一边处理、一边输出处理数据的方式。这种方法对程序编制要求较高,即不但要功能上能够实现,更重要的是要解决好三者间的时序配合即实时要求。由于TMS320'C2000系列DSP的速度不是很快,因此按这种方法,它能处理的信号带宽应在数十千赫兹以内。这里给出一个以10kHz采样频率采集1kHz方波信号进行低通滤波处理的C语言编程的例子。主程序如下,详细内容参见光盘中的MinSYS_2407_ADCIIR子目录,结果见图7.15。虽然两种方法处理流程不同,但结果类似。图7.15逐点采集滤波处理情况(a)采集输入与滤波输出波形图;(b)采集输入与滤波输出频谱图(a)(b)
2.TMS320‘C2000上FIR滤波器设计
实际信号的采集与FIR滤波流程基本上和上面的IIR情况一致,所不同的只是滤波器的实现方式。FIR滤波器很容易实现线性相位特性,因此很适合用于对波形有要求的应用场合。但是FIR滤波器的效率比IIR要低得多,因此,要得到同样的滤波效果,其阶数比IIR大得多。结果是这种情况下的信号处理带宽大约比IIR要低一个数量级。
限于篇幅,这里不再列出程序详细内容,分段采集处理,即以5kHz采样率采集500Hz方波信号进行低通滤波处理的程序参见光盘中的MinSYS_2407_ADC_FIR子目录,逐点采集处理程序见光盘中的MinSYS_2407_ADCFIR子目录。
3.TMS320‘C2000上基于FFT的谱分析
由于基于FFT的谱分析需要一个时间段的信号,因此只能采用分段采集处理的方法。又由于现在的显示设备很灵活,因此作谱分析时不必像以前那样再把频谱信号变成模拟信号后通过示波器显示。
FFT是DFT的快速算法,DFT的输入信号默认为复(数)信号,实际应用中,大多数信号是以实信号方式出现,因此利用DFT的一些性质,将实信号表示成一个复信号,则信号长度将减少,从而减少计算量。设有长度为2N的序列g(n),将其分为长度为N的两个奇偶序列:(7.7)并将这两个奇偶序列组成一个新的复序列x(n):
x(n)=xe(n)+jxo(n)(7.8)这里,n=0,1,…,N-1。显然,DFT[xe(n)]=Xep(k),DFT[xo(n)]=-jXop(k),DFT[x(n)]=X(k)则有
X(k)=Xep(k)+Xop(k)(7.9)令X(k)=Xr(k)+jXi(k),且令(7.10)则有(7.11)这里,k=1,2,…,N/2-1。对于其它k=0和k=N/2点,有(7.12)
可见,通过对组合复序列x(n)进行FFT变换,可求出其实部Xr(k)和虚部Xi(k),通过式(7.10)~式(7.13),可求出共轭对称分量Xep(k)和共轭反对称分量Xop(k)。注意,这里是N点DFT。
实际上,如果有两个序列x1(n)和x2(n),设x1(n)=xep(n),x2(n)=xop(n),则Xep(k)和Xop(k)则分别是它们各自的DFT。这样,用一个N点复DFT求出了两个N点实DFT,N较大时,运算量几乎减少一半。(7.13)设长度为2N的序列g(n)的DFT为G(k),令(7.14)则可推导出:(7.15)(7.16)其中,(7.17)这里,k=1,2,…,N/2-1。对于其它k=0、k=N/2和k=N点,有(7.18)(7.19)(7.20)可见,通过式(7.15)~式(7.20),再结合式(7.14),可得长度为2N的序列g(n)的DFT的前半部分,即k=0,1,2…,N的G(k)。
利用实序列DFT的共轭对称性,可容易地求出G(k)的后半部分:
X(2N-k)=X*(k)
(7.21)
这里,k=1,2,…,N-1。
其实,如果DFT是用于实信号的功率(幅度)谱分析,则只需要前半部分即可得到全部信息量。
TI公司免费给出了128/256/512点实序列和复序列的FFT程序模块,有汇编语言子程序和C语言函数两种方式,读者可从TI网站上下载。对于更多点数的处理,可以参照这些模块加以扩展。实际上,由于运算的规范性,需要解决的只是蝶式因子而已,其它只是循环次数参数的修改。
为了减小频谱泄漏,这些模块中增加了数据加窗功能。使用库函数进行谱分析,一个实际C语言程序见光盘中的MinSYS_2407_fft512r_Sim子目录,程序产生一个线性调频实信号,目的是为了得到一个较宽的频带,以便观察。该程序结果如图7.16所示。图中上半部分为线性调频实信号,下半部分左边为DSP基于FFT的谱分析结果,右边为DSP开发系统CC的谱分析结果。可见二者形状类似,数值的差异是因为DSP基于FFT的谱分析未进行定标处理。实信号频谱正(数字频率0~
)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 医院物价管理培训
- 物流行业物流标准化建设方案
- 智能水务管理系统研发合作协议
- 销售手册业务操作与技巧指南
- 食品行业食品包装安全检测与评估方案
- 煤炭行业智能化开采与利用方案
- 服装行业产品质量保证合同
- 体育赛事参与者风险自担及免责协议书
- 休闲娱乐场所管理免责条款
- 2025年河北货运从业资格实操模拟试题
- 2023年副主任医师(副高)-普通外科学(副高)考试高频试题(历年真题)带答案
- 新华人寿保险管理信息系统案例分析
- 中华人民共和国史马工程课件01第一章
- PPT中国地图素材(可修改颜色)
- 2023年深国交入学考试英语模拟试题
- 2022年中国农业银行(广东分行)校园招聘笔试试题及答案解析
- 品牌管理第五章品牌体验课件
- DB63-T 1672-2018+沥青路面整治工程新旧路面联结层技术规范
- 园艺疗法共课件
- 布氏、韦氏、洛氏硬度换算表
- 保姆级别CDH安装运维手册
评论
0/150
提交评论