单片机程序优化一

优化分类

程序优化分为:“代码格式优化"和"代码速度优化”

代码格式优化

  1. 程序的书写结构 :在书写程序时,对于一些while、for、do…while、if…else、switch…case等语句或这个语句的嵌套使用时,采用缩进格式进行书写。
  2. 标识符:在书写程序时,要遵守标识符的命名规则,不要使用如a,b,c,x,y,z最为变量这样的变量不够明了程序阅读起来不够清晰,应采用具有相关意义的英文缩写或者拼音作为标识符,如:count、number、work等等。
  3. 程序结构:在书写程序时,将某个功能的函数进行拆分化为若干个模块,不同模块完成不同的功能。单个模块之间的变量具有相对的独立性,尽量减少使用全局变量。但同时也不能太细否则会导致程序的执行效率降低(进入和退出一个函数时保护和恢复寄存器器会占用一些时间)。
  4. 定义常数:我们在使用常数时如果直接将他写入程序中则不利于维护程序,这是我们就可以采用预处理命令的方式来定义常数,及避免输入出错有利于维护。
  5. 减少判断语句:能够使用条件编译(ifdef)的地方就使用条件编译而不使用if语句,有利于减少编译生成的代码的长度。
  6. 表达式:对于使用宏定义的表达式或则对运算执行的优先顺序不太明确容易混淆的地方,应当采用圆括号明确指定优先顺序。
  7. 函数:在编写函数时应当对函数进行说明,若函数没有参数和返回值则应当加上void进行说明。
  8. 尽量减少全局变量,使用局部变量:全局变量放在数据存储器中,定义一个全局变量,MCU就少了一个数据存储器空间,如果定义了太多的全局变量,会导致编译器无法足够的内存可以分配。局部变量大多定位于MCU的内部寄存器中,在MCU中使用寄存器操作速度比数据存储器快,指令也更多更灵活,利于生成质量更高的代码,而且局部变量所占用的寄存器和数据存储器在不同的模块中可重复利用。
  9. 设定合适的编译程序选项:很多编译器都有几种不同的优化选项,在使用前应当理解各个优化选项的含义,理解所使用的优化选项在进行优化时那些参数会受到影响,那些参数不会受到影响,然后再选择适合自己的优化选项。

代码速度优化

  1. 选择合适的算法和数据结构 :应熟悉算法语言。将比较慢的顺序查找法用较快的二分查找法或乱序查找法代替,插入排序或冒泡排序法用快速排序、合并排序或根排序代替,这样可以大大提高程序执行的效率。
    选择一种合适的数据结构也很重要,比如在一堆随机存放的数据中使用了大量的插入和删除指令,比使用链表要快得多。数组与指针具有十分密切的关系,一般来说指针比较灵活简洁,而数组则比较直观,容易理解。对于大部分分的编译器,使用指针比使用数组生成的代码更短,执行效率更高。
    但是在Keil 中则相反,使用数组比使用的指针生成的代码更短。

  2. 使用尽量小的数据类型:能够使用字符型(char)定义的变量,就不要使用整型(int)变量来定义;能够使用整型变量定义的变量就不要用长整型(long int),能不使用浮点型(float)变量就不要使用浮点型变量。当然,在定义变量后不要超过变量的作用范围,如果超过变量的范围赋值,C 编译器并不报错,但程序运行结果却错了,而且这样的错误很难发现。

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

  4. 减少运算的强度:可以使用运算两小但功能相同的表达式替换原来复杂的表达式如求余运算

    a=a%8;

    可以改为:

    a=a&7;

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

    a=pow(a,2.0);

    可以改为:

    a = a* a;

    说明:在有内置硬件乘法器的单片机中(如51 系列),乘法运算比求平方运算快得多,因为浮点数的求平方是通过调用子程序来实现的,在自带硬件乘法器的AVR 单片机中,如ATMega163 中,乘法运算只需2 个时钟周期就可以完成。既使是在没有内置硬件乘法器的AVR单片机中,乘法运算的子程序比平方运算的子程序代码短,执行速度快。
    位移实现乘除法运算

    a = a * 4;
    b = b / 4;

    可以改为:

    a = a << 2;
    b = b >> 2;

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

    a = a *9;

    可以改为:

    a = (a<<3) + a;

  5. 循环:对于一些不需要循环变量参加运算的任务可以把它们放到循环外面,这里的任务包括表达式、函数的调用、指针运算、数组访问等,应该将没有必要执行多次的操作全部集合在一起,放到一个init 的初始化程序中进行。

  6. 查表:在程序中一般不进行非常复杂的运算,如浮点数的乘除及开方等,以及一些复杂的数学模型的插补运算,对这些即消耗时间又消费资源的运算,应尽量使用查表的方式,并且将数据表置于程序存储区。如果直接生成所需的表比较困难,也尽量在启动时先计算,然后在数据存储器中生成所需的表,后以在程序运行直接查表就可以了,减少了程序执行过程中重复计算的工作量。

  7. 其他:比如使用在线汇编及将字符串和一些常量保存在程序存储器中,均有利于优化。

应用https://www.cnblogs.com/tianqiang/p/9005538.html

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值