不同系列的嵌入式系统的C编译器,根据它所对应的不同芯片系列有其各自的特点,在这里,以KEIL公司的针对51系列的KEILC51编译器为例,简要说明它与ANSI-C的主要区别,其它的编译系统与ANSI-C的差别,可具体参照指定编译系统手册,找出它们的不同之处。清楚嵌入式系统的C编译器与标准 ANSI-C的区别是用C编译器系统进行嵌入式系统开发的前提条件。
不同的嵌入式C编译系 统之所以与ANSI-C有所不同,主要是由于它们所针对的硬件系统有其各自不同的硬件特点,对国内开发人员熟悉的51系列单片机,有着最为丰富的编译系 统,其中最为出色的当属KEIL(也就是大家熟知的FRANKLING,但FRANKLING只相当于KEIL的早期产品,它是KEIL公司在美国销售时 曾使用的一个品牌)。
从头文件来说,51系列有不同的厂家,不同的系列产品,如仅 ATMEL公司就有大家熟悉的89c2051、89c51、89c52以及大家不熟悉的89s8252等系列产品。它们都是基于51系列的芯片,唯一不同 之处在于内部资源如定时器、中断、I/O等数量以及功能的不同,为了实现这些功能,只需将相应的功能寄存器的头文件加载在程序中就可实现它们所指定的不同功能。因此,KEILC51系列头文件集中体现了各系列芯片的不同功能。
从数据类型来说,由于8051系列器件包含位操作空间和丰富的位操作指令,直接嵌入式C与ANSI-C相比,比ANSI-C多一种位类型,使得它能如同汇编一样,灵活的进行位指令操作。
从 数据存储类型来说,8051系列有片内、片外程序存储器,片内、片外数据存储器,片内程序存储器还分直接寻址区和间接寻址类型,分别对应code、 data、xdata、idata以及根据51系列特点而设定的pdata类型,使用不同的存储器,将使程序执行效率不同,在编写C51程序时,最好指定 变量的存储类型,这样将有利于提高程序执行效率(此问题将在后面专门讲述)。与ANSI-C稍有不同,它只分SAMLL、COMPACT、LARGE模 式,各种不同的模式对应不同的实际硬件系统,也将有不同的编译结果。
从数据运算操作和程序 控制语句以及函数的使用上来讲,它们几乎没有什么明显的不同,只是在函数的使用上,由于嵌入式系统的资源有限,它的编译系统不允许太多的程序嵌套,C语言的丰富的库函数对程序开发提供了很大的帮助,但它的库函数和ANSI-C也有一些不同之处,从编译相关的不同来说,由于51系列是8位机,扩展16位字符不被C51所支持,其次,ANSI-C所具备的递归特性不被C51所支持,在C51中,要使用递归特性,必须用REENTRANT进行申明才能使用。
KEILC51 与标准ANSI-C在库函数,由于部分库函数不适合嵌入式处理系统,因此被排除在外,如字符屏幕和图形函数,也有一些库函数继续使用,但这些库函数是厂家针对硬件特点相应开发的,它们与ANSI-C的构成及用法都有很大不同,如printf和scanf。在ANSI-C中这两个函数通常用于屏幕打和,接收 字符,而在KEILC51中,它们则主要用于串行数据的收发。
ANSI C的标准函数库(与之相关联的头文件):
assert.h
ctype.h
errno.h
float.h
limits.h
locale.h
math.h
setjmp.h
signal.h
stdarg.h
stddef.h
stdio.h
stdlib.h
string.h
time.h
keil c 库函数
C51强大功能及其高效率的重要体现之一在于其丰富的可直接调用的库函数,多使用库函数使程序代码简单,结构清晰,易于调试和维护,下面介绍C51的库函数系统。
C51提供的本征函数是指编译时直接将固定的代码插入当前行,而不是用ACALL和LCALL语句来实现,这样就大大提供了函数访问的效率,而非本征函数则必须由ACALL及LCALL调用。
C51的本征库函数只有9个,数目虽少,但都非常有用,列如下:
_crol_,_cror_:将char型变量循环向左(右)移动指定位数后返回
_iror_,_irol_:将int型变量循环向左(右)移动指定位数后返回
_lrol_,_lror_:将long型变量循环向左(右)移动指定位数后返回
_nop_: 相当于插入NOP
_testbit_: 相当于JBC bitvar测试该位变量并跳转同时清除。
_chkfloat_: 测试并返回源点数状态。
使用时,必须包含#inclucle <intrins.h>一行。
如不说明,下面谈到的库函数均指非本征库函数。
1. 专用寄存器include文件
例如8031、8051均为REG51.h其中包括了所有8051的SFR及其位定义,一般系统都必须包括本文件。
2. 绝对地址include文件absacc.h
该文件中实际只定义了几个宏,以确定各存储空间的绝对地址。
3. 动态内存分配函数,位于stdlib.h中
4. 缓冲区处理函数位于“string.h”中
其中包括拷贝比较移动等函数如:
memccpy memchr memcmp memcpy memmove memset
这样很方便地对缓冲区进行处理。