电子发烧友网 > 控制/MCU > 正文

如何提高单片机C语言程序的执行效率

2020年03月06日 18:52 次阅读

首先什么是执行效率。我们平常所说的执行效率就是使用相同的算法在相同输入条件下完成相同计算所产生的系统开销,目前来说一般会更多关注执行时间方面的开销。所有语言编写的代码最终要运行,都要转化成机器码。在更短的时间内完成相同的事那么效率就高。

关于如何提高C语言程序的执行效率,以我多年的编程经验在这里我来谈谈我的想法:

1.尽量避免调用延时函数

没有带操作系统的程序只能在while(1)里面循环执行,如果在这里面调用大量的延时这样会很消耗CPU的资源,延时等于是让他在这歇着不干事了,只有中断里面的才会执行。如果仅仅是做一个LED一秒闪烁一次的程序,那么很简单,可以直接调用延时函数,但是实际的项目中往往在大循环里有很多事要做,对于实时性要求较高的场合就不行了。为了避免使用延时,可以使用定时器中断产生一个标志位,到了时间标志位置1,在主程序里面只需要检测标志位,置1了才执行一次,然后清标志。其他时间就去做别的事了,而不会在这等待了。最好的例子就是数码管的显示,使用中断调显示,在我们的例程里面有。然后是那个按键检测的,一般的程序都是做的while(!key)等待按键释放,如果按键一直按着,那后面的程序就永远得不到运行死在这了,其实可以做一个按键标志检测下降沿和上升沿就可以避免这个问题了。

2.写出来的代码要尽量简洁,避免重复

在10天学会单片机那本书上看到他写的数码管显示那部分代码,选中一个位,然后送数据,再选中一个位,再送数据,依次做完。代码重复率太高了,不仅占用过多的类存,而且执行效率差可读性差,仅仅是实现了功能而已,实际的编程可以做一个循环,for循环或者while循环。这样的代码看起来更有水平。

如何提高单片机C语言程序的执行效率

3.合理使用宏定义

在程序中如果某个变量或寄存器经常用到,可以使用宏定义定义一个新的名代替他,这样的好处是方便修改,比如液晶的数据端总线接的P1,现在想改到P0,那么只需要修改宏定义这里就可以了,编译器编译的时候,他会自动的把定义的名替换成实际的名称。

4.使用尽量小的数据类型

比如某个变量的值范围是0-255,那么就定义成unsignedchar,当然也可以定义成unsignedint,但是这样造成了内存的浪费,而且运算时效率要低一点。如果数据没有负数的话,尽量定义成无符号的类型。应尽量避免定义成浮点型数据类型或双精度(占8个字节)类型,这两种类型运算时很消耗CPU资源。比如采集电压范围是0-5v,精确到小数点后三位,可以把采集到的数据扩大1000倍,即使最大也才到5000,然后多采集几次做个滤波算法,最后电压算出来后只需要在第一位后面加个小数点就可以了,变量定义成unsignedint型变量就没问题了。

5.避免使用乘除法

乘除法很消耗CPU资源,查看汇编代码会发现,一个乘除法运算会编译出10几甚至几10行代码。如果是乘以或除以2的n次方,可以用<<或>>来实现,这种移位运算在编译时就已经算好了,所以代码很简洁,运算效率就高。但是需要特别注意运算符的优先级问题。

6.尽量使用复合赋值运算符

a=a+b与a+=b这两个表达式有什么区别呢?前者是先计算a+b的值,然后保存到ACC寄存器,然后再把ACC寄存器的值赋给a,而后者是直接将a+b的值赋给a,节省一个步骤,虽然只节省了一条指令,但是当这个运算循环几千次几万次呢,那么效果很明显了。像其他的-=、*=、/=、%=等都是一样的。

7.尽量不要定义成全局变量

先来看一下局部变量,全局变量,静态局部变量,静态全局变量的异同:

(1)局部变量:在一个函数中或复合语句中定义的变量,在动态存储区分配存储单元,在调用时动态分配,在函数或复合语句结束时自动释放;

