网站大量收购独家精品文档,联系QQ:2885784924

51单片机程序优化.doc

  1. 1、本文档共12页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
51单片机程序优化

?????????????程序优化 ????由于单片机的性能同电脑的性能是天渊之别的,无论从空间资源上、内存资源、工作频率,都是无法 与之比较的。PC?机编程基本上不用考虑空间的占用、内存的占用的问题,最终目的就是实现功能就可以了。 对于单片机来说就截然不同了,一般的单片机的Flash?和Ram?的资源是以KB?来衡量的,可想而知,单片 机的资源是少得可怜,为此我们必须想法设法榨尽其所有资源,将它的性能发挥到最佳,程序设计时必须 遵循以下几点进行优化: 1.?使用尽量小的数据类型 能够使用字符型(char)定义的变量,就不要使用整型(int)变量来定义;能够使用整型变量定义的变 量就不要用长整型(long?int),能不使用浮点型(float)变量就不要使用浮点型变量。当然,在定义变 量后不要超过变量的作用范围,如果超过变量的范围赋值,C?编译器并不报错,但程序运行结果却错了, 而且这样的错误很难发现。 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=M3 N=M/8?可以改为N=M3 说明:通常如果需要乘以或除以2n,都可以用移位的方法代替。如果乘以2n,都可以生成左移 的代码,而乘以其它的整数或除以任何数,均调用乘除法子程序。用移位的方法得到代码比调用乘除法子 程序生成的代码效率高。实际上,只要是乘以或除以一个整数,均可以用移位的方法得到结果。如N=M*9 可以改为N=(M3)+M; (4)?自加自减的区别 例如我们平时使用的延时函数都是通过采用自加的方式来实现。 void?DelayNms(UINT16?t) { UINT16?i,j; for(i=0;it;i++) for(j=0;i1000;j++) } 可以改为 void?DelayNms(UINT16?t) { UINT16?i,j; for(i=t;i=0;i--) for(j=1000;i=0;j--) } 说明:两个函数的延时效果相似,但几乎所有的C?编译对后一种函数生成的代码均比前一种代码少1~3 个字节,因为几乎所有的MCU?均有为0?转移的指令,采用后一种方式能够生成这类指令。 4.?while?与do...while?的区别 void?DelayNus(UINT16?t) { while(t--) { NOP(); } } 可以改为 void?DelayNus(UINT16?t) { do { NOP(); }while(--t) } 说明:使用do…while?循环编译后生成的代码的长度短于while?循环。 5.?register?关键字 void?UARTPrintfString(INT8?*str) { while(*str??str) { UARTSendByte(*str++) } } 可以改为 void?UARTPrintfString(INT8?*str) { register?INT8?*pstr=str; while(*pstr??pstr) { UARTSendByte(*pstr++) } } 说明:在声明局部变量的时候可以使用register?关键字。这就使得编译器把变量放入一个多用途的寄存 器中,而不是在堆栈中,合理使用这种方法可以提高执行速度。函数调用越是频繁,越是可能提高代码的 速度,注意register?关键字只是建议编译器而已。 6.?volatile?关键字 volatile?总是与优化有关,编译器有一种技术叫做数据流分析,分析程序中的变量在哪里赋值、在 哪里使用、在哪里失效,分析结果可以用于常量合并,常量传播等

文档评论(0)

2017ll + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档