hzbitzyj
驱动牛犊
驱动牛犊
  • 注册日期2004-08-10
  • 最后登录2005-09-01
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2897回复:10

各位大虾帮忙看看这个延时函数是怎么回事?(C语言)

楼主#
更多 发布于:2004-09-27 09:47
我是学习C语言的新手!请各位大虾帮忙看看这个延时函数是怎么回事?
void  Delay(Uint Delay_Len)
{
 Uint i;
 while(Delay_Len--)
 {
   i=1000;
    WDTCTL=WDTPW+WDTCNTCL;
   while(i--);  //4000*0.25US=1ms
 }
}
在调用的时候 Delay(4500);//则表示45秒的延时时间.
请各位帮我讲解一下这个函数的原理!谢谢了!!
lbcat
驱动牛犊
驱动牛犊
  • 注册日期2002-03-19
  • 最后登录2007-09-27
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-09-27 13:19
  没什么特别,只是用循环来延时,里面加了看门狗防止死机………… :D
hzbitzyj
驱动牛犊
驱动牛犊
  • 注册日期2004-08-10
  • 最后登录2005-09-01
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-09-27 13:38
 没什么特别,只是用循环来延时,里面加了看门狗防止死机………… :D

谢谢楼上的回复!但是我不知道它哪个延时时间是怎么回事?
为什么4500就是45秒呀?这个延时间是怎么换算的呀?>
weikf
驱动牛犊
驱动牛犊
  • 注册日期2003-03-19
  • 最后登录2005-02-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-09-27 14:31
我是学习C语言的新手!请各位大虾帮忙看看这个延时函数是怎么回事?
void  Delay(Uint Delay_Len)
{
 Uint i;
 while(Delay_Len--)
 {
   i=1000;
    WDTCTL=WDTPW+WDTCNTCL;
   while(i--);  //4000*0.25US=1ms
 }
}
在调用的时候 Delay(4500);//则表示45秒的延时时间.
请各位帮我讲解一下这个函数的原理!谢谢了!!


while(i--) 代表延时1ms
    不清楚你的程序的执行环境,我想是while语句需要4个指令周期,一个指令周期需要0.25微秒。也请各位大虾指点
while(Delay_Len--) 代表延时时间,即4500*1ms=45秒



[编辑 -  9/27/04 by  weikf]
lbcat
驱动牛犊
驱动牛犊
  • 注册日期2002-03-19
  • 最后登录2007-09-27
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-09-28 08:50
  应该是
i=1000;
WDTCTL=WDTPW+WDTCNTCL;
while(i--);
这几条语句共用了4个指令周期,所以while(Delay_Len--)一次就延时1ms,不过怎么来45秒就…………是不是你看错了??是4.5秒吧??一般也不会用到这么长的延时啊??? :P
jsblcg
驱动牛犊
驱动牛犊
  • 注册日期2004-06-06
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-09-28 21:53
不知你这段代码运行于什么环境或芯片,C语言级别的代码一般不可能精确延时,因为同一条语句编译后的指令与编译器及其设置有关。例如上述语句中那个加法在一些编译器中可能会便完全优化掉。这种延时语句一般在DOS之类独占实模式环境下做大致延时。说白了,就是让芯片做些无用功浪费一点时间,具体浪费(延时)多少与编译器和芯片有关。

[编辑 -  9/28/04 by  jsblcg]
hzbitzyj
驱动牛犊
驱动牛犊
  • 注册日期2004-08-10
  • 最后登录2005-09-01
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-09-29 10:37
不知你这段代码运行于什么环境或芯片,C语言级别的代码一般不可能精确延时,因为同一条语句编译后的指令与编译器及其设置有关。例如上述语句中那个加法在一些编译器中可能会便完全优化掉。这种延时语句一般在DOS之类独占实模式环境下做大致延时。说白了,就是让芯片做些无用功浪费一点时间,具体浪费(延时)多少与编译器和芯片有关。

[编辑 -  9/28/04 by  jsblcg]


我用的是MSP430F149芯片,编译环境就是TI公司自带的IAR环境!这个程序是一位前辈写的,他在程序中很多需要延时的地方都调用了这个延时函数,根据不同的延时时间,而对Delay_len参数以1/100的比率来得到秒!真的好郁闷呀不懂!
xz-zhuo
驱动牛犊
驱动牛犊
  • 注册日期2004-09-29
  • 最后登录2005-03-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-09-29 11:16
好像是在用C51在编程.
chenfeng111
驱动牛犊
驱动牛犊
  • 注册日期2004-09-29
  • 最后登录2016-01-09
  • 粉丝1
  • 关注0
  • 积分8分
  • 威望55点
  • 贡献值0点
  • 好评度34点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-09-29 12:23
他的意思好像是第2个while循环一次为一条指令,占4个时钟周期,
每个时钟周期为0.25us,(cpu主频40MHZ).所以while(Delay_Len--)一次就延时1ms.
但对Delay_len参数以1/1000的比率来得到秒啊!怎么会是1/100呢?
jsblcg
驱动牛犊
驱动牛犊
  • 注册日期2004-06-06
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-09-29 17:26
我对C51和MSP430F149不熟,我只弄过x86上的东西,但道理是一样的。原理很简单,上面已经说过了,一般不需钻牛角尖(那段代码质量并不高,采用那种循环延时是权宜之计,精确延时应使用汇编接口或嵌入式汇编),如确实需要完全弄懂需要:
1 编译时输出汇编文件,一般编译器都有这个设置;
2 找到该函数对应的代码;
3 察看指令手册,得到相关指令(以上面的代码看,有跳转指令、逻辑比较指令、加法指令、内存操作指令)的执行时间(以时钟周期为单位);
4 计算这些指令执行的总时间
5 得到CPU的频率,然后就得到真正延时的时间了;

还有一个简单的法子,就是循环执行这段代码N次,得到总时间,然后除以N即可。建议看看微机原理或单片机编程一类的东西,循环延时操作是非常常见的(Windows 2000内核也使用这种方式进行微秒级延时)。

[编辑 -  9/29/04 by  jsblcg]

[编辑 -  9/29/04 by  jsblcg]

[编辑 -  9/29/04 by  jsblcg]

[编辑 -  9/29/04 by  jsblcg]
zmwk
驱动中牛
驱动中牛
  • 注册日期2001-05-15
  • 最后登录2009-04-05
  • 粉丝0
  • 关注0
  • 积分59分
  • 威望51点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-10-01 14:17
430芯片的时钟是复合时钟,可以有三种时钟模式:
RC振荡器
低频晶振
高频晶振

而且支持固件切换时钟模式。
所以,同样的代码在不同的时钟模式下延时不同!
如果你的程序对延时要求较高,可千万不能使用上述代码!
倒不是编译器的问题,而是RC振荡器随着温度的变化会有很大误差。
A strong man can save himself. A great man can save another.
游客

返回顶部