(2)静态局部变量:在一个函数中定义局部变量时,若加上static声明,则此变量为静态局部变量,在静态存储区分配存储单元,在程序运行期间都不释放;静态局部变量只能在该函数中使用;静态局部变量在编译时赋值(若在定义时未进行赋值处理,则默认赋值为0(对数值型变量)或空字符(对字符型变量));静态局部变量在函数调用结束后不自动释放,保留函数调用结束后的值;

(3)全局变量:在函数外定义的变量称为全局变量;全局变量在静态存储区分配存储单元,在程序运行期间都不释放,在文件中的函数均可调用该全局变量,其他文件内的函数调用全局变量,需加extern声明;

(4)静态全局变量:在函数外定义变量时,若加上staTIc声明,则此变量为静态全局变量;静态全局变量在静态存储区分配存储单元,在程序运行期间都不释放,静态全局变量在编译时赋值(若在定义时未进行赋值处理,则默认赋值为0(对数值型变量)或空字符(对字符型变量));只能在当前文件中使用。

一般情况下就定义成局部变量,这样不仅运行更高效,而且很方便移植。局部变量大多定位于MCU内部的寄存器中,在绝大多数MCU中,使用寄存器操作速度比数据存储器快,指令也更多更灵活,有利于生成质量更高的代码,而且局部变量所的占用的寄存器和数据存储器在不同的模块中可以重复利用。

当中断里需要用到的变量时,就需要定义成全局变量,并且加volaTIle修饰一下,防止编译器优化。如果数据是只读的比如数码管的断码、汉字取模的字库需要放在ROM里,这样可以节省RAM,51单片机是加code,高级点的单片机都是加const修饰。

8.选择合适的算法和数据结构

应该熟悉算法语言,知道各种算法的优缺点,具体资料请参见相应的参考资料,有很多计算机书籍上都有介绍。将比较慢的顺序查找法用较快的二分查找或乱序查找法代替,插入排序或冒泡排序法用快速排序、合并排序或根排序代替,都可以大大提高程序执行的效率。.

选择一种合适的数据结构也很重要。指针是一个包含地址的变量,可对他指向的变量进行寻址。使用指针可以很容易的从一个变量移到下一个变量,故特别适合对大量变量进行操作的场合。数组与指针语句具有十分密切的关系,一般来说,指针比较灵活简洁,而数组则比较直观,容易理解。对于大部分的编译器,使用指针比使用数组生成的代码更短,执行效率更高。但是在Keil中则相反,使用数组比使用的指针生成的代码更短。

9.使用条件编译

一般情况下对C语言程序进行编译时,所有的程序都参加编译,但是有时希望对其中一部分内容只在满足一定条件才编译,这就是条件编译。条件编译可以根据实际情况,选择不同的编译范围,从而产生不同的代码。

10.嵌入汇编---杀手锏

汇编语言是效率最高的计算机语言,在一般项目开发当中一般都采用C语言来开发的,因为嵌入汇编之后会影响平台的移植性和可读性,不同平台的汇编指令是不兼容的。但是对于一些执着的程序员要求程序获得极致的运行的效率,他们都在C语言中嵌入汇编,即“混合编程”。注意:如果想嵌入汇编,一定要对汇编有深刻的了解。不到万不得已的情况,不要使用嵌入汇编。
责任编辑;zl

下载发烧友APP

打造属于您的人脉电子圈

关注电子发烧友微信

有趣有料的资讯及技术干货

关注发烧友课堂

锁定最新课程活动及技术直播

电子发烧友观察

一线报道 · 深度观察 · 最新资讯
收藏 人收藏
分享:

评论

相关推荐

书童哥(龙顺宇)62讲生动课程带您玩儿转STM8单片机

【课程介绍】:朋友们大家好,本套视频教程由本人录制,现做为录播课程上传至电子发烧友网平台,感谢电子发烧友网让单片机学习的
发烧友学院发表于 2019-01-19 00:00 3004次阅读
书童哥(龙顺宇)62讲生动课程带您玩儿转STM8单片机

揭秘嵌入式C语言main函数的写法原因

但凡是学过C语言的人,都知道要先写main函数,然而很多时候我们看到的main函数却各有差异,这究竟是为啥?哪种是对的...
发表于 2020-03-07 14:43 28次阅读
揭秘嵌入式C语言main函数的写法原因

