delayms(1)怎么是延时了1ms呢?不应该是2*114us么?

[复制链接]
9277|19
 楼主| doublers 发表于 2010-6-26 22:08 | 显示全部楼层 |阅读模式
/**********************************************************
  延时函数
**********************************************************/
void delayms(unsigned int ms)
{
  unsigned char k;
  while(ms--)
  {
    for(k = 0; k < 114; k++);
  }
}

请问:delayms(1)怎么是延时了1ms呢?不应该是2*114us么?
danpianjizui 发表于 2010-6-26 22:09 | 显示全部楼层
你可以在keil中去调试,就能看出延时时间
原野之狼 发表于 2010-6-27 00:03 | 显示全部楼层
这种延时只是粗略的延时 更好的方式可以采用库函数来延时
zjswuyunbo 发表于 2010-6-27 00:27 | 显示全部楼层
有库函数?
maxking 发表于 2010-6-27 08:41 | 显示全部楼层
51没有。AVR有。
machunshui 发表于 2010-6-27 08:44 | 显示全部楼层
用定时器
invinliang 发表于 2010-6-27 08:45 | 显示全部楼层
...这还要看你晶振多少啊,这延时只是个大概啊。要准确延时就用定时器
 楼主| doublers 发表于 2010-6-27 09:30 | 显示全部楼层
晶振是12M的
一条for语句执行时间是2微秒,114次不应该是228微秒么?
但实际执行后确实1000微秒
为什么呢?
 楼主| doublers 发表于 2010-6-27 09:31 | 显示全部楼层
keil软件中能看到单条语句执行的时间么?
我原来用的万利的仿真器,很方便,可以看到单条语句执行的时间
在keil中能看到单条语句的执行时间么?
南湖游子 发表于 2010-6-27 09:32 | 显示全部楼层
你在keil中进行调试就知道怎么延时了:
  将你的延时程序改成如下

        在keil中利用视图中的反汇编,会出现如下:
        其中的汇编CLR指令,MOV,INC都是消耗一个机器周期,CJNE是两个机器周期,根据循环条件,第三行和第四行要执行114次,所以此延时程序消耗的机器周期数为
        N=1+1+(1+2)*114;由此可以推出语句(for(k = 0; k < n; k++);)所消耗的机器周期数为N=3*n+2,近似于N=3*n;
        二重循环时:for(k = 0; k < m; k++);
                      for(k = 0; k < n; k++);
        所消耗的机器周期数近似:N=3*m*n;当单片机的晶振频率为12M时,机器周期就是1Us所以你要延时多少时间直接用以上公式算就行,如m=100,n=200时,就延时了60000us,即60ms'
南湖游子 发表于 2010-6-27 09:44 | 显示全部楼层

RE: delayms(1)怎么是延时了1ms呢?不应该是2*114us么?

你在keil中进行调试就知道怎么延时了:
  将你的延时程序改成如下


keil中利用视图中的反汇编,会出现如下:


其中的汇编CLR指令,MOVINC都是消耗一个机器周期,CJNE是两个机器周期,根据循环条件,第三行和第四行要执行114次,所以此延时程序消耗的机器周期数为

N=1+1+1+2*114;由此可以推出语句(for(k = 0; k < n; k++);)所消耗的机器周期数为N=3*n+2,近似于N=3*n

二重循环时:for(k = 0; k < m; k++);

              for(k = 0; k < n; k++);

所消耗的机器周期数近似:N=3*m*n;当单片机的晶振频率为12M时,机器周期就是1Us所以你要延时多少时间直接用以上公式算就行,如m=100n=200时,就延时了60000us,即60ms'

以上是我以前学习中从资料上看到的分析方法,用keil给你截图下来解释了一下,希望对你有用!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| doublers 发表于 2010-6-27 09:47 | 显示全部楼层
致  南湖游子

请看一下这个小的延时函数
/*************延时函数*************/

void delay(void)
{
  unsigned char i,j,k;

  for(k=10;k>0;k--)

  for(j=10;j>0;j--)

  for(i=100;i>0;i--);
}

//注:1、延时时间大约为i*j*k*2us。
//    2、i取值越大,k取值越小时间越准。
//    3、晶振为12M。

这是我当时实践过的,误差不是很大
但如果像你的公式好像就差的太大了
 楼主| doublers 发表于 2010-6-27 09:58 | 显示全部楼层
/**********************************************************
  延时函数
**********************************************************/
void delayms(unsigned int ms)
{
  unsigned char k;
  while(ms--)
  {
    for(k = 0; k < 114; k++);
  }
}

给大家推荐这个简单实用的延时函数
delay(1)确实是延时1ms,但是却算不来怎么得来的
,根据南湖游子的公式应该是3*114+2=344us
hz100 发表于 2010-6-27 10:17 | 显示全部楼层
懂点汇编是好的
yangxiaolongqq 发表于 2010-6-30 22:58 | 显示全部楼层
围观中。
lfb112 发表于 2010-6-30 23:14 | 显示全部楼层
看keil反汇编代码计算吧
xd54622 发表于 2011-7-26 10:48 | 显示全部楼层
标记一下吧
邪恶猛男 发表于 2011-7-26 14:57 | 显示全部楼层
楼主对汇编一点常识都无,for在12M下怎么才2uS呢 **中for 是8个机器周期 8*114=912 还有产生的其他机器周期加起来将近1000个
mmcjackxie 发表于 2011-7-26 17:52 | 显示全部楼层
你那个是要看步长的。。而且这种定时很不准确,最好是直接用定时器来写程序
毅如靳往 发表于 2011-7-26 23:11 | 显示全部楼层
有的时候算的机器周期和实际指令运行时间是不相等的,尤其c需要转换成汇编的时候
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

37

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部