微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 51单片机延时程序的简单研究

51单片机延时程序的简单研究

时间:11-19 来源:互联网 点击:

,这倒是的确可以延迟很长时间~~~但是毫无精度可言了。
  那么,用C到底能不能实现精确的延时呢?我把代码稍微改了一下:

void delay1(unsigned char i)
{
  while(i--);
}

因为根据经验,越简洁的C代码往往也能得出越简洁的机器代码。那这样结果如何呢?把它生成的汇编代码拿出来看一看就知道了。满怀希望的我按下了“Build target”键,结果打击是巨大的:

; FUNCTION _delay1 (BEGIN)
                      ; SOURCE LINE # 13
;---- Variable "i" assigned to Register "R7" ----
                      ; SOURCE LINE # 14
0000     ?C0004:
                      ; SOURCE LINE # 15
0000 AE07       MOV   R6,AR7
0002 1F        DEC   R7
0003 EE        MOV   A,R6
0004 70FA       JNZ   ?C0004
                      ; SOURCE LINE # 16
0006     ?C0006:
0006 22        RET  
       ; FUNCTION _delay1 (END)

虽说生成的代码跟用for语句是不大一样,不过我可以毫无疑问的说,这两种方法的效率是一样的。似乎到此为止了,因为我实在想不出来源程序还有什么简化的余地。看来我就要得出来这个结论了:“如果需要us级的延时精度,需要时用汇编语言。”但是真的是这样吗?我还是不甘心。因为我不相信大名鼎鼎的 Keil C 编译器居然连 djnz 都不会用???因为实际上程序体里只需要一句 loop: djnz r7, loop。近乎绝望之际(往往人在这种情况下确可以爆发出来,哦呵~~~),我随手改了一下:

void delay1(unsigned char i)
{
  while(--i);
}

心不在焉的编译,看源码:

; FUNCTION _delay1 (BEGIN)
                      ; SOURCE LINE # 13
;---- Variable "i" assigned to Register "R7" ----
                      ; SOURCE LINE # 14
0000     ?C0004:
                      ; SOURCE LINE # 15
0000 DFFE       DJNZ  R7,?C0004
                      ; SOURCE LINE # 16
0002     ?C0006:
0002 22        RET  
       ; FUNCTION _delay1 (END)

天~~~奇迹出现了......我想这个程序应该已经可以满足一般情况下的需要了。如果列个表格的话:
i  delay time/us
1  5
2  7
3  9
...

计算延时时间时,已经算上了调用函数的lcall语句所花的2个时钟周期的时间。

终于,结果已经明了了。只要合理的运用,C还是可以达到意想不到的效果。很多朋友抱怨C效率比汇编差了很多,其实如果对Keil C的编译原理有一个较深入的理解,是可以通过恰当的语法运用,让生成的C代码达到最优化。即使这看起来不大可能,但还是有一些简单的原则可循的:1.尽量使用unsigned型的数据结构。2.尽量使用char型,实在不够用再用int,然后才是long。3.如果有可能,不要用浮点型。4.使用简洁的代码,因为按照经验,简洁的C代码往往可以生成简洁的目标代码(虽说不是在所有的情况下都成立)。5...想不起来了,哦呵~~~

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top