基于μC/OS-II操作系统在SPCE061A上...

SPCE061A是凌阳科技新推出的u课SP内核的十六位单片机,内嵌32K字 Flash的SPCE06....
发表于 2020-03-07 09:57 33次阅读
基于μC/OS-II操作系统在SPCE061A上...

可编程逻辑器件与单片机共同构成的双控制器

在传统的控制系统中,人们常常采用单片机作为控制核心。但这种方法硬件连线复杂,可靠性差,且单片机的端口....
发表于 2020-03-06 11:54 34次阅读
可编程逻辑器件与单片机共同构成的双控制器

单片机与MAX485通讯时,单片机到光耦的供电电压不正常

该电路图是另一块主板(单片机在主板上)的收发TTL信号,到该板转换为485信号输出。电路板红色圈主部分,是MAX4...
发表于 2020-03-06 11:16 130次阅读
单片机与MAX485通讯时,单片机到光耦的供电电压不正常

请问为什么步进电机的程序会自己跑起来?

我想要做到按住按钮步进电机就动,现在用我自己的程序和别人写的程序都是导入后端口的电平在自动变化,按钮控制不了。...
发表于 2020-03-06 11:06 142次阅读
请问为什么步进电机的程序会自己跑起来?

你知道什么是Python吗

Python是一种跨平台的计算机程序设计语言 。是一种面向对象的动态类型语言,最初被设计用于编写自动....
发表于 2020-03-06 10:19 87次阅读
你知道什么是Python吗

基于M16C62单片机实现实时多任务系统的设计方...

随着微电子技术和网络的发展,人们对网络的认识日益深入。网络终端产品也越来越受到人们的关注,嵌入式操作....
发表于 2020-03-06 09:47 53次阅读
基于M16C62单片机实现实时多任务系统的设计方...

用少量的程序代码能实现人机交互设计吗?

本系统设计按键时遇到以下情况:(1)产品外设较多,单片机I/O口比较少,设计时需要考虑节省I/O口。(2)现场情况所...
发表于 2020-03-06 07:28 63次阅读
用少量的程序代码能实现人机交互设计吗?

请问C语言中能高效方式跟换字节位置吗?

C语言中有没有一种高效方式跟换字节中的BIT位置,如:76543210更换成自己想要的规格如:45670123或者46570213等等...
发表于 2020-03-06 04:35 13次阅读
请问C语言中能高效方式跟换字节位置吗?

请问单片机怎么过WiFi连接路由器或以太网?

如题,光盘的参考资料上也没找到参考方案...
发表于 2020-03-06 04:35 19次阅读
请问单片机怎么过WiFi连接路由器或以太网?

C语言指针必须要进行强制类型转换?

[C] 纯文本查看 复制代码 #include int main(void){    char *pc;    int * pi;[C] 纯文本查看...
发表于 2020-03-06 04:14 25次阅读
C语言指针必须要进行强制类型转换?

89C2051单片机怎么组成数显八路断线检测仪?

由89C2051单片机组成的数显八路断线检测仪
发表于 2020-03-06 03:51 31次阅读
89C2051单片机怎么组成数显八路断线检测仪?

单片机驱动输出电压达不到12V

可编程开关 我现在有一个12V电压控制的机械快门,想实现的功能是通过单片机和放大电路进行控制。 当控制单片机管脚...
发表于 2020-03-06 00:32 46次阅读
单片机驱动输出电压达不到12V

C语言浮点数运算结果是什么??

