找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2403|回复: 2
打印 上一主题 下一主题
收起左侧

整理STC单片机延时函数时遇到的玄学问题

[复制链接]
跳转到指定楼层
楼主
  1. void Delay  

  2. {  

  3.     unsigned char i, j;  

  4.     i = 11;  

  5.     j = 190;  

  6.     do  

  7.     {  

  8.         while (--j);  

  9.     } while (--i);  

  10. }  

  11.   

  12.   

  13.   

  14. void Delay  

  15. {  

  16.     unsigned char i, j;  

  17.     i = 11;  

  18.     j = 190;  

  19.     while(i--)  

  20.     {  

  21.         while (--j);  

  22.     }  

  23. }  



复制代码


以上两段代码,第一段为STCISP提供的1ms延时函数,第二段为改编版。按照个人对C语言的理解,这两种写法所得到的结果应该是一致的,最起码在Dev-C++上以下两端代码输出结果相同,均为2739:


  1. int main(int argc, char *argv[])

  2. {

  3.     unsigned char i, j;

  4.     int num = 0;

  5.     i = 11;

  6.     j = 190;

  7.     while(i--)

  8.     {

  9.         while (--j)

  10.         {

  11.             num++;

  12.         }

  13.     }

  14.     printf("num=%d\n",num);

  15.     return 0;

  16. }







  17. int main(int argc, char *argv[])

  18. {

  19.     unsigned char i, j;

  20.     int num = 0;

  21.     i = 11;

  22.     j = 190;

  23.     do

  24.     {

  25.         while (--j)

  26.         {

  27.             num++;

  28.         }

  29.     } while (--i);

  30.     printf("num=%d\n",num);

  31.     return 0;

  32. }

复制代码



但开头提到的两段代码,在STC15F104(11.0592M)单片机上跑起来其延时结果却截然不同。实测在预设延时500ms时(即重复运行上述函数500次),第一段代码比较符合实际,第二段要比第一段要慢一倍左右,即将第二段代码中的11改为6后可以得到大体相同的延时结果。

造成这种现象的原因,到现在也没搞清楚,我发表在开源电子网的提问贴截止到目前也没有收到合理的解释。我不打算再耗下去,只能强行解释一波了:

造成延时结果不同的原因是单片机在执行 while()...; 和 do...while(); 时的效率不同。





这解释很有道理,因为在 while()...; 和 do...while(); 在汇编代码中的长度的确相差一倍左右。但仍不能很好解释延时结果相差之大。因为无论是 while()...; 和 do...while(); ,在延时函数中仅仅执行了11次而已,真正起决定性作用的应该是中间那段 while (--j); ,在如此大基数的循环下, while()...; 和 do...while();  相差的那点时间应该显得微不足道才对啊。

算了,这件事告一段落了,不打算再在这上面浪费时间了。下面附上 while()...; 和 do...while(); 的汇编代码。代码来源于网络,其实我也不懂。


  1. /**** while 语句 pseudo-code ********/

  2. while ( condition )

  3. {  

  4.   body of loop;

  5. }

  6. /****while 语句 assembly language *******/

  7. while:

  8. ; code to set FLAGS based on condition

  9. jxx   endwhile

  10. ; body of loop

  11. jmp while

  12. endwhile:

  13. /****while 语句 assembly language (end) ***/  



  14. /**** Do while 语句 pseudo-code ********/

  15. do

  16. {

  17.   body of loop;

  18. }while ( condition )

  19. /****Do while 语句 assembly language *******/

  20. do_while:

  21. ; body of loop

  22. ; code to set FLAGS based on condition

  23. jxx   do_while

  24. /****Do while 语句 assembly language (end) ***/
复制代码





评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:462827 发表于 2019-4-29 08:30 | 只看该作者
楼主提到Dev-C++,你这是在PC上编译且运行的吧。

你得在51上把那两个delay调试转成汇编,认认真真计算它们的具体所用指令周期,相信你会有所发现的。
回复

使用道具 举报

板凳
ID:522450 发表于 2019-4-29 09:56 | 只看该作者
摘录了一本书中的内容,应该可以很好解释你的问题,至少,是你的代码产生差别的主要原因,你找的原因可能有影响,但应该不是主因。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表