DSP芯片的开发包括硬件开发和软件开发两个方面,就软件开发而言,用汇编语言编写程序是一件比较繁琐的事情,因为不同类型芯片的汇编语言有所不同,其可读性和可移植性较差且需较长的开发周期,而一旦开发完毕,要再对其修改和升级将非常困难。用C语言开发DSP程序将使其开发速度大大加快,而且可读性和可移植性都大大增加,程序修改也极为方便。但在某些情况下,C代码的效率还是无法与手工编写的汇编代码的效率相比,如FFT程序等,而且一些硬件控制功能也不如汇编语言方便,而且有些操作C语言甚至无法直接实现。因此,在很多情况下,如果使用C语言和汇编语言来进行混合编程,便可达到最佳的效果。
1 TMS320C3x简介
TMS320C3x(以下简称C3x)是TI(Texas Instru-ments)公司生产的第三代DSP产品,也是第一代浮点DSP芯片,该系列包括C30、C31、C32和C33四种产品,是目前TMS320系列中性能价格比较高的一种浮点式DSP芯片。它具有32位的浮点精度,总共有三套总线,即程序总线、数据总线和DMA总线,取指、读写数据以及DMA操作可以并行进行,并可以寻址16M字的空间,是目前国内应用比较广泛的DSP芯片之一。其中C30的简化和改进型C31去掉了扩展总线和一个串口,因而降低了芯片的成本,并且在硬件上增加了一个非常有用的功能,即程序引 导功能(Bootloader),从而使其程序可以从低速E-PROM、PROM或串行口装入到系统的高速RAM中全速运行。C32和C33是C31的进一步简化和改进型产品,其中C32片内RAM减为512字,因此进一步降低了成本。而C33的片内RAM为34K字,采用3.3V电源供电。
2 C和汇编语言的混合编程方法
采用C语言和汇编语言混合编程的具体方法有如下三种:
( 1)独立编写C和汇编程序。
( 2)直接在C程序中嵌入汇编语句。
(3)对C程序进行编译生成相应的汇编程序,然后对其进行手工优化和修改。
2.1 独立的C和汇编模块接口
这是一种较常用的C和汇编语言的接口方法,采用这种方法编程时,首先独立编写C和汇编程序,然后将它们加入到同一个工程文件中,再利用CodeComposer集成开发环境进行编译链接,最后生成可执行代码,利用仿真器将其加载到高速RAM中即可运行。通常,FFT程序一般采用汇编语言编写,而主程序则可采用C语言,这样只需在C程序中定义FFT程序为外部调用即可。采用这种方法必须遵循有关的调用规则和寄存器规则,有了这些规则,C和汇编函数之间的接口就变得很方便。C程序既可以调用汇编程序,也可以访问汇编程序中定义的变量;与此同时,汇
编程序也可以调用C函数程序中定义的变。下是互相访问变量的编程实例。
例1:在C程序访问.bss定义的汇编程序变量:
汇编程序:
2.2 直接在C程序中嵌入汇编语句
在C程序中嵌入汇编语句是一种直接的C和汇编接口方法。采用这种方法一方面可以在C程序中实现用C语言无法实现的一些硬件控制功能,如修改中断控制寄存器、中断使能或屏蔽、读取状态寄存器和中断标志寄存器等;另一方面,也可以用这种方法在C程序中的关键部分用汇编语句代替C语言以优化程序。而采用这种方法的缺点是比较容易破坏C环境,因为C编译器在编译嵌入了汇编语句的C程序时并不检查或分析所嵌入的汇编语句。嵌入汇编语句的方法比较简单,只需在汇编语句的左右加上一个引号,然后用小括弧将汇编语句括住,并在括弧前加上asm标识符即可。
如C31,在C程序中可用下列汇编语句实现一些硬件控制功能:
2.3 修改编译器的输出
可以通过控制编译器的输出来产生具有交叉列表的汇编程序,在Code Composer集成开发环境中,选择View菜单下的Mixed Source/ASM选项即可看到交叉列表的汇编程序。在所生成的语句中,每个C语句的下面就是C编译器对该C语句编译所生成的汇编语句。通过查看交叉列表的汇编程序,可以对某些编译不是很优但却是比较关键的汇编语句进行修改。修改汇编语句时,必须严格遵守不破坏C环境的原则。
3 TMS320C3x中断的C语言实现
3.1 C3x的中断机制
C3x芯片提供有32个中断源,其中片内设置的中断有串行口中断、定时器中断、DMA中断等;同时,TMS320C3x为外围设备提供了四个中断源,分别是INT0、INT1、INT2和INT3。它们的中断允许寄存器(IE)是一个32位寄存器,CPU的中断允许位置为10~0,而DMA中断允许位是在26~16。芯片为每个中断源分配了一个唯一的中断号。设计时将中断源的中断号填入选择寄存器中,即可将该中断源映射到相应的CPU中断。将中断允许寄存器的相应位写1则允许相应的中断,而写0则会禁止相应的中断,复位时寄存器写入0。当C环境初始化时,初始化程序并不对处理器的中断作任何初始化操作,因此,当硬件复位后,系统的中断实际上都没有被使能,即所有的中断都是无效的。若系统需要中断功能,则必须对所需的中断作相应的处理,由于没有专门的C语句对中断使能或屏蔽,因此必须嵌入汇编语句。举例如下:
3.2 中断向量表的设置
中断发生后,DSP将停止当前执行的程序,而转到中断服务向量表以执行相应的中断服务程序。可用汇编指令.sect直接建立中断向量表,并在链接命令文件中将其分配到指定地址。对于C30和工作于微处理器(即MP)工作方式的C31,其中断向量起始地址为0x00,且中断矢量地址的值就是中断服务程序的地址,其中断向量表内容可定义如下:
当工作于微计算机(即MCBL)方式时,它采用双矢量方案来响应中断请求。在这种方案中,需在相应的中断矢量地址存放一跳转指令,而不是直接存放中断服务程序的地址。正常的中断矢量定义在片内RAM块的最后63个地址。当激活引导程序后,还需要在片内RAM1块的最后63个地址存放跳转至相应中断服务程序的跳转指令,其中断向量表的内容如下:
3.3 C语言中断服务程序
C中断程序采用一个特殊的函数名,其格式为c—intnn,其中nn代表00-99之间的两位数,如:c—int01就是一个有效的中断函数名。c—int00是C程序的入口点,它是专为系统复位中断保留的,这个特殊的中断程序用于系统的初始化和调用main()函数。中断服务子程序与其他的函数类似,因为它可以有局部变量和全局变量,但是在说明中断程序时,不能传递参数。下面是一个C30中断程序的例子,其功能为采用中断方式从串行口0输入一个样值,并将这个样值从串行口输出。
需要说明的是:上述程序中的:IO—ADD为I/O口的起始地址。
4结束语
TMS320C3x不仅具有丰富的硬件资源,而且还提供了强大的指令系统,同时也支持高级语言,所以在编程时应充分考虑其硬件结构和指令系统,并合理运用汇编语言和C语言来进行混合编程,以使系统达到最优化。