如何提高单片机C语言代码效率

时间:2023-03-19作者:佚名
代码效率包括两个方面内容:代码的大小和代码执行速度。如果代码精简和执行速度快,我们就说这个代码效率高。一般情况下,代码精简了速度也相应提上来了。单片机的ROMRAM的空间都很有限,当您编程时遇到单片机的ROMRAM的不够用的时候,或者您的程序要求较高的执行速度时,我们就得面对解决代码效率问题了。如何提高代码效率?现笔者以一个LED闪烁的程序为例与您探讨。

#i nclude//包含头文件

sbit led=P2^0;//定义位变量led,使其关联单片机管脚P2.0

void Delayms(unsigned int t);//定义延时函数

int main(void)//主函数(C语言程序入口函数)

{

while(1)

{

led=0;//P2.0拉低,点亮LED

Delayms(500);//调用延时函数,延时500毫秒

led=1;//P2.0拉高,熄灭LED

Delayms(500);//调用延时函数,延时500毫秒

}

return 0;

}

void Delayms(unsigned int t)//延时函数

{

unsigned int i,j;

for(i=0;i

for(j=0;j<120;j );//大约延时1毫秒

}

这是指示灯LED闪烁的C源码,这个源码在Keil uVision4 生成的程序代码是67个字节。下面我们就采用几个方法来提高这个程序的效率。

一.尽量定义局部变量

单片机程序的全局变量一般是放在通用数据存储器(RAM)中,而局部变量一般是放在特殊功能寄存器当中。处理寄存器数据的速度比处理RAM数据要快,如果在一个局部函数里调用一个全局变量将会多生成好几个代码出来。所以,少定义全局变量,多定义局部变量。如上例中,如果把延时函数里的ij定义为全局变量,编译后程序代码会增加到79个字节,多了12个字节。

二.省略函数定义

在一个单片机程序里我们习惯在main函数的前面先定义被调用函数,然后在mian函数的下面再实现被调用函数。这样的写法固然是一个好习惯,但每定义一个函数会增加几个代码,而且函数形参数据类型越大、形参越多增加的代码就越多,显然这不是什么好事。如果不定义编译器又报错,怎么办?C编译器的编译顺序是从上往下编译,只要被调用的函数在主调函数调用之前实现就没有问题了。所以,笔者的习惯写法是不用定义函数,但要按先后顺序(被调用函数一定要在主调函数之前写好)来写函数实现,到最后再写main函数。这样做编译器不但不会报错,而且代码得到精简了。如上例中,把延时函数的定义删除了,然后把延时函数的实现搬到main函数的上面,编译后程序代码减少到63个字节,减少了4个字节。

三.省略函数形参

函数带形参,是为了在函数调用时传递实参,不但可以避免重复代码出现,还可以通过传递不同的实参值多次调用函数且实现不同的函数功能,总体代码也会得到精简。在实际编程的时候,我们只要注意,还可以进一步精简代码。对于不是多次调用或者多次调用但实参值不变的函数我们可以省略函数形参。如上例中的延时函数,我们把它改成不带形参的函数:

void Delayms()//延时函数

{

unsigned int i,j;

for(i=0;i<500;i )

for(j=0;j<120;j );//大约延时1毫秒

}

编译后,程序代码变成了56个字节,精简了11个字节。

四.改换运算符

也许您可能没有注意到C运算符的运用也会影响程序代码的数量。如上例中,把延时函数里的自加运算符改成自减运算符后,如:

void Delayms(unsigned int t)//延时函数

{

unsigned int i,j;

for(i=t;i>0;i--)

for(j=120;j>0;j--);//#p#分页标题#e#大约延时1毫秒

}

编译后,程序代码变成了65个字节,精简了2个字节。

通过改换运算符能达到精简代码的例子还有:

1.把求余运算表达式改为位与运算表达式。如:b=a%8 可以改为:b=a&7

2.把乘法运算表达式改为左移运算表达式。如:b=a*8 可以改为:b=a<<3

3.把除法运算表达式改为右移运算表达式。如:b=a/8 可以改为:b=a>>3

五.选择合适的数据类型

C语言里选择变量的数据类型很讲究,变量的数据类型过小满足不了程序的要求,变量的数据类型过大会占用太多的RAM资源。您可能还没有注意到数据类型定义也影响程序代码的大小,而且这个影响还不小。如上例中,延时函数里的局部变量j定义的数据类型明显偏大,如果把它由unsigned int改成unsigned char 。编译后,程序代码变成了59个字节,精简了8个字节。

六.直接嵌入代码

在您的程序里如果某个函数只调用一次,而您又要求代码提高执行速度,建议您不要采用调用函数的形式,而应该将该函数里的代码直接嵌入主调函数里,代码执行效率会大大提高。

七.使用效率高的C语句

C语言里有一个三目运算符“?”,俗称“问号表达式”。很多程序员都很喜欢使用,因为它逻辑清晰表达简洁。

看这个问号表达式:c=(a>b) ? a 1 : b 1;实际上等效于以下的if…else结构:

if (a>b) c=a 1;

else c=b 1;

可以看到,使用问号表达式,语句相当简洁,但它的执行效率却很低,远没有if…else语句效率高。所以,当您的程序要求提高执行速度的话,建议您不要使用问号表达式了。

另外,do…while语句也比while语句的效率高。

代码的效率问题,不是我们编程中的主要问题,除了程序要求较高的执行速度或者单片机的ROMRAM不够用的时候才会考虑。一般情况下,我们不用在乎。如果您一味追求高效率的代码,可能会影响代码的可读性和可维护性。

相关阅读

晶体管开关电路计算实例(一)

晶体管开关电路计算实例 引言:三极管是电流型元件,利用偏置电阻产生大于0.7V的Vbe电压,然后通过控制电流大小,使晶体管工作在不同的区。 因此关于晶体管电路的设计相关计算,...
2023-06-01
晶体管开关电路计算实例(一)

三相负载不平衡时零线上电流的计算公式详解

对于三相不平衡负载,零线或中性线上面的电流就不为0A,那么怎么计算? 一个简单快速的计算方法,即:√a2 b2 c2—ab—bc—ac,借助这个计算公式,可以轻松计算出三相不平衡负载中...
2024-03-18
三相负载不平衡时零线上电流的计算公式详解

自耦变压器工作原理及种类

  普通的变压器有一次绕组和二次绕组,如果将两个绕组融合成一个绕组就能构成一种特殊的变压器,即自耦变压器。自耦变压器是一种只有一个绕组的变压器。    1.外形   自...
2023-06-27
自耦变压器工作原理及种类

央企招聘高级电气工程师面试经验分享

央企招聘高级电气工程师面试经验分享 1. 充分准备专业知识: - 电路与系统基础:对电路分析、欧姆定律、基尔霍夫定律等基本电路理论要烂熟于心,能够快速准确地分析和解决电路相...
2024-09-09
央企招聘高级电气工程师面试经验分享

电路电气图形符号大全,从此看图识图无压力,电力人都收藏了

好多小伙伴给小编私信问:在看电路图纸的时候常常会遇到一些看不懂的字母、字符,不知道它们所代表的含义,举例说:SS、SR等字母及符号,今天小编在网络上搜集了一些电工电路图...
2023-06-11
电路电气图形符号大全,从此看图识图无压力,电力人都收藏了

热销商品

连发瓦斯枪通用瓦斯射钉钢钉枪瓦斯气体高强度瓦斯射钉枪165气罐

连发瓦斯枪是一款专为高强度瓦斯射钉设计的工具,其特点在于能够连续发射瓦斯气体,适用于多种需要快速穿透和固定材料的场景。这款瓦斯枪配备了165气罐,容量足够满足...
4.5

黄铜镀镍金属电缆防水接头EWM密封格兰头HSM电线固定填料函M20M16

黄铜镀镍金属电缆防水接头EWM密封格兰头(HSM型)是一款高性能电线固定与密封装置,适用于M16和M20螺纹规格。采用优质黄铜材质并表面镀镍处理,具备优异的防腐蚀性、机械...
1.14

消防配件二氧化碳灭火器2 3 5 7KG弯头喷管24Kg干冰CO2外喷头喷嘴

二氧化碳灭火器配件中的2357KG弯头喷管与24Kg干冰CO₂外喷头喷嘴,是专业消防设备的重要组成部分。该弯头喷管采用高强度耐腐蚀材料制造,连接灵活,适用于高压CO₂灭火...
4.5

雷士照明led筒灯孔灯客厅吊顶天花灯嵌入式过道筒灯射灯桶灯家用

雷士照明LED筒灯是一款专为现代家居设计的嵌入式照明产品,适用于客厅、吊顶、过道、卧室等空间。采用高品质LED光源,光线柔和均匀,显色指数高,有效还原真实色彩,营造舒...
5.78

雷士照明嵌入式防眩筒灯射灯窄边过道灯深杯客厅无主灯天花灯米雪

雷士照明嵌入式防眩筒灯射灯——“米雪”系列,专为现代无主灯设计打造。采用窄边深杯结构,有效控制杂散光,实现精准防眩,营造舒适柔和的光环境。适用于客厅、过道、天...
25.67

网站栏目