void Delay
{
unsigned char i, j;
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
} void Delay
{
unsigned char i, j;
i = 11;
j = 190;
while(i--)
{
while (--j);
}
}

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

int main(int argc, char *argv[])
{
unsigned char i, j;
int num = 0;
i = 11;
j = 190;
while(i--)
{
while (--j)
{
num++;
}
}
printf("num=%d\n",num);
return 0;
} int main(int argc, char *argv[])
{
unsigned char i, j;
int num = 0;
i = 11;
j = 190;
do
{
while (--j)
{
num++;
}
} while (--i);
printf("num=%d\n",num);
return 0;
}

但开头提到的两段代码,在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(); 的汇编代码。代码来源于网络,其实我也不懂。

/**** while 语句 pseudo-code ********/
while ( condition )
{
body of loop;
}
/****while 语句 assembly language *******/
while:
; code to set FLAGS based on condition
jxx endwhile
; body of loop
jmp while
endwhile:
/****while 语句 assembly language (end) ***/ /**** Do while 语句 pseudo-code ********/
do
{
body of loop;
}while ( condition )
/****Do while 语句 assembly language *******/
do_while:
; body of loop
; code to set FLAGS based on condition
jxx do_while
/****Do while 语句 assembly language (end) ***/

整理STC延时函数时遇到的玄学问题的更多相关文章

  1. Linux内核使用毫秒延时函数

    毫秒延时函数:mdelay() 微妙延时函数:ndelay() #ifndef mdelay #define mdelay(n) (/ (__builtin_constant_p(n) &&a ...

  2. 5-3 Linux内核计时、延时函数与内核定时器【转】

    转自:http://www.xuebuyuan.com/510594.html 5-3 Linux内核计时.延时函数与内核定时器 计时 1. 内核时钟 1.1   内核通过定时器(timer)中断来跟 ...

  3. STM32延时函数的四种方法

    单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us()和毫秒级delay_ms().本文基于STM32F207介绍4种不同方式实现的延时函数. 1.普通延时 这种延时方式应该是 ...

  4. 改进的延时函数Delay(使用MsgWaitForMultipleObjects等待消息或超时的到来)

    解决上一节中延时函数占CPU使用率(达50%)的第二种方法是利用消息机制,通过API函数MsgWaitForMultipleObjects等待消息或超时的到来,从而避免使用循环检测使CPU占用率过高. ...

  5. msp430学习笔记-时钟及延时函数

    引用:http://blog.chinaunix.net/uid-24343357-id-3271380.html MCLK默认时钟源是DCOCLK,SMCLK默认时钟源也是DCOCLK,DCOCLK ...

  6. 【CC2530强化实训02】普通延时函数实现按键的长按与短按

    [CC2530强化实训02]普通延时函数实现按键的长按与短按 [题目要求]      用一个按键实现单击与双击的功能已经是很多嵌入式产品的常用手法.使用定时器的间隔定时来计算按键按下的时间是通用的做法 ...

  7. Android 如何通过代码模拟按钮点击 延时函数

    View.performClick();   比如: private Button mButton01;    mButton01 = (Button)findViewById(R.id.myButt ...

  8. 延时函数出错,volatile一例

    莫名其妙的错误.使用Systick做的延时. 初始化是这样的: //SysTick配置 SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); if ...

  9. jquery 调用函数时加()和不加()的执行顺序是不同的

    编写JQUERY(3.0,向下兼容3.0)代码当我们调用一个函数时可以不加括号,但加括号与不加括号是不同的.如下代码: $(function(){ a(b);//先打印a 再打印 b a(b());/ ...

随机推荐

  1. HCNA Routing&Switching之DHCP服务

    前文我们了解了STP的端口状态.计时器以及端口状态切换和网络拓扑变化相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15140672.html:今天我们 ...

  2. 在Django中使用Channels功能

    前言:最近后台写游戏更新版本功能,简单就是前端发送更新请求,后端需要对很多台服务器进行更新和各种操作,本来想着实现不难,后来发现因为后端需要执行很长时间,前端返回报错,后端会执行完毕,但是前端先断开了 ...

  3. springboot项目出现Whitelabel Error Page的问题

    springboot项目出现Whitelabel Error Page的问题 大概就是这种情况,然而昨天还是没问题的,通过对比就发现,是自己手欠了 简单来说解决办法就是将springboot的启动项目 ...

  4. 深入理解-dl_runtime_resolve

    深入理解-dl_runtime_resolve 概要 目前大部分漏洞利用常包含两个阶段: 首先通过信息泄露获取程序内存布局 第二步才进行实际的漏洞利用 然而信息泄露的方法并不总是可行的,且获取的内存信 ...

  5. 常见web中间件漏洞(一)IIS漏洞

    web中间件作为web安全的重要一块,经常会有人问balabala,虽然有很多已经人尽皆知并且基本不再构成威胁了,但是还是有必要说一下,了解历史,了解我们从哪里来 鉴于内容实在是太多,本来打算一起写完 ...

  6. noip33

    T1 第一个猎人死的轮数等于在1号猎人之前死的猎人数+1,如果当前这个人没死,那么他死在一号猎人之前的概率为 \(\frac{w_{i}}{w_{1}+w_{i}}\),因为每死一个就会造成1的贡献, ...

  7. Windows安装Linux虚拟机(CentOS7)

    一.在电脑上安装虚拟机,百度搜索vmware,下载后傻瓜式安装即可. 二.CentOS下载,阿里云镜像:http://mirrors.aliyun.com/centos/7/isos/x86_64/. ...

  8. spring cloud 项目

    ### 项目需求 客户端:针对普通用户,用户登录.用户退出.菜品订购.我的订单. 后台管理系统:针对管理员,管理员登录.管理员退出.添加菜品.查询菜品.修改菜品.删除菜品.订单处理.添加用户.查询用户 ...

  9. git 的指定参考教程

    https://www.runoob.com/git/git-create-repository.html

  10. 十:JavaWeb中的监听器(一)

    2.1.基本概念 JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext, HttpSession和 ServletRequest等域 ...