基于Keil C51编译器的程序优化

2014-08-27 08:12
时代农机 2014年2期
关键词:编译器数据类型存储器

徐 斯

(湖南机电职业技术学院,湖南 长沙 410151)

80C51单片机是目前国内外工业测控领域中使用极为广泛的一类8位MCU,C51是面向80C51单片机的C语言。C语言是一种结构化的程序设计高级语言,在单片机应用系统开发中采用C语言编程,易于开发复杂的单片机应用程序,易于进行单片机应用程序的移植,有利于产品中的单片机重新选型,可大大加快单片机应用程序的开发速度。用C51编写的应用程序须经C51编译器转换生成单片机可执行的代码程序。Keil C51编译器生成的代码紧凑、使用方便、全面支持8051单片机主流产品及其众多的派生系列。

1 灵活选择变量的存储器类型和数据类型

(1)变量的数据类型选择。①尽可能使用最小的数据类型char、unsigned char或bit。这类数据只占用1B或者1位,由于80C51是8位机,显然对它们的操作要比对int或long类型数据操作要方便得多。②尽可能使用unsigned数据类型,原因是80C51机器指令不支持符号运算。当在C源代码中使用了有符号的变量,尽管从字面上看,其操作十分简单,但C51编译器将要增加相应的库函数,产生更多的程序代码去处理符号运算。所以除了根据变量长度来选择变量类型以外,还要考虑该变量是否会用于负数的场合,如果程序中可以不需要负数,那么可把变量都定义成无符号类型的。

(2)变量的存储器类型选择。由于单片机系统的存储器资源有限,为了提高执行效率,对存储器类型的设定,应该根据以下原则:只要条件满足,尽量先使用直接寻址片内数据存储器(data),其次设定变量为间接寻址片内数据存储器(idata),在内部存储器数量不够的情况下,才使用外部存储器,而且在外部存储器中,优先选择分页寻址的数据存储器pdata,最后才是片外数据存储器xdata,而且,在内部和外部存储器共同使用的情况下,要合理分配存储器,对经常使用和计算频繁的数据,应该使用内部存储器,其他的则使用外部存储器。根据它们的数量进行分配,尽量减少访问外部存储器,从而提高程序运行效率。

2 避免使用浮点变量

在80C51单片机系统上使用32位浮点数是得不偿失的,这样做会浪费单片机大量的存储器资源和程序执行时间。一定要在系统中使用浮点数的时候,可以通过提高数值数量级或使用整型运算代替浮点运算。在运算时,可以进行定点运算的尽量进行定点运算,避免进行浮点运算。尽量减少乘除法运算,如*2或/2,就可以使用移位操作代替乘除法运算,这样不仅可以减少代码量,同时还能大提高程序执行效率。处理ints和longs比处理doubles和floats要方便得多,代码执行起来会更快,C51编译器也不用连接处理浮点运算的模块。

3 尽可能使用局部变量

一个源文件可以包含一个或几个函数。在一个函数内部定义的变量是局部,它只在本函数范围内有效。在函数之外定义的变量是全局变量,它可以为本源文件中其它函数所共用,有效范围为:从定义变量的位置开始到本源文件结束。

在编写C51语言程序时,不是特别必要的地方一般不要使用全局变量,而尽可能地使用局部变量,因为:

(1)局部变量只是在使用它时,编译器才为它在内部存储区分配存储单元,而全局变量在程序的全部执行过程中都要占用存储单元。

(2)全局变量使函数的通用性降低了,因为函数在执行时要依赖于其所在的外部变量。如果将一个函数移到另一个文件中,还要将有关的外部变量及其值一起移过去。但若该外部变量与其它文件的变量同名时,就会出现问题,降低了程序的可靠性和通用性。在程序设计中,在划分模块时要求模块的“内聚性”强、与其它模块的“耦合性”弱。即模块功能要单一(不要把许多互不相干的功能放到一个模块中),与其它模块的相互影响尽量少。而全局变量是不符合这个原则的。一般要求把C51程序中的函数做成一个封闭体,除了可以通过“实参——形参”的渠道与外界发生联系外,没有其它渠道。这样的程序移植性好、可读性强。

(3)使用全局变量过多,会降低程序的清晰性,人们往往难以清楚地判断出每个瞬时各个外部变量的值。在各个函数执行时都可能改变外部变量的值,程序容易出错。因此,要限制使用全局变量。

4 使用库函数

从用户的角度来看,有两种函数:库函数和用户自定义函数。库函数是KeilC51编译器提供的,不需要用户进行定义,可以直接调用。用户自定义函数是用户根据自己需要编写的能实现特定功能的函数,它必须先进行定义之后才能调用。正确而灵活地使用库函数可使程序代码简单、结构清晰、易于调试和维护。

(1)重视本征库函数的使用。本征库函数是库函数中的一类,它在编译时直接将固定的代码插入到当前行,而不是用汇编语言中的“ACALL”和“LCALL”指令来实现调用,从而大大提高了函数的访问效率。

