1、DSP原理及应用,武汉大学电子信息学院 肖进胜二零一一年陆月,目录,第1章 绪论 第2章 TMS320C54x数字信号处理器硬件结构 第3章 TMS320C54x的数据寻址方式 第4章 TMS320C54x汇编指令系统 第5章 TMS320C54x软件开发 第6章 CCS集成开发环境 第7章 汇编语言程序设计 第8章 TMS320C54x片内外设及应用实例,第1章 绪论,DSP定义:利用数字计算机或专用数字硬件,对数字信号进行的一切处理运算称为数字信号处理。 DSP芯片:解决实时处理要求,适合DSP运算需求的单片可编程微处理器芯片。,图1-1 典型的数字信号处理系统,(1)在微机上用软件实现。
2、MATLAB, 教学研究仿真,速度慢,不实时。 (2)用特殊DSP芯片实现。FFT,FIR芯片,速度快,不灵活。 (3)用FPGA/CPLD实现。可以进行简单编程 (4)用通用DSP芯片实现。可以C,汇编编程,速度快,灵活。 相对普通芯片的改进:采用了改进的哈佛结构、硬件乘法器、流水线结构、并行性,专用的数字信号处理指令等。,与模拟系统(ASP)相比,数字系统有如下特点: 精度高,可靠性高 ,灵活性大,易于大规模集成 ,可获得高性能指标,局限性,DSP芯片可以按照以下3种方式进行分类。 1按基础特性分:静态DSP, 一致性dsp 2按数据格式分 定点:TMS320C2000/C5000/C64
3、x,ADSP21xx 浮点:TMS320C67x,ADSP21xxx 3按用途分:通用,专用,DSP芯片的主要特点,1哈佛结构: 将程序和数据存储在不同的存储空间中,独立编址,独立访问,独立总线。 冯.诺伊曼结构程序和数据共用总线和存储空间。 2多总线结构 多总线可以在一个机器周期内多次访问程序空间和数据空间。 3指令系统的流水线操作 处理器可以并行处理多条指令,4专用的硬件乘法器 通用处理器:乘法是由加法和位移,软件实现,多周期 DSP处理器:专用的硬件乘法器,一个周期内 5特殊的DSP指令 其他用于数字信号处理指令 6快速的指令周期 TMS320C5402 100MIPS 7硬件配置强 T
4、MS320C5000:串行口、主机接口(HPI),DMA控制器,。还有的可以工作在省电模式下,第2章 TMS320C54x数字信号处理器硬件结构,2.1 TMS320C54x的特点和硬件组成框图 2.2 TMS320C54x的总线结构 2.3 TMS320C54x的存储器分配 2.4 中央处理单元(CPU) 2.5 TMS320C54x片内外设简介 2.6 硬件复位操作 2.7 TMS320VC5402引脚及说明,2.2 TMS320C54x的总线结构,TMS320C54x DSP采用先进的哈佛结构并具有八组总线 其独立的程序总线和数据总线允许同时读取指令和操作数,实现高度的并行操作。,返回首
5、页,程序总线(PB)传送从程序存储器来的指令代码和立即数 3组数据总线(CB、DB和EB)连接各种元器件,如CPU、数据地址产生逻辑、程序地址产生逻辑、片内外设和数据存储器。 CB和DB总线传送从数据存储器读出的操作数,EB总线传送写入到存储器中的数据。 4组地址总线(PAB、CAB、DAB、EAB)传送执行指令所需的地址。,2.3 TMS320C54x的存储器分配,TMS320C54x存储器由3个独立的可选择空间组成:程序空间、数据空间和I/O空间。,程序存储器空间包括程序指令和程序中所需的常数表格;,数据存储器空间用于存储需要程序处理的数据或程序处理后的结果;,I/O空间用于与外部存储器映
6、象的外设接口,也可以用于扩展外部数据存储空间。,TMS320C54x芯片包括:RAM(随机访问存储器)和ROM(只读存储器) RAM分为:DARAM(双访问RAM)和SARAM(单访问RAM)。,RAM一般映像在数据存储器空间(OVLY=0),也可以在程序存储器空间(OVLY=1)。 ROM则映像在程序存储器空间(MP/MC=0),也可以部分映像到数据存储器空间(MP/MC=1)。,处理器工作方式状态寄存器(PMST)中的3个状态位与片内存储器的关系: MP/MC位 若MP/MC=0,则ROM可映象到程序空间 若MP/MC=1, 则ROM不映象到程序空间 OVLY位 若OVLY=0, 则片内R
7、AM只映象到数据存储空间 若OVLY=1, 则片内RAM映象到程序和数据空间 DROM位 当DROM=1,则部分片内ROM映象到数据空间 当DROM=0,则片内ROM映象与MP/MC的有关,除程序存储器空间和数据存储器空间外,C54x系列器件还提供了I/O存储器空间,利用I/O空间可以扩展外部存储器。I/O存储器空间为64K字(0000hFFFFh),有两条指令PORTR和PORTW可以对I/O存储器空间操作,读写时序与程序存储器空间和数据存储器空间有很大不同。,使用片内存储器没有等待状态,速度快; 使用片外存储器可以对更大的存储空间寻址,但是速度较慢。,2.4 中央处理单元(CPU),CPU
8、的基本组成如下: CPU状态和控制寄存器 40位算术逻辑单元(ALU) 40位累加器A和B 桶形移位寄存器 乘法器/加法器单元 比较、选择和存储单元(CSSU) 指数编码器,返回首页,2.5 TMS320C54x片内外设简介,1通用I/O引脚 2定时器 3时钟发生器 4主机接口(HPI) 5串行口 6软件可编程等待状态发生器 7可编程分区转换逻辑,返回首页,第3章 TMS320C54x的数据寻址方式,3.1 立即寻址 3.2 绝对寻址 3.3 累加器寻址 3.4 直接寻址 3.5 间接寻址 3.6 存储器映象寄存器寻址 3.7 堆栈寻址,表3-1 寻址指令中用到的缩写符号及其含义,3.1 立即
9、寻址,指令中包括了立即操作数(立即数)。 立即数:短立即数:3、5、8或9位(一个字长) 长立即数:16位。(指令编码为两个字长)。 在数字或符号常数前加 “”号,表示立即数。 用于初始化 LD # 80h, A ;80 LD # 32767,B ;32767 LD # 23,DP ;23 DP LD # 15,ASM ;15 ASM LD # 3,ARP ;3 ARP,返回首页,3.2 绝对寻址,指令中给出所要寻址的存储单元的16位地址 存储单元的16位地址,地址标号指令长度至少2个字3.2.1 数据存储器(dmad)寻址 3.2.2 程序存储器(pmad)寻址 3.2.3 端口地址(PA)
10、寻址 3.2.4 长立即数*(lk)寻址,返回首页,3.3 累加器寻址,累加器寻址是用累加器中的数值作为一个地址读写程序存储器。共有两条指令可以采用累加器寻址:READA Smem ;以累加器A中的数为地址,从程序存储器中读入一个数,并传到Smem所指定的数据存储单元中。WRITA Smem ;或反过来。,返回首页,3.4 直接寻址,在直接寻址方式中,指令中包含数据存储器地址(dma)的低7位,这7位dma作为地址偏移量,结合基地址(由数据页指针DP或堆栈指针SP给出)共同形成16位的数据存储器地址。 使用这种寻址方式,用户可在不改变DP或SP的情况下,对一页内的128个存储单元随机寻址。 采
11、用这种寻址方式的好处是指令为单字指令,数据存储器地址(dma)的低7位放在指令字中。,返回首页,直接寻址 例1,CPL0:DP(高9位)与Smem的低7位合并16位地址,0000 0001 1 111 1111 = 0x01FF ;DP=3 0000 0001 1 000 0000 = 0x0180 ;DP=3,3.5 间接寻址,3.5.1 单操作数寻址 3.5.2 双操作数寻址,返回首页,1 循环寻址,循环缓冲区滑窗 应用:卷积、相关、FIR滤波、取SIN和COS值等保存最新一批数据或周期性取数 特点: 1. 循环缓冲区首尾相连 2. 地址增量值可变,可正可负 优点:滑窗数据不需移位(每次输
12、入新数据至存放最老数据的单元中),1 循环寻址,循环缓冲区的长度值存放在BK (循环缓冲区长度)寄存器中。长度为R的缓冲区必须从N位地址的边界开始(即循环缓冲区基地址的N个最低有效位必须为0),N是满足2NR的最小的整数。长度R=31的循环缓冲区须从地址XXXX XXXX XXX0 0000,(N=5,2531,该地址的最低5位为0)开始,同时须将R值加载到BK寄存器中。BK中的数值由指令STM lk,BK设定。在循环寻址时,首先要指定一个辅助寄存器ARx指向循环缓冲区,根据ARx的低N位作为循环缓冲区的偏移量进行所规定的寻址操作。寻址操作完成后,再根据以下循环寻址算法修证这个偏移量,并返回A
13、Rx的低N位:if 0 index + step BK;index = index + stepelse if index + stepBK;index = index + step - BKelse if index + step 0index = index + step + BK,返回本节,2 位码倒序寻址实现方法,用途:将基-2 FFT乱序的结果整序 用法举例(对于16点FFT): 设定(AR2)0060 存放16个数据的基地址(AR0)0008 N/2=8 实现程序 RPT #15PORTW *AR2+0B,PA0,3.5.2 双操作数寻址,双数据存储器操作数间接寻址类型为*ARx、
14、*ARx-、*ARx+、*ARx+0%。 所用辅助寄存器只能是AR2、AR3、AR4、AR5。 其特点是:占用程序空间小,运行速度快,在一个机器周期内通过两个16位数据总线(C和D)读两个操作数。 指令中Xmem表示从DB总线上读出的16位操作数,Ymem表示从CB总线上读出的16位操作数。,3.6 存储器映象寄存器寻址,存储器映象寄存器寻址用于修改存储器映象寄存器(MMR)中的内容,不影响当前数据页指针DP和当前堆栈指针SP。 由于这种方式不需要修改DP和SP,对寄存器的写操作开销最小。,返回首页,存储器映象寻址指令: LDM MMR, dst MVDM dmad, MMR MVMD MMR
15、, dmad MVMM MMRx, MMRy POPM MMR PSHM MMR STLM src, MMR STM #lk, MMR,3.7 堆栈寻址,当发生中断或子程序调用时,系统堆栈自动保存PC值。堆栈也可以用于保存和传递其他数据。 堆栈由高地址向低地址增长,处理器使用16位的存储器映象寄存器堆栈指针(SP)对堆栈进行寻址,SP总是指向压入堆栈的最后一个数据。,返回首页,有4条使用堆栈寻址的指令: PSHD 把一个数据存储器数据压入堆栈; PSHM 把一个存储器映象寄存器中的值压入堆栈; POPD 从堆栈中弹出一个数据至数据存储器单元; POPM 从堆栈中弹出一个数据至存储器映象寄存器。
16、,第4章 TMS320C54x汇编指令系统,4.1 符号和缩写 4.2 指令系统,指令的表示方法,TMS320C54x 指令形式: (1) 助记符形式指令(本部分重点介绍) (2) 代数形式指令指令的表示方法LD 0FF,A (助记符操作码) (操作数),返回首页,1 指令系统中的符号和缩写,1 指令系统中的符号和缩写(2),4.2 指令系统,4.2.1 算术运算指令 4.2.2 逻辑运算指令 4.2.3 程序控制指令 4.2.4 加载和存储指令,返回首页,C54x 指令系统的主要特点,(1) 可同时读入2或3个操作数; (2) 支持双精度运算(32位长操作数指令); (3) 单条指令重复和块
17、指令重复操作; (4) 块存储器传送指令; (5) 并行操作(并行存储和加载,并行存储和加/减法, 并行存储和乘法)指令; (6) 条件存储指令; (7) 延迟操作指令; (8) 从中断快速返回指令; (9) 特殊用途指令(支持FIR滤波器、最小均方算法、多项式计算以及浮点运算); (10)空转(省电方式)指令。,C54x的算术运算指令包括加法指令、减法指令、乘法指令、乘累加指令与乘法减法指令、双字/双精度运算指令及专用指令。,逻辑指令包括与、或、异或(按位)、移位和测试指令。,程序控制指令包括分支转移指令、子程序调用指令、中断指令、返回指令、重复指令、堆栈操作指令及混合程序控制指令。,加载和
18、存储指令包括加载指令、存储指令、条件存储指令、并行加载和存储指令、并行加载和乘法指令、并行存储和加/减法指令、混合加载和存储指令。 加载指令是将存储器内容或立即数赋给目的寄存器;存储指令是把源操作数或立即数存入存储器或寄存器。,第5章 TMS320C54x软件开发,5.1 软件开发过程及开发工具 5.2 公共目标文件格式 5.3 常用汇编伪指令 5.4 链接器命令文件的编写与使用 5.5 汇编语言程序编写方法 5.6 TMS320C54x C语言编程 5.7 用C语言和汇编语言混合编程,开发过程说明,1建立源程序 用C语言或汇编语言写源程序,*.c,*.asm 2C编译器(C Compiler
19、) 将C语言源程序自动编译为TMS320C54x的汇编语言 3汇编器(Assembler) 将汇编语言源程序汇编成机器语言的目标文件, *.obj 格式为COFF,开发过程说明,4连接器(Linker) 将目标文件连接在一起,产生可执行文件, *.out 输入COFF文件,*.cmd,库文件和部分连接好的文件 输出可执行COFF目标模块 a. 归档器(Archiver) 将一组文件归入一个库。 b. 交叉引用列表(Cross-Reference Lister) 查错。,开发过程说明,5调试工具 a.软件仿真(Simulator),PC机软件模拟窗口模拟调试 b.硬件在线仿真(XDS Emula
20、tor)开发系统仿真器(XDS510)进行系统级仿真 c.评估模块(EVM板)开发板进行系统性能评估测试,开发过程说明,6十六进制转换公用程序(Hex Conversion Utility) a. 将COFF文件(*.out)转化为标准的ASCII码二进制文件格式,可以写入EPROM或FLASH等外部存储器。片外断电不会丢失 b. 上电后通过DSP自举引导程序(BOOTLOADER),将程序搬移到速度较快的DSP的RAM中运行,5.2 公共目标文件格式,5.2.1 COFF文件的基本单元段 5.2.2 汇编器对段的处理 5.2.3 链接器对段的处理 5.2.4 重新定位 5.2.5 程序装入
21、5.2.6 COFF文件中的符号,返回首页,5.2.1 COFF文件的基本单元段,段(sections)是COFF文件中最重要的概念。每个目标文件都分成若干个段。一个段就是最终在存储器映象中占据连续空间的一个数据或代码块。目标文件中的每一个段都是相互独立的。 一般地,COFF目标文件包含3个缺省的段:text (此段常包含可执行代码data (此段常包含初始化数据bss (此段常为未初始化变量保留存储空间),5.2.2 汇编器对段的处理,1未初始化段 未初始化段主要用来在存储器中保留空间,通常将它们定位到RAM中。这些段在目标文件中没有实际内容,只是保留空间而已。程序可以在运行时利用这些空间建
22、立和存储变量。 未初始化段是通过使用.bss和.usect汇编伪指令建立的,两条伪指令的句法分别为:.bss 符号,字数符号 .usect “段名”,字数,2已初始化段 已初始化段包含可执行代码或已初始化数据。这些段的内容存储在目标文件中,加载程序时再放到TMS320C54X存储器中。 三个用于建立初始化段的伪指令句法分别为:.text 段起点.data 段起点.sect “段名”,段起点,其中, 段起点是任选项。如果选用,它就是为段程序计数器(SPC)定义的一个起始值。,3命名段 命名段就是程序员自己定义的段,它与缺省的.text、.data和.bss段一样使用,但与缺省段分开汇编。 将初始
23、化数据汇编到与 .data段不同的存储器中, 将未初始化的变量汇编到与 .bss段不同的存储器中。 产生命名段的伪指令为:符号 .usect “段名”,字数.sect “段名”,段起点,5.2.3 链接器对段的处理,链接器对段的处理有两个功能。 首先,它将汇编器产生的COFF目标文件(.obj文件)中的各种段作为输入段,当有多个文件进行链接时,它将输入段组合起来,在可执行的COFF输出模块中建立各个输出段。 其次,链接器为输出段选择存储器地址。,链接器有两个命令完成上述功能,即: MEMORY 命令定义目标系统的存储器配置图,包括对存储器各部分的命名,以及规定它们的起始地址和长度。 SECTI
24、ONS命令告诉链接器如何将输入段组合成输出段,以及在存储器何处存放输出段。子段可以用来更精确地编排段,可用链接器SECTIONS命令指定子段。,5.2.5 程序装入,(1)硬件仿真器和CCS集成开发环境,具有内部的装入器,调用装入器的LOAD命令即可装入可执行程序。 (2)将代码固化在片外存储器中,采用Hex转换工具(Hex conversion utility),例如Hex500将可执行的COFF目标模块(.out文件)转换成几种其他目标格式文件,然后将转换后的文件用编程器将代码写入EPROM/Flash。,返回本节,5.2.6 COFF文件中的符号,COFF文件中有一个符号表,用于存储程序
25、中的符号信息。链接器对符号重定位时使用该表,调试工具也使用该表来提供符号调试。 外部符号指在一个模块中定义,在另一个模块中使用的符号。 可使用.def、.ref或.global汇编伪指令将符号定义为外部符号。 .def在当前模块中定义,可以在别的模块中使用的符号; .ref在当前模块中引用,但在别的模块中定义的符号; .global可用于以上任何一种情况。,例5-3 以下代码说明符号的定义x: ADD #56h , A ;B y ;.def x ;.ref y ;,返回本节,.def在当前模块中定义,可以在别的模块中使用的符号; .ref在当前模块中引用,但在别的模块中定义的符号; .glob
26、al可用于以上任何一种情况。,5.3 常用汇编伪指令,返回首页,伪指令(Directives)不生成最终代码,但对汇编器、链接器有重要指示作用, 包括:段定义,条件汇编,文件引用,宏定义等。,表5-2 常用的汇编伪指令1,表5-2 常用的汇编伪指令2,5.4 链接器命令文件的编写与使用,5.4.1 MEMORY伪指令及其使用 5.4.2 SECTIONS伪指令及其使用,返回首页,a.obj b.obj /*Input filename*/ -o prog.out /*Option */ -m prog.map /*Option */ MEMORY /*MEMORY directive*/ RA
27、M : org=0100h, length=0100hROM : org=1000h, length=0100h SECTIONS .text : ROM.data : ROM.bss : RAM ,链接器命令文件 举例,5.4.1 MEMORY伪指令及其使用,MEMORY伪指令就是用来指定目标存储器的模型。定义存储器的形式、起始地址、容量 MEMORY伪指令的一般语法为:MEMORY PAGE 0:name 1(attr):origin=constant, length=constant;PAGE 1:name n(attr):origin=constant, length=constant
28、; ,返回本节,MEMORY PAGE 0:name 1(attr):origin=constant, length=constant;PAGE 1:name n(attr):origin=constant, length=constant; ,返回本节,PAGE:指定存储器空间页面,255个。 name: 存储器区间的取名,64字符。 attr: 指定存储区的属性,R,W,X,I origin: 指定存储区的起始地址 length: 指定存储区的长度 fill: 指定存储区的填充,5.4.2 SECTIONS伪指令及其使用,SECTIONS伪指令功能如下:说明如何将输入段组合成输出段。 在可
29、执行程序中定义输出段。 指定输出段在存储器中存放的位置。 允许对输出段重新命名。,SECTIONSname : property ,property ,property .name : property ,property ,property .name : property ,property ,property .,SECTION命令的一般句法,MEMORY和SECTION命令的缺省定义,MEMORY PAGE 0:PROG: origin=0x0080,length=0xFF00 PAGE 1:DATA: origin=0x0080,length=0xFF80 SECTIONS .tex
30、t: PAGE=0 .data: PAGE=0 .cinit: PAGE=0 ;cflag option only .bss : PAGE=1 ,链接命令文件fir.cmd如下: fir.obj -m fir.map -o fir.out MEMORY PAGE 0:ROM1(RIX):ORIGIN=0080H,LENGTH=100HPAGE 1:RAM1(RW) :ORIGIN=2400H,LENGTH=0200HRAM2(RW) :ORIGIN=2600H,LENGTH=0100HRAM3(RW) :ORIGIN=2700H,LENGTH=0100HB2B(RW) :ORIGIN=0070
31、H,LENGTH=10H ,SECTIONS .text : ROM1 PAGE 0 .data : RAM1 PAGE 1FIR_COEF : RAM2 PAGE 1FIR_BFR : RAM3 PAGE 1.stack : B2B PAGE 1 ,5.5 汇编语言程序编写方法,5.5.1 汇编语言源程序格式 5.5.2 汇编语言中的常数和字符串 5.5.3 汇编源程序中的符号 5.5.4 汇编源程序中的表达式,返回首页,5.5.3 汇编源程序中的符号,1标号 2局部标号 3符号常数 4先定义的符号常数 5替代符号,返回本节,5.6 TMS320C54x C语言编程,5.6.1 存储器模式
32、5.6.2 寄存器规则 5.6.3 函数调用规则 5.6.4 中断处理 5.6.5 表达式分析,返回首页,汇编语言设计难度大,不易于移植 C语言具有不依赖或少依赖硬件,兼容性和可移植 C语言可以缩短开发和升级的周期 C语言使修改和移植变得方便 C5000支持的C语言与标准C语言无本质差别,5.6.1 存储器模式,1段 C54x将存储器处理为程序存储器和数据存储器两个线性块。 程序存储器包含可执行代码;数据存储器主要包含外部变量、静态变量和系统堆栈。 编译器的任务是产生可重定位的代码,允许链接器将代码和数据定位进合适的存储空间。 C编译器对C语言编译后除了生成3个基本段,即.text、.data
33、、.bss外, 还生成.cinit、.const、.stack、.sysmem段。,返回本节,初始化段有: .text、.data:段包括可执行代码、字符串和编译器产生的常数。 .cinit:初始化变量和常数表。 .const:字符串和以const关键字定义的常量。 .switch:包含switch语句表。 未初使化段有: .bss:为全局变量和静态变量保留空间,程序启动后,C初始化引导程序将数据从.cinit段复制到.bss段。 .stack:为C的系统堆栈分配存储空间,变量传递及分配局部变量 .sysmem:动态分配存储器分配保留空间,malloc,calloc,realloc。,2C/C
34、+系统堆栈,.stack不同于DSP汇编指令定义的堆栈。DSP汇编程序中要将堆栈指针SP指向一块RAM,用于保存中断、调用时的返回地址,存放PUSH指令的压栈内容。 .stack定义的系统堆栈实现的功能是保护函数的返回地址,分配局部变量,在调用函数时用于传递参数,保护临时结果。 .stack定义的段大小(堆栈大小)可用链接器选项-stack size设定,链接器产生一个全局符号_STACK_SIZE, 并赋给它等于堆栈长度的值,以字为单位,缺省值为1K。,3存储器分配,(1)运行时间支持函数。 I/O,动态存储器分配,串操作等, rts.lib,rts.src 包含了标准运行时间支持库和源码
35、(2)动态存储器分配。 Malloc,calloc,realloc。为全局pool或heap分配的存储器空间定义在.sysmem段,在链接器命令中用-heap size 选项设置.sysmem段的长度。链接器还产生一个全局符号_SYSMEM_SIZE,并赋给他等于堆(heap)长度的值,以字为单位,缺省值为1K struct big *table; table = (struct big *)malloc(100*sizeof(struct big);struct big table100;,(3)静态和全局变量的存储器分配。在C程序中定义的外部变量或静态变量被分配一个唯一的连续空间,空间地址
36、由链接器确定。编译器保证这些变量的分配,按字边界对其。 (4)位域/结构的对准。编译器为结构分配空间,所有的非位域类型成员对准字的边界。位域按所需分配,不能跨两个字。,返回本节,5.6.2 寄存器规则,寄存器规则明确了编译器如何使用寄存器以及在函数调用过程中如何保护寄存器。 (1)辅助寄存器:AR1、AR6、AR7由被调用函数保护AR0、AR2、AR3 、AR4、AR5由调用函数保护 (2)堆栈指针SP:函数调用时自动保护 (3)ARP:在函数进入和返回时为0,运行时为其他值 (4)在默认情况下,编译器总是假定ST1中的OVM在硬件复位时被清0。若在汇编代码中对OVM置位为1,返回到C环境时必
37、须复位。 (5)寄存器变量 :对两个寄存器关键字声明的变量分配AR1,AR6。全局变量。,返回本节,5.6.3 函数调用规则,(1)局部帧的产生 函数被调用时,编译器在堆栈中建立一个帧存储信息,当前的函数帧为局部帧。每调用一次函数产生一个。 (2)参数传递 调用者将第一个参数放进累加器A,将剩下的参数以逆序压入堆栈。浮点数或长整型先低后高,结构体传递地址。 (3)函数的返回 函数返回一个值,则放入累加器A。返回一个结构体,则把内容放到A所指的存储空间。没有返回值,则A置为0。,返回本节,5.6.4 中断处理,(1)中断的使能和屏蔽必须由程序员自己来设置。 (2)中断程序没有参数传递,即使说明,
38、也会被忽略 (3)中断处理程序不能被正常的C程序调用。 (4)为了使中断程序与中断一致,在相应的中断矢量中必须放置一条转移指令,可以用.sect汇编伪指令建立一个简单的跳转指令表来完成此项功能。,(5)在汇编语言中,注意在符号名前面加上一个下划线,例如c_int00记为_ c_int00。 (6)中断程序使用的所有寄存器,包括状态寄存器和程序中调用函数使用的寄存器都必须予以保护。 (7)TMS320C54x C编译器将C语言进行了扩展,中断可以利用interrupt关键字由C/C+函数直接处理。 interrupt void isr() ,返回本节,5.6.5 表达式分析,当C程序中需要计算整
39、型表达式时,必须注意以下几点: (1)算术上溢和下溢。 C54x用16位或32位数据操作都会产生40位结果,不能预测溢出。 (2)整除和取模。 C54x没有整除指令,需要调用运行时间支持函数库rts.lib。表达右操作数传给堆栈,左操作数给A,结果返回A,(3)C代码对16位乘法结果高16位的访问。 用以下方法访问16位乘法结果高16位。 a. 有符号结果 int m1,m2; int result; result = (long)m1*(long)m2)16; b. 无符号结果 unsigned int m1,m2; unsigned int result; result = (unsign
40、ed long)m1*(unsigned long)m2)16;,C54x C编译器将浮点数表示位IEEE单精度格式。单、双精度都表示为32位,没区别。 运行时间支持函数库提供了浮点运算的函数库,包括加法、减法、乘法、除法、比较、整数和浮点数的转换及标准错误处理。,返回本节,5.7 用C语言和汇编语言混合编程,5.7.1 独立的C模块和汇编模块接口 5.7.2 从C程序中访问汇编程序变量 5.7.3 在C程序中直接嵌入汇编语句,返回首页,C代码的效率无法与手工写的汇编代码的效率相比 C代码无法在所有情况下最佳地利用DSP芯片提供的资源 C语言写的中断程序要保护寄存器,效率低 C语言对DSP芯片
41、的某些硬件控制不如汇编方便 C语言和汇编语言的混合编程主要有3种 (1)独立编写C程序和汇编程序。 (2)直接在C程序的相应位置嵌入汇编语句。 (3)对C程序进行编译,生成汇编程序,然后对汇编程序手工优化和修改。,在编写独立的汇编程序时,必须注意以下几点: (1)不论是用C语言编写的函数还是用汇编语言编写的函数,都必须遵循寄存器使用规则。 (2)必须保护函数要用到的几个特定寄存器。 AR1、AR6、AR7和SP (3)中断程序必须保护所有用到的寄存器。 (4)从汇编程序调用C函数时,第一个参数(最左边)必须放入累加器A中,剩下的参数按自右向左的顺序压入堆栈。,(5)调用C函数时,注意C函数只保
42、护了几个特定的寄存器,而其他是可以自由使用的。 (6)长整型和浮点数在存储器中存放的顺序是低位字在高地址,高位字在低地址。 (7)如果函数有返回值,返回值存放在累加器A中。 (8)汇编语言模块不能改变由C模块产生的.cinit段,如果改变其内容将会引起不可预测的后果。,(9)编译器在所有标识符(函数名、变量名等)前加下划线“_”。 如C程序中定义x,汇编中为_x (10)任何在汇编程序中定义的对象或函数,如果需要在C程序中访问或调用,则必须用汇编指令.global定义。 (11)编辑模式CPL指示采用何种指针寻址,如果CPL=1,则采用堆栈指针SP寻址;如果CPL=0,则选择页指针DP进行寻址
43、。 LD *(_global_var), A ;当CPL=1 汇编程序将C中定义的全局变量的值放进累加器,5.7.2 从C程序中访问汇编程序变量,从C程序中访问在汇编程序中定义的变量或常数,可以分为以下3种情况: (1)访问在.bss块中定义的变量 采用 .bss 命令定义变量。 采用 .global 命令定义为外部变量。 在变量名前加一下划线 “_” . 在C程序中将变量声明为外部变量,返回本节,(2)对于访问不在.bss块中定义的变量 必须定义一个指向该变量的指针,在C程序中间接访问这个变量。 在汇编中定义常数表时,可以为这个表定义一个独立的块,定义完后,说明指向该表起始地址的全局标号。在
44、C程序访问该表时,必须另外声明一个指向该表的指针,(3)对于在汇编程序中用.set和.global伪指令定义的全局常数,也可以使用特殊的操作从C程序中访问它们。 一般在C程序或汇编程序中定义的变量,符号表实际上包含的是变量值的地址,而非变量值本身。 在汇编中定义的常数,符号包含的是常数的值。 在C中访问汇编中常数要加一个地址符“&”,5.7.3 在C程序中直接嵌入汇编语句,在C程序中嵌入汇编语句是一种直接的C模块和汇编模块接口方法。采用这种方法一方面可以在C程序中实现用C语言难以实现的一些硬件控制功能。另一方面,也可以用这种方法在C程序中的关键部分用汇编语句代替C语句以优化程序。 采用这种方法
45、的一个缺点是它比较容易破坏C环境,因为C编译器在编译嵌入了汇编语句的C程序时并不检查或分析所嵌入的汇编语句。,返回本节,第6章 CCS集成开发环境,6.1 CCS系统安装与设置 6.2 CCS菜单和工具栏 6.3 CCS中的编译器、汇编器和链接器选项设置 6.4 用CCS开发简单的程序 6.5 在CCS中读取数据和数据的图形显示 6.6 代码执行时间分析(Profiler的使用),6.1 CCS系统安装与设置,6.1.1 CCS系统安装 6.1.2 为CCS安装设备驱动程序,返回首页,4Project菜单,表6-4 Project菜单,5Debug菜单,表6-5 Debug菜单,6Profil
46、er菜单,表6-6 Profiler菜单,6.3 CCS中的编译器、汇编器和链接器选项设置,6.3.1 编译器、汇编器选项 6.3.2 链接器选项,返回首页,6.3.1 编译器、汇编器选项,编译器(Compiler)包括分析器、优化器和代码产生器,它接收C/C+源代码并产生TMS320C54x汇编语言源代码。 汇编器(Assembler)的作用就是将汇编语言源程序转换成机器语言目标文件,这些目标文件都是公共目标文件格式(COFF)。如图6-13、表6-9所示。,6.3.2 链接器选项,在汇编程序生成代码中,链接器的作用如下: (1)根据链接命令文件(.cmd文件)将一个或多个COFF目文件链接
47、起来,生成存储器映象文件(.map)和可执行的输出文件(.out文件)。 (2)将段定位于实际系统的存储器中,给段、符号指定实际地址。 (3)解决输入文件之间未定义的外部符号引用(如图6-14、表6-10所示)。,6.4 用CCS开发简单的程序,1创建新的工程文件 工程文件中包含着设计中所有的源代码文件、链接器命令文件、库函数、头文件等。 (1)在CCS的安装目录的myprojects子目录下创建一个volume1目录。 (2)启动CCS,在Project菜单中选择New项,在Project中输入volume1,CCS将创建一个名为volume1.pjt的工程。,返回首页,2.将文件添加到工程
48、中 (1)将文件添加到工程中 (2)察看工程的结构(如图6-15所示)。 (3)查看代码,图6-15 工程视窗,3生成和运行程序 (1)选择菜单命令ProjectRebuild All,对工程重新编译、汇编和链接,主窗口下方的信息窗口将显示build进行汇编、编译和链接的相关信息。 (2)选择菜单命令FileLoad Program,在当前目录的Debug目录下选择volume1.out并打开,将Build生成的程序加载到DSP中。 (3)选择菜单命令DebugRun或在Debug工具栏上单击Run按钮,运行该程序。,4改变Build选项并修改程序语法错误 选择菜单命令ProjectBuild
49、 Options,弹出Build Options窗口,选择Compiler标签,在类(Category)列表中选择预处理(Preprocessor),如图6-16所示。在Define Symbols域中键入FILEIO,定义符号FILEIO。此时,在命令输入和显示窗口看到-d“FILEIO”。,5断点和观察窗口的应用 (1)选择菜单命令FileReload Program,重新加载程序(即加载volum1.out)。 (2)在工程视图中双击volume.c,打开源文件编辑窗口,将光标放在dataIO()行上,并按F9键或工具栏中的设置断点。 (3)选择菜单命令ViewWatch Window,弹出Watch窗口(如下图)。,