收藏 分享(赏)

DSP C语言程序设计.pdf

上传人:HR专家 文档编号:6297865 上传时间:2019-04-05 格式:PDF 页数:48 大小:304.75KB
下载 相关 举报
DSP C语言程序设计.pdf_第1页
第1页 / 共48页
DSP C语言程序设计.pdf_第2页
第2页 / 共48页
DSP C语言程序设计.pdf_第3页
第3页 / 共48页
DSP C语言程序设计.pdf_第4页
第4页 / 共48页
DSP C语言程序设计.pdf_第5页
第5页 / 共48页
点击查看更多>>
资源描述

1、第13章 DSP程序设计主要内容:(1)DSP C语言程序设计(2)C语言与汇编语言混合编程(3)DSP程序烧写13.1 DSP C语言程序设计DSP支持使用ANCI C 进行程序设计,并提供了相应的编译器和C优化编译工具,利用这些优化编译工具可以产生可与手工编写相比的汇编语言程序。13.1.1 DSP C语言的特征DSP C语言以ANSI C为基础,并对ANSI C进行了相应的限定和扩展。以下是LF2407 C语言的一些不同于一般标准C的特征:标识符和常量 所有标识符的前100个字符是有效的,区分大小写。 不允许多字节字符。 多字符的字符常数按序列中的最后一个字符来编码。例如: abc =

2、c。数据类型 整型、双精度型等数据类型长度与常见编译器中数据类型不同,所有的浮点型都是由MS320C2x/C2xx/C5x的32位的二进制浮点格式来表示。 size_t(sizeof操作符的结果)定义为unsigned int。 ptrdiff_t(指针加减的结果)定义为int。类型转换 浮点数转换为整型数为向零取整转换。 指针和整型数可以自由转换。表达式 当两个有符号整型数相除,如果两个数中任一个为负数,则商为负数,并且余数的符号与被除数的符号相同。用斜线符号(/)可以得到商,用百分号(%)可以得到余数。例如:10 / -3 = -3; -10 / 3 = -3;10 % -3 = 1; -