例如单字节循环位移指令RL A和RR A相对的调令是_crol_(循环左移)和_cror_(循环右移)。如果想对int或long类型的变量进行循环位移,汇编调令将更加复杂,而且执行的时间会更长。对于int类型C库函数为_irol_、iror_,对于long类型函数为_lrol_、_lror_。再例如JBC指令相对的调令是_testbit_,如果参数位置位,它将返回1;否则将返回0。

(2)重视复制、比较、移动等子符串处理库函数的使用。子符串处理库函数位于string.h中,其中包括复制、比较、移动等函数:memccpy、memchr、memcmp、memcpy、memmove、memset。在这些函数中,字符串的长度由调用者明确规定,函数可以工作在任何模式下。使用这些函数可以很方便地对字符串进行处理。

例1:使用库函数对字符串进行复制、比较、移动。

5 使用宏替代无符号数据类型和函数

(1)使用宏替代无符号数据类型。在输入源程序时,为了提高输入效率,可使用宏替代无符号数据类型。其方法是在源程序开头,使用#define语句定义。

例 2:#define uchar unsigned char

这样,在输入源程序时,可以 uchar、uint、ulong代替unsigned char、unsigned int、unsigned long。在后面的叙述中我们有可能不加说明地使用uchar、uint、ulong说明定义的变量。

(2)使用宏替代函数。对于小段代码,像从锁存器中读取数据,可通过使用宏来替代函数,使得程序有更好的可读性,可把代码定义在宏中,这样看上去更像函数编译器在碰到宏时,按照事先定义的代码去替代宏。宏的名字应能够描述宏的操作,当需改变宏时,只要修改宏定义处即可。

例3:#define led_on(){

宏能够使得访问多层结构和数组更加容易,可以用宏替代程序中经常使用的复杂语句,以减少程序输入时的工作量,且有更好的可读性和可维护性,与函数调用相比较,执行效率更高,但程序的执行代码较大,因编译器将定义的宏内容直接嵌入到代码中。

6 尽量使用小存储模式

C51提供了三种存储器模式存储变量、过程参数和分配再入函数堆栈。应该尽量使用小存储器模式,即SMALL模式。应用系统很少需要使用其他两种模式,像有大的再入函数堆栈系统那样。一般来说如果系统所需要的内存数小于内部RAM数时,都应以小存储模式进行编译,对其它存储模式可以由PDATA和XDATA进行说明。

在SMALL模式下,DATA段是所有的内部变量和全局变量的默认存储段,所有参数传递都发生在DATA段中。如果有函数被声明为再入函数,编译器会在内部RAM中为它们分配空间。这种模式的优势就是数据的存取速度很快,但由于片内RAM空间有限,对于较大的程序还得采用LARGE存储器模式。

在实际进行项目开发时,如果能遵守科学的工程开发规则,灵活地运用C语言的强大功能,熟悉硬件特点,就能够在较短时间内编写出高效率、高可靠、易维护的嵌入式系统的执行代码。

7 使用C51和汇编语言的混合编程

在模块化程序开发过程中,一般用汇编语言编写与硬件有关的程序,用C51语言编写主程序及数据处理程序。使用混合编程技术可以很方便地在一些较大的C51程序中加入已有的汇编驱动程序。在编写较大的程序时利用已有的汇编程序一方面可以节约大量的程序开发时间,另一方面在编写驱动程序时,使用汇编语言可以保证部分对时间和稳定性有严格要求的程序段。同时,混合编程中的C51和汇编语言的使用仍然和独立开发时基本一样,只是在使用不同的语言时,需要注意不同函数之间的调用格式和参数传递的规定。

在实际进行项目开发时,如果能遵守科学的工程开发规则,灵活地运用C语言的强大功能,熟悉硬件特点,就能够在较短时间内编写出高效率、高可靠、易维护的嵌入式系统的执行代码。

[1]谭浩强.C程序设计(第三版)[M].北京:清华大学出版社,2005.

[2]李广弟.单片机基础[M].北京:北京航空航天大学出版社,2007.

[3]张齐,杜群贵.单片机应用系统设计技术-基于C语言编程[M].北京:电子工业出版社,2004.

[4]徐爱钧.8051单片机实践教程-asm51汇编语言与C51高级语言应用[M].北京:电子工业出版社,2005.

[5]杨恢先.单片机原理及应用[M].湘潭:湘潭大学出版社,2013.

[6]施大发.基于Keil C51编译器的程序优化设计[J].电脑编程技巧与维护,2010,(2).

猜你喜欢
编译器数据类型存储器
详谈Java中的基本数据类型与引用数据类型
静态随机存储器在轨自检算法
如何理解数据结构中的抽象数据类型
基于相异编译器的安全计算机平台交叉编译环境设计
基于SeisBase模型的地震勘探成果数据管理系统设计
相似度计算及其在数据挖掘中的应用
Microchip为MPLAB XC系列专业版编译器推出低成本可续订包月许可证
存储器——安格尔(墨西哥)▲
通用NC代码编译器的设计与实现
基于Nand Flash的高速存储器结构设计