0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何高效率编写单片机代码,优化程序设计

贸泽电子设计圈 来源:未知 作者:佚名 2017-12-25 09:20 次阅读

由于单片机的性能同电脑的性能是天渊之别的,无论从空间资源上、内存资源、工作频率,都是无法与之比较的。PC 机编程基本上不用考虑空间的占用、内存的占用的问题,最终目的就是实现功能。而对于单片机来说就截然不同了,一般的单片机的Flash 和Ram 的资源是有限的,可想而知,单片机的资源是少得可怜,为此我们必须想法设法榨尽其所有资源,将它的性能发挥到最佳,程序设计时必须遵循以下几点进行优化:

1、使用尽量小的数据类型

能用unsiged就不用signed;能用char就不用int;能不用floating就不用;能用位操作不用算数。

2、使用自加、自减指令

通常使用自加、自减指令和复合赋值表达式(如a-=1 及a+=1 等)都能够生成高质量的程序代码,编译器通常都能够生成inc 和dec 之类的指令,而使用a=a+1 或a=a-1 之类的指令,有很多C 编译器都会生成二到三个字节的指令。

3、减少运算的强度

可以使用运算量小但功能相同的表达式替换原来复杂的的表达式。

(1) 求余运算

N= N %8 可以改为N = N &7

说明:位操作只需一个指令周期即可完成,而大部分的C 编译器的“%”运算均是调用子程序来完成,代码长、执行速度慢。通常,只要求是求2n 方的余数,均可使用位操作的方法来代替。

(2) 平方运算

N=Pow(3,2) 可以改为N=3*3

说明:在有内置硬件乘法器的单片机中(如51 系列),乘法运算比求平方运算快得多, 因为浮点数的求平方是通过调用子程序来实现的,乘法运算的子程序比平方运算的子程序代码短,执行速度快。

(3) 用位移代替乘法除法

N=M*8 可以改为N=M<<3N=M/8 可以改为N=M>>3

说明:通常如果需要乘以或除以2n,都可以用移位的方法代替。如果乘以2n,都可以生成左移的代码,而乘以其它的整数或除以任何数,均调用乘除法子程序。用移位的方法得到代码比调用乘除法子程序生成的代码效率高。实际上,只要是乘以或除以一个整数,均可以用移位的方法得到结果。

如N=M*9可以改为N=(M<<3)+M;

(4) 自加自减的区别

例如我们平时使用的延时函数都是通过采用自加的方式来实现。