3、10 % 3 = -1; 有符号型数的右移是算术移位,符号被保留。声明 寄存器变量(register)声明对short,integer,pointer等所有类型的变量都有效。预处理指令(#pragma) 预处理器会忽略所有不支持的预处理指令。 支持下列预处理指令:CODE_SECTION, DATA_SECTION和FUNC_EXT_CALLED。13.1.2 数据类型所有整数类型(char,short,int以及对应的无符号类型)都是相同的,都是由16位的二进制数来表示。长整型(long)和无符号长整型(unsigned long)都是由32位的二进制数来表示。有符号类型都是由基2的补码来表

4、示。字符型是有符号类型,等同于整型。枚举(enum)类型的对象用16位数来表示;在表达上与整型相似。所有浮点型(float,double和long double)相似,在TMS320C2x/C2xx/C5x中都是用32位浮点格式来表示。long和float类型以低有效字存储在低端的存储地址。注: 在TMS320C2x/C2xx/C5x C语言中,字节长度为16位,sizeof操作符返回的对象长度是以16位为字节长度的字节数。例如sizeof(int) = 1。13.1.3 寄存器变量C编译器 在一个函数中最多只能用两个寄存器变量 ,而且必须在参数表或函数的开始处声明。在嵌套块中的寄存器变量定义

5、被认为是一般的变量。编译器用AR6和AR7作寄存器变量 : AR6被指定为第一个寄存器变量。 AR7被指定为第二个寄存器变量。变量的地址放在指定的寄存器中,访问起来更加容易。16位的字节变量(char,short,int和pointer)可以用作寄存器变量。在运行时,设置每一个寄存器变量需要四条指令。为了有效地利用这种方式,只有在一个变量被多次访问时,才使用寄存器变量。程序优化编译器也会定义寄存器变量,但使用方式不同。编译器会自己决定哪些变量作为寄存器变量,程序中声明的寄存器变量会全部被忽略。13.1.4 asm语句TMS320C2x/C2xx/C5x的 C编译器可以在编译器输出的汇编语言中直

6、接嵌入汇编语言指令 。这种能力是C语言的扩展 asm语句 。asm语句 能够实现一些C无法实现的功能。/*/asm(“ clrc INTM“);/*/对于 嵌入的汇编指令,编译器不会进行语法检查 ,编程者必须确认嵌入的指令合理有效。使用asm指令的时候应小心不要破坏C语言的环境 。如果C代码中插入跳转指令和标识符可能会引起不可预料的操作结果。能够改变块或其它影响汇编环境的指令也可能引起麻烦。对带asm语句的代码使用优化器时要特别小心。 尽管优化器不能删除asm指令,但它可以重新安排asm指令附近的代码顺序,这样就可能会引起不期望的结果。13.1.5 访问I/O空间I/O空间地址声明要在程序中访

7、问io空间地址,必须首先用关键字“ioport”对要访问的地址进行定义。语法:ioport type porthex_numioport 声明io空间端口变量的关键字;type 变量类型,可以为char, short, int或unsigned int;porthex_num 端口号,port后面接16进制数字。/*/ioport unsigned int port10;/*/注: 声明io空间地址必须在C文件起始声明, 不允许在函数中使用ioport声明io空间地址。I/O空间地址访问访问用ioport关键字声明的I/O端口变量和访问一般变量没有区别。/*/ioport unsigned i

8、nt port10; /* 访问I/O端口10h的变量 */int func ().port10 = a; /* 写 a到端口 10h */.b = port10; /* 读取端口10h的值到 b */./*/I/O端口变量的使用不仅仅局限于赋值,和其他变量同样也可以应用于其它的表达式 。/*/call (port10); /* read port 10h and pass to call */a = port10 + b; /* read port 10h, add b, assign to a */port10 += a; /* read port 10h, add a, write to

9、 port 10h */*/程序中访问的任何一个IO地址都必须在C语言程序起始处用ioport关键字声明!13.1.6 访问数据空间访问数据空间不需要对要访问的单元预先声明,访问是通过指针的方法实现的。/*/unsigned int org,cnt,block,offset,tmp,i;org = *(unsigned int *) 0x8000;cnt = *(unsigned int *) 0x8001;block = *(unsigned int *) 0x8002;offset = *(unsigned int *) 0x8003;for (i=0; icnt; i+)tmp = *(

10、unsigned int *) (org + i);*(unsigned int *) (org + offset +i) = tmp;/*/13.1.7 中断处理(1)中断处理方法查询法程序通过查询中断标志位来判断是否有中断发生,并进行相应的处理。优点: 流程易于控制,不会发生中断嵌套的问题,一般也不会发生丢失中断的问题。缺点: 中断实时性差。回调法为中断指定一个回调函数,即中断服务程序。将中断服务程序的入口地址放在中断向量处。优点: 中断实时性好,程序结构简洁,类似于windows操作系统下事件驱动的编程方式。缺点: 处理不好容易造成中断嵌套或丢失中断。(2)回调法处理中断的一般性问题中断

11、服务函数可以和一般函数一样访问全局变量、分配局部变量和调用其它函数等。进入中断服务函数,编译器将自动产生程序保护所有必要的寄存器,并在中断服务函数结束时恢复运行环境。c_int0是保留的复 位中断处理函数,不会被调用,也不需要保护任何寄存器。要将中断服务函数入口地址放在中断向量处以使中断服务函数可以被正确调用。中断服务函数要尽量短小,避免中断嵌套等问题。(3)用C编写中断服务函数有两种方式定义中断服务函数:a)任何具有名为c_int d 的函数( d为0到9的数),都被假定为一个中断程序,c _int0函数留作系统复位中断用。b)利用中断关键词interrupt进行定义。举例如下:/*/voi

12、d c_int1 ()/*/interrupt void isr ()/*/(4)C语言编写中断处理函数注意事项:中断处理函数必须是void类型,而且不能有任何输入参数。进入中断服务程序,编译器只保护与运行上下文相关的寄存器,而不是保护所有的寄存器。中断服务程序可以任意修改不被保护的寄存器,如外设控制寄存器等。要注意IMR、INTM等中断控制量的设置。中断处理函数可以被其他C程序调用,但是效率较差。多个中断可以共用一个中断处理函数,除了c_int0。使用中断处理函数和一些编译选项冲突,注意避免对包含中断处理函数的C程序采用这些编译选项。13.2 C语言与汇编语言混合编程C语言编写DSP程序对底

13、层的了解要 求较低,流程控制灵活,开发周期短。程序可读性、可移植性好,程序修改、升级方便。某些硬件控制功能不如汇编语言灵活 ,程序实时性不理想,很多核心程序可能仍然需要利用汇编语言来实现。13.2.1 C语言与汇编语言混合编程的方式 C语言调用汇编语言编写的函数 使用内嵌汇编语句(asm语句) C语言访问汇编语言变量 手动修改C语言程序编译后生成的汇编代码13.2.2 存储器模式TMS320C2x/C2xx/C5x的C语言编译器将存储器分为两个线性的空间: 程序存储器 存储可执行代码 数据存储器 存储各种变量和堆栈编译器将存储器以分段(section)的方法分配和管理,用户以不同的方式分配存储

14、器,可以形成不同的系统配置。连接器将各个块连接在一起形成最终输出的存储器结构。已初始化的段:.text 包含所有可执行代码和浮点型常量 Page 0.cinit 包含初始化变量和常量表 Page 0.const 包含字符串常量,以及以const修饰的全局或静态变量的声明和初始化 Page 1.switch 包含switch语句的分支跳转地址表 Page 0未初始化的块:.bss 为全局和静态变量保留空间 Page 1.stack 为系统软件堆栈分配空间 Page 1.system 为动态分配的内存保留空间,可以被calloc、malloc、realloc函数使用 Page 113.2.3 系统

15、堆栈系统堆栈分为硬件堆栈和软件堆栈。DSP内部程序控制逻辑部分包含一定大小的堆栈,通常称为硬件堆栈,可以用来保存若干个分支、跳转、函数调用或中断服务程序的返回地址,也可以用来保存其它变量。通过系统配置可以另外生成一定大小的软件堆栈,用来:分配局部变量传递函数参数保存处理器状态保存函数返回地址保存临时结果保存寄存器内容堆栈从低端地址向高端地址生成。编译器利用两个辅助寄存器来管理堆栈: AR1 堆栈指针(SP, stack pointer),指向当前堆栈顶。 AR0 帧指针(FP, frame pointer),指向当前帧的起始点,每一个函数都会在堆栈顶部建立一个新的帧,用来保存局部或临时变量。C

16、语言环境自动操作这两个寄存器。如果编写用到堆栈的汇编语言程序,一定要注意正确使用这两个寄存器。用-stack连接选项可以指定软件堆栈的大小,用C编写DSP程序一定注意保留足够的堆栈空间!注意:编译器不会检查堆栈溢出情况,堆栈溢出会破坏DSP运行环境,导致程序失败。编写DSP程序和配置DSP存储器资源要注意防止堆栈溢出的发生。13.2.4 动态分配内存TMS320C2x/C2xx/C5x C语言可调用malloc、calloc或realloc函数动态申请内存,申请的内存将分配在.system块。动态分配的内存只能通过指针进行访问。将大数组通过这种方式来分配可以节省.bss块的空间。通过连接器的-

17、heap选项可以定义.system块。/*/unsigned int *data;data =(unsigned int *) malloc (100 * sizeof (unsigned int);/*/13.2.5 寄存器规则TMS320C2x/C2xx/C5x运行环境对寄存器的使用有严格的要求,如果编写涉及到寄存器的汇编程序,必须严格遵守这些规则,否则可能造成系统工作异常。寄存器规则规定了编译器如何使用寄存器,和寄存器在函数调用的过程中如何进行保护。寄存器按照保护方式分为两种: 调用保存(save on call),调用其它函数的函数负责保存这些寄存器的内容。 入口保存(save on entry),被调用的函数负责保存这些寄存器的内容。注:无论是否使用优化编译,都必须遵守这些寄存器规则。寄存器的使用和保护Yes寄存器变量AR6-AR7No局部变量指针( LVP)AR2Yes帧指针( FP)AR0No表达式运算返回值AccumulatorNo表达式运算AR3-AR5Yes堆栈指针( SP)AR1调用时保护用途寄存器

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报