int   main(void) {        float        A=0.18; ...
发表于 2020-03-05 21:57 14次阅读
C语言浮点数运算结果是什么??

在电子设计中有许多坑 如何躲避就是个大问题

做电子工程设计需要谨小慎微,考虑周全尽可能避免一些错误。但是,对于刚入门的小白来说,很多时候难以做到....
发表于 2020-03-05 17:11 45次阅读
在电子设计中有许多坑 如何躲避就是个大问题

单片机开发规则与注意事项

要完成单片机系统的开发,用户不仅需要掌握编程技术,还需要针对实际应用选择合理的单片机芯片和外围器件,....
发表于 2020-03-04 10:06 74次阅读
单片机开发规则与注意事项

单片机中一些最基本的软硬件介绍

单片机是一门实践性很强、非常注重动手的课程。学习单片机最有效的方法是理论与实践并重,边学习,边演练,....
发表于 2020-03-03 16:07 187次阅读
单片机中一些最基本的软硬件介绍

嵌入式硬件还是软件比较好

嵌入式硬件工程师那在工作中,是指能够根据项目管理和工程技术的实际要求,按照系统总体设计规格进行软、硬....
发表于 2020-03-02 10:51 117次阅读
嵌入式硬件还是软件比较好

你觉得嵌入式入门容易吗

首先需要学习LINUX内核基础部分,包括内核配置编译,内核模块,并发控制,字符设备,设备模型,平台设....
发表于 2020-03-02 10:42 98次阅读
你觉得嵌入式入门容易吗

单片机的种类有哪些

 国外单片机品牌有意法半导体ST,恩智浦,瑞萨,mcrochip,赛普拉斯,atmel等等
发表于 2020-03-01 14:14 248次阅读
单片机的种类有哪些

单片机制作模拟电子琴

在这个小制作里除了给大家介绍了“mini”模拟电子琴所需的硬件外,还主要介绍了用单片机为控制核心如何....
发表于 2020-03-01 14:02 173次阅读
单片机制作模拟电子琴

库区测温网络无线传输系统的硬件电路和软件设计

库区温度直接关系到库存物资的安全与性能,目前库区温度数据的传输大多采用有线方式,存在布线难度大、材料....
发表于 2020-02-29 11:12 94次阅读
库区测温网络无线传输系统的硬件电路和软件设计

如何快速学习单片机编程

编译器的不同会造成单片机C程序编写过程中细节的差异,比如unsignedint类型,在某些编译器当中....
发表于 2020-02-28 14:06 281次阅读
如何快速学习单片机编程

基于AVR单片机和温度传感器实现智能温控系统的设...

在工农业生产和日常生活中,温度的测量及控制越来越重要。传统的温度控制系统采用热敏电阻器或热电偶测量温....
发表于 2020-02-27 10:51 166次阅读
基于AVR单片机和温度传感器实现智能温控系统的设...

采用AVR单片机和GTJ4-10A固态继电器实现...

温度显示曲线图的主要任务是将单片机接收到的数据显示出来,当温度传过时,在软件中分别显示当前的温度值和....
发表于 2020-02-27 10:48 391次阅读
采用AVR单片机和GTJ4-10A固态继电器实现...

通过采用单片机和指纹识别模块实现电子机械锁的设计

随着生活水平的提高,人们对物质生活的要求越来越高,尤为注重住宅安全问题。随着生物特征识别技术的发展,....
发表于 2020-02-27 10:38 165次阅读
通过采用单片机和指纹识别模块实现电子机械锁的设计

基于ATmega64及RTL8019AS实现工业...

随着互联网的日益普及,各种家电设备、仪器仪表以及工业生产中的数据采集与控制设备在逐步地走向网络化,以....
发表于 2020-02-27 10:38 92次阅读
基于ATmega64及RTL8019AS实现工业...

C语言的数据储存与数据类型及类型转换的详细资料说...

程序说到底就是对数据的处理,所以首先要弄清楚需要处理哪些数据,计算机如何存储这些数据。C语言根据需要....
发表于 2020-02-24 15:39 418次阅读
C语言的数据储存与数据类型及类型转换的详细资料说...

C语言与Java之间的主要区别有哪些

本文主要为C#开发人员了解Java提供一些基础。 Java中缺少C#的功能 C#包含更多....
发表于 2020-02-24 14:31 381次阅读
C语言与Java之间的主要区别有哪些

C语言中#和##符号有什么样的作用

、#的预处理作用 预处理过程实质上是处理“#”,包括: 将#include包含的头文件直....
发表于 2020-02-24 10:56 633次阅读
C语言中#和##符号有什么样的作用

C语言printf格式化输出的实例详细资料说明

printf 是C语言非常有用的一个函数,也是我们入门学习C语言的第一个函数。掌握 printf 的....
发表于 2020-02-24 10:53 292次阅读
C语言printf格式化输出的实例详细资料说明