void DelayNms(UINT16 t){UINT16 i,j;for(i=0;idefine MAX(A,B) {(A)>(B)?(A):(B)}

说明:函数和宏函数的区别就在于,宏函数占用了大量的空间,而函数占用了时间。大家要知道的是,函数调用是要使用系统的栈来保存数据的,如果编译器里有栈检查选项,一般在函数的头会嵌入一些汇编语句对当前栈进行检查;同时,CPU也要在函数调用时保存和恢复当前的现场,进行压栈和弹栈操作,所以,函数调用需要一些CPU时间。而宏函数不存在这个问题。宏函数仅仅作为预先写好的代码嵌入到当前程序,不会产生函数调用,所以仅仅是占用了空间,在频繁调用同一个宏函数的时候,该现象尤其突出。

1.适当地使用算法

假如有一道算术题,求1~100 的和。

作为程序员的我们会毫不犹豫地点击键盘写出以下的计算方法:

UINT16 Sum(void){UINT8 i,s;for(i=1;i<=100;i++){s+=i;}return s;}

很明显大家都会想到这种方法,但是效率方面并不如意,我们需要动脑筋,就是采用数学算法解决问题,使计算效率提升一个级别。

UINT16 Sum(void){UINT16 s;s=(100 *(100+1))>>1;return s;}

结果很明显,同样的结果不同的计算方法,运行效率会有大大不同,所以我们需要最大限度地通过数学的方法提高程序的执行效率。

2.用指针代替数组

在许多种情况下,可以用指针运算代替数组索引,这样做常常能产生又快又短的代码。与数组索引相比,指针一般能使代码速度更快,占用空间更少。使用多维数组时差异更明显。下面的代码作用是相同的,但是效率不一样。

UINT8 szArrayA[64];UINT8 szArrayB[64];UINT8 i;UINT8 *p=szArray;for(i=0;i<64;i++)szArrayB=szArrayA;for(i=0;i<64;i++)szArrayB=*p++;

指针方法的优点是,szArrayA 的地址装入指针p 后,在每次循环中只需对p 增量操作。在数组索引方法中,每次循环中都必须进行基于i 值求数组下标的复杂运算。

3.强制转换

C 语言精髓第一精髓就是指针的使用,第二精髓就是强制转换的使用,恰当地利用指针和强制转换不但可以提供程序效率,而且使程序更加之简洁,由于强制转换在C 语言编程中占有重要的地位,下面将已五个比较典型的例子作为讲解。

例子1:将带符号字节整型转换为无符号字节整型

UINT8 a=0;INT8 b=-3;a=(UINT8)b;

例子2:在大端模式下(8051 系列单片机是大端模式),将数组a[2]转化为无符号16 位整型值。

方法1:采用位移方法。

UINT8 a[2]={0x12,0x34};UINT16 b=0;b=(a[0]<<8)|a[1];

结果:b=0x1234

方法2:强制类型转换。

UINT8 a[2]={0x12,0x34};

UINT16 b=0;

b= (UINT16 )a; //强制转换

结果:b=0x1234

例子3:保存结构体数据内容。

方法1:逐个保存。

typedef struct _ST{UINT8 a;UINT8 b;UINT8 c;UINT8 d;UINT8 e;}ST;ST s;UINT8 a[5]={0};s.a=1;s.b=2;s.c=3;s.d=4;s.e=5;a[0]=s.a;a[1]=s.b;a[2]=s.c;a[3]=s.d;a[4]=s.e;

结果:数组a 存储的内容是1、2、3、4、5。

方法2:强制类型转换。

typedef struct _ST{UINT8 a;UINT8 b;UINT8 c;UINT8 d;UINT8 e;}ST;ST s;UINT8 a[5]={0};UINT8 p=(UINT8 )&s;//强制转换UINT8 i=0;s.a=1;s.b=2;s.c=3;s.d=4;s.e=5;for(i=0;i

define Perror(FUN) printf(“Err:%s %s %d: %s ”, FILE, func,LINE,FUN) 类linux的perror函数实现,这里加了出错的文件位置,所在函数,引发出错调用的函数FUN。

宏中#和##的用法define STR(s) #sdefine CONS(a, b) int(a##e##b)printf(STR(vck));//输出vckprintf(“%d ”, CONS(2,3));//2e3 输出2000

这些方法常用,必然会让你的代码更加简洁高效!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6001

    文章

    43973

    浏览量

    620821
  • 编程
    +关注

    关注

    88

    文章

    3440

    浏览量

    92383

原文标题:编写高效率稳定的单片机代码,其实也没你想得那么难~

文章出处:【微信号:Mouser-Community,微信公众号:贸泽电子设计圈】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    高效率的DC电源模块设计技巧

    的开关电源作为电源模块的核心。开关电源通常比线性电源具有更高的转换效率,可以将输入电压转换为所需的输出电压而减少能量损耗。 提高效率的DC电源模块设计技巧 2. 优化输入滤波电路:在电源模块的输入端添加适当的滤波电路,可以阻挡高
    的头像 发表于 02-26 14:27 166次阅读
    提<b class='flag-5'>高效率</b>的DC电源模块设计技巧

    单片机代码自动生成器程序

    和输入/输出设备的芯片。它通常用于嵌入式系统中,能够完成一系列特定的任务。开发人员编写单片机代码负责指导单片机执行相应的任务。然而,编写
    的头像 发表于 01-08 14:12 721次阅读

    如何提升单片机开发技术?

    选择合适的单片机型号和外设,能够更好地满足程序的需求,提高程序的运行效率。 问:如何进行单片机程序
    发表于 01-05 10:14

    使用c语言给单片机编写程序在运行的时候if语句运行的快还是switch语句执行的速度快?

    请问使用c语言给单片机编写程序在运行的时候if语句运行的快,还是switch语句执行的速度快?在优化之前的人写的程序,有人看到
    发表于 11-08 06:55

    如何用51单片机编写一个时钟程序

    用51单片机做时钟程序,怎么写代码让才能让蜂鸣器整点报时?
    发表于 10-28 08:29

    能否使用通过编写代码检测单片机的寄存器存在问题?

    如题,能否使用通过编写代码检测单片机的寄存器存在问题????
    发表于 10-27 08:30

    基于VB的PC机与单片机间串口通讯及程序设计

    电子发烧友网站提供《基于VB的PC机与单片机间串口通讯及程序设计.pdf》资料免费下载
    发表于 10-23 14:10 2次下载
    基于VB的PC机与<b class='flag-5'>单片机</b>间串口通讯及<b class='flag-5'>程序设计</b>

    单片机驱动LCD如果提高效率

    单片机驱动LCD如果提高效率
    发表于 10-23 07:44

    单片机编程中怎么让效率提高,代码也简洁?

    单片机编程中怎么让效率提高,代码也简洁
    发表于 10-20 06:19

    单片机C语言程序设计实训100例

    单片机C语言程序设计实训100例51 Proteus仿真本书基于Keil μVision程序设计平台和Proteus硬件仿真平台,精心编写了100余个8051
    发表于 09-27 06:16

    高效率反激变换器设计技巧分享

    漏感问题是反激变换器的基本问题。漏感是硬伤。要实现高效率,控制漏感是重头戏。先做好漏感,再说其余。漏感有多大?意味着能量传递损失多大,变换器效率损失有多大,钳位电路热损耗有多大。这都是额外的,其他变换器没有的。
    发表于 09-19 07:44

    51单片机的无线供电台灯电路图及程序设计

    本资源内容概要: 这是基于51单片机的无线供电台灯电路图及程序设计包含了电路图源文件(Altiumdesigner软件打开)、C语言程序代码(keil软件打开) 。 本资源适合人群:
    发表于 08-11 15:10 0次下载

    如何与PIC单片机建立PICKit3程序编写电路?

     在本文中,主要解释如何与PIC单片机建立PICKit3程序编写电路,以下图电路为例,组装在试验板上的程序编写电路是以下电路图的红色部分。
    的头像 发表于 07-10 11:19 1435次阅读
    如何与PIC<b class='flag-5'>单片机</b>建立PICKit3<b class='flag-5'>程序</b><b class='flag-5'>编写</b>电路?

    几种常见的单片机驱动程序设计模式

    单片机开发人员需要掌握的一项基本技能是,了解如何编写驱动程序。在嵌入式系统中,通常有两种类型的驱动程序单片机外围设备驱动
    的头像 发表于 07-10 11:09 3275次阅读
    几种常见的<b class='flag-5'>单片机</b>驱动<b class='flag-5'>程序设计</b>模式

    基于51单片机的串口测试程序设计资料源程序文件

    基于51单片机的串口测试程序设计资料源程序文件
    发表于 04-27 15:05 0次下载