整理STC延时函数时遇到的玄学问题
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延时函数时遇到的玄学问题的更多相关文章
- Linux内核使用毫秒延时函数
毫秒延时函数:mdelay() 微妙延时函数:ndelay() #ifndef mdelay #define mdelay(n) (/ (__builtin_constant_p(n) &&a ...
- 5-3 Linux内核计时、延时函数与内核定时器【转】
转自:http://www.xuebuyuan.com/510594.html 5-3 Linux内核计时.延时函数与内核定时器 计时 1. 内核时钟 1.1 内核通过定时器(timer)中断来跟 ...
- STM32延时函数的四种方法
单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us()和毫秒级delay_ms().本文基于STM32F207介绍4种不同方式实现的延时函数. 1.普通延时 这种延时方式应该是 ...
- 改进的延时函数Delay(使用MsgWaitForMultipleObjects等待消息或超时的到来)
解决上一节中延时函数占CPU使用率(达50%)的第二种方法是利用消息机制,通过API函数MsgWaitForMultipleObjects等待消息或超时的到来,从而避免使用循环检测使CPU占用率过高. ...
- msp430学习笔记-时钟及延时函数
引用:http://blog.chinaunix.net/uid-24343357-id-3271380.html MCLK默认时钟源是DCOCLK,SMCLK默认时钟源也是DCOCLK,DCOCLK ...
- 【CC2530强化实训02】普通延时函数实现按键的长按与短按
[CC2530强化实训02]普通延时函数实现按键的长按与短按 [题目要求] 用一个按键实现单击与双击的功能已经是很多嵌入式产品的常用手法.使用定时器的间隔定时来计算按键按下的时间是通用的做法 ...
- Android 如何通过代码模拟按钮点击 延时函数
View.performClick(); 比如: private Button mButton01; mButton01 = (Button)findViewById(R.id.myButt ...
- 延时函数出错,volatile一例
莫名其妙的错误.使用Systick做的延时. 初始化是这样的: //SysTick配置 SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); if ...
- jquery 调用函数时加()和不加()的执行顺序是不同的
编写JQUERY(3.0,向下兼容3.0)代码当我们调用一个函数时可以不加括号,但加括号与不加括号是不同的.如下代码: $(function(){ a(b);//先打印a 再打印 b a(b());/ ...
随机推荐
- SunOS与Solaris系统的对应关系
下文绝大部分译自维基百科Solaris词条的"历史"部分: http://en.wikipedia.org/wiki/Solaris_(operating_system)#Hist ...
- JavaScript学习07(jQuery)
jQuery 什么是JQuery jQuery 由 John Resig 于 2006 年创建.它旨在处理浏览器不兼容性并简化 HTML DOM 操作.事件处理.动画和 Ajax. 十多年来,jQue ...
- @Valid和@Validated 区别
Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303规范,是标准JSR-303的一个变种),javax提供了@Valid(标准JSR- ...
- SpringBoot开发二十四-Redis入门以及Spring整合Redis
需求介绍 安装 Redis,熟悉 Redis 的命令以及整合Redis,在Spring 中使用Redis. 代码实现 Redis 内置了 16 个库,索引是 0-15 ,默认选择第 0 个 Redis ...
- 从MySQL大量数据清洗到TiBD说起
从MySQL大量数据清洗到TiBD说起 一.业务场景: 公司主要做的业务是类似贝壳的二手房租售,公司数据库存了上亿级别的房源数据,之前的数据库使用的是 mysql,后面需要将mysql数据库切换成了 ...
- noip 模拟4
咕 题都改不完怎么可能有空写题解啊啊啊
- swiper在一个页面多个轮播图
<script> var swiper = new Swiper('.swiper-container1', { spaceBetween: 30, centeredSlides: tru ...
- UDP与TCP的对比
参考网址:https://blog.csdn.net/m0_38121874/article/details/82914634 1.报头(1)TCP协议报头TCP指传输控制协议,其报头格式如下: TC ...
- ASP.NET Core教程:在ASP.NET Core中使用HttPClient调用WebService
一.前言 在以前的一篇文章中,曾经讲述过如何在ASP.NET Core中调用WebService.但是那种方式是通过静态引用的方式去调用的,如果是在生产环境中,肯定不能使用这种方式去调用,幸运的是微软 ...
- .net core api 对于FromBody的参数验证
前言 在framework的mvc中,经常会使用 Model.State . ModelState.IsValid 配合着特性进行参数验证,通过这种方式可以降低controller的复杂度,使用方便. ...