您的位置 首页 电路

8位单片机的程序优化11条

1采用短变量一个提高代码效率的最基本的方式就是减小变量的长度。使用C编程时,我们都习惯于对循环控制变量使用int类型,这对8

1 选用短变量

一个进步代码功率的最基本的办法便是减小变量的长度。运用 C 编程时,咱们都习惯于对循环控制变量运用 int 类型,这对 8 位的单片机来说是一种极大的糟蹋,你应该细心考虑你所声明的变量值或许的规模,然后挑选适宜的变量类型,很明显,常常运用的变量应该是unsigned char,只占用一个字节。

2 运用无符号类型
为什么要运用无符号类型呢?原因是8051不支持符号运算,程序中也不要运用含有带符号变量的外部代码,除了依据变量长度来挑选变量类型外,你还要考虑是否变量是否会用于负数的场合。假如你的程序中能够不需求负数那么把变量都界说成无符号类型的。
3 防止运用浮点指针
在 8 位操作体系上运用 32 位浮点数是因小失大的。你能够这样做,但会糟蹋许多的时刻,所以当你要在体系中运用浮点数的时分,你要问问自己这是否必定需求,能够经过进步数值数量级和运用整型运算来消除浮点指针,处理ints和longs比处理doubles和floats要便利得多,你的代码履行起来会更快,也不必衔接处理浮点指针的模块。假如你必定要,选用浮点指针的话,你应该选用西门子 80517 和达拉斯半导体公司的 80320 这些现已对数,处理进行过优化的单片机。假如你不得不在你的代码中参加浮点指针,那么你的代码长度会添加程序履行速度也会比较慢。假如浮点指针运算能被中止的话,你有必要确保要么中止中不会运用浮点指针运算,要么在中止程序前运用 fpsave 指令把中止指针推入仓库,在中止程序履行后运用 fprestore 指令把指针康复,还有一种办法是,当你要运用像 sin()这样的浮点运算程序时,制止运用中止,在运算程序履行完之后再使能它。
4 运用位变量
关于某些标志位应运用位变量而不是 unsigned char,这将节约你的内存,你不必多糟蹋7位存储区,并且位变量在RAM中拜访他们只需求一个处理周期。
5 用局部变量代替全局变量
变量界说成局部变量比全局变量更有功率,编译器为局部变量在内部存储区中分配存储空间,而为全局变量在外部存储区中分配存储空间,这会下降你的拜访速度,另一个防止运用全局变量的原因是你有必要在你体系的处理进程中调理运用全局变量,由于在中止体系和多任务体系中,不止一个进程会运用全局变量。
6 为变量分配内部存储区
局部变量和全局变量可被界说在你想要的存储区中,依据从前的评论,当你把常常运用的变量放在内部 RAM 中时,可使你的程序的速度得到进步,除此之外,你还缩短了你的代码,由于外部存储区寻址的指令相对要费事一些考虑到存储速度,按下面的次序运用存储器DATA IDATA PDATA XDATA,当然你要记住留出满足的仓库空间。
7 运用特定指针
当你在程序中运用指针时,你应指定指针的类型确认它们指向哪个区域如 XDATA 或CODE 区,这样你的代码会愈加紧凑,由于编译器不必去确认指针所指向的存储区,由于你现已进行了阐明。
8 运用调令
关于一些简略的操作,如变量循环位移,编译器供给了一些调令供用户运用,许多调令直接对应着汇编指令,而别的一些比较杂乱并兼容 ANSI 一切这些调令都是再入函数,你可在任何地方安全的调用他们和单字节循环位移指令 RL A 和 RR A 相对应的调令是_crol_ 循环左移 和_cror_(循环右移)。假如你想对 int 或 long 类型的变量进行循环位移,调令将愈加杂乱并且履行的时刻会更长 关于 int 类型调令为_irol_,_iror_ ,关于 long 类型调令为_lrol_,_lror_。在 C 中也供给了像汇编中 JBC 指令那样的调令_testbit_ ,假如参数方位位他将回来1,否则将回来 0 这条调令在查看标志位时非常有用,并且使 C 的代码更具有可读性调令将直接转换成 JBC 指令。
#include
void serial_intr(void) interrupt 4 {
if (!_testbit_(TI)) { // 是否是发送中止
P0=1; // 翻转 P0.0
_nop_(); // 等候一个指令周期
P0=0;

}
if (!_testbit_(RI)) {
test=_cror_(SBUF, 1); // 将SBUF中的数据循环
// 右移一位

}
}
8 运用宏代替函数
关于小段代码,像使能某些电路或从锁存器中读取数据,你可经过运用宏来代替函数使得程序有更好的可读性你可把代码界说在宏中,这样看上去更像函数。编译器在碰到宏时,依照事前界说的代码去代替宏,宏的姓名应能够描绘宏的操作,当需求改动宏时,你只需修该宏界说处。
#define led_on() {
led_state=LED_ON;
XBYTE[LED_CNTRL] = 0x01;}
#define led_off() {
led_state=LED_OFF;
XBYTE[LED_CNTRL] = 0x00;}
#define checkvalue(val)
( (val < MINVAL || val > MAXVAL) ? 0 : 1 )
宏能够使得拜访多层结构和数组愈加简单,能够用宏来代替程序中常常运用的杂乱句子以削减你打字的工作量且有更好的可读性和可维护性。
9 存储器形式
C51供给了 3 种存储器形式来存储变量、进程参数和分配再入函数仓库。你应该尽量运用小存储器形式,很少运用体系需求运用其它两种形式,像有大的再入函数仓库体系那样。一般来说假如体系所需求的内存数小于内部RAM 数时,都应以小存储形式进行编译。在这种形式下 DATA 段是一切内部变量和全局变量的默许存储段,一切参数传递都发生在DATA 段中,假如有函数被声明为再入函数,编译器会在内部 RAM 中为他们分配空间,这种形式的优势便是数据的存取速度很快,但只要120个字节的存储空间供你运用,总共有128个字节,但至少有8个字节被寄存器组运用,你还要为程序调用拓荒满足的仓库。假如你的体系有 256 字节或更少的外部 RAM 你能够运用紧缩存储形式。这样一来,假如不加阐明,变量将被分配在 PDATA 段中,这种形式将扩大你能够运用的 RAM 数量,对XDATA 段以外的数据存储仍然是很快的,变量的参数传递将在内部 RAM 中进行,这样存储速度会比较快,对 PDATA 段的数据的寻址是经过 R0 和R1进行直接寻址,比运用 DPTR 要快一些在大存储形式中,一切变量的默许存储区是 XDATA 段 Keil C 尽量运用内部寄存器组进行参数传递,在寄存器组中能够传递参数的数量和和紧缩存储形式相同,再入函数的模仿栈将在 XDATA中 对 XDATA 段数据的拜访是最慢的,所以要细心考虑变量应存储的方位使数据的存储速度得到优化。
10 混合存储形式
Keil 答应运用混合的存储形式,这点在大存储形式中对错常有用的。在大存储器形式下,有些进程对数据传递的速度要求很高。我就把进程界说在小存储形式寄存器中,这使得编译器为该进程的局部变量在内部 RAM中分配存储空间,并确保一切参数都经过内部 RAM进行传递。虽然选用混合形式后编译的代码长度不会有很大的改动,但这种尽力是值得的就像能在大形式下把进程声明为小形式相同,你像能在小形式下把进程声明为紧缩模或大形式,这一般运用在需求许多存储空间的进程上,这样进程中的局部变量将被存储在外部存储区中,你也能够经过进程中的变量声明,把变量分配在 XDATA 段中。
11 运行库
运行库中供给了许多言简意赅的函数,你能够很便利的运用他们,你自己很难写出更好的代码了。值得注意的是库中有些函数不是再入函数,假如在履行这些函数的时分被中止,而在中止程序中又调用了该函数,将得到意想不到的成果。并且这种过错很难找出来,最好制止运用这些函数的中止。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/dianlu/261097.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部