c51中如何实现1ms到10s范围内的延时?

[复制链接]
11141|29
 楼主| sandisker 发表于 2008-6-6 23:39 | 显示全部楼层 |阅读模式
能不能用定时器做一个1ms的延时程序,然后通过循环调用实现长时间(10s)延时。
还是分成不同的数量级的延时比如1ms-100ms,1s-10s;各自编制响应的延时程序。
diannaoza 发表于 2008-6-7 03:15 | 显示全部楼层

1ms-100ms,1s-10s

1ms标志
10ms标志
100ms标志
;;;;;;;;;;;;;;;
1s标志
10s标志
1分钟标志
1小时标志
;;
12小时标志
24小时标志
;;
31天标志
1年标志
10年标志
100年标志
1000年标志
10000年标志
呆板书生 发表于 2008-6-7 06:01 | 显示全部楼层

一个毫秒级别的中断

在中断程序中,可以这样写

if (++ms ==1000){
  ms = 0;
  if (++sendcond == 60){
    sendcond = 0;
    ...
  }
}

有了这个时间坐标系,要延时的时候就很方面
hyg1984 发表于 2008-6-7 11:41 | 显示全部楼层

楼上的,太麻烦了吧

void delay(unsigned int z)
{
     unsigned int i,j;
     for(i=z;i>0;i--)
         for(j=114;j>0;j--); 
}
写一子函数,晶振为11.0592M,想延时1ms就delay(1),想延时1s就delay(1000),简单方便.
 楼主| sandisker 发表于 2008-6-7 13:22 | 显示全部楼层

四楼的方法比较容易理解

我用的是12Mhz的晶振,
for循环的执行周期如何计算?
桂电飞天鼠 发表于 2008-6-7 13:41 | 显示全部楼层

四楼的只能拿来学习或某些特定场合可以用

没有太大的实际意义。
三楼的方法才是既能产生需要的时标,也能够让系统做其它事的做法。
yewuyi 发表于 2008-6-7 14:18 | 显示全部楼层

~~

呆板书生 发表于 2008-6-7 06:01 侃单片机 ←返回版面    

3楼: 一个毫秒级别的中断 

在中断程序中,可以这样写

if (++ms ==1000){
  ms = 0;
  if (++sendcond == 60){
    sendcond = 0;
    ...
  }
}

有了这个时间坐标系,要延时的时候就很方面
 
 
这么写合理:
if(ms>=1000){
            ms=0;
            ...
            }
else{
     ms++;
    }
xwj 发表于 2008-6-7 15:25 | 显示全部楼层

3楼正解,4楼纯属误到新人的教学方法

希望LZ仔细去想想3楼的方法,明白后你会更上一个层次的





7楼的yewuyi,虽然你的方法有千分之一的机会可以少执行个指令,但你的1000mS会变成1001mS哦
理解上容易出误差哦
yewuyi 发表于 2008-6-7 15:55 | 显示全部楼层

呵呵,是的,我那么写只是想告诉初学者

最好把if ,else写全了,成对出现,养成好习惯,并尽量用简单易懂的方式写程序。


另俺一般规定那样的情况下,必须要用>或者>=做为判断式,尽量不用那位兄弟写的++ms ==1000判断方式。


呆板书生 发表于 2008-6-7 17:21 | 显示全部楼层

yewuyi的是标准写法

在实战中,我通常会采用yewuyi的写法,

其实没有XWJ的担心,反而更安全。

因为当弹片机弹飞后,写成 ++ms >= 1000; 就很显作用,

还有,变量名也要规范化,

不过对于初学者来说,说得太多东西,他们反而不容易明白
huangqi412 发表于 2008-6-7 17:27 | 显示全部楼层

还是规范点好

yewuyi 发表于 2008-6-7 17:38 | 显示全部楼层

呵呵,这个书生不知道又是谁的马甲?

看着特别像马甲……
xwj 发表于 2008-6-7 18:05 | 显示全部楼层

用>或者>=做为判断式是对的,加else也是对的,但他的程序有B

不知10楼的书生看出了没有啊?
hyg1984 发表于 2008-6-7 21:09 | 显示全部楼层

呵呵~~看错,不好意思

我(4楼),上面用的是软件延时,12MHZ的软件延时可以取j=100;如果频繁的调用是很占CPU的,我看漏了LZ说的是用定时器,不好意思,如果用定时器延时,可以这样写,详细点:
#include<reg52.h>
unsigned int count;
void main()
{   
    TMOD=0x01;
    TH0=(65536-10000)/256;//1ms定时
    TL0=(65536-10000)%256;
    EA=1;
    ET0=1;
    TR0=1;   
    while(1)
    {
        if(count==1)
        {1ms的响应程序}        //如果程序小的话,可以在中断中加的
        else if(count==10)
        {10ms的响应程序}
        -----
        -----类似的可以增加
        else
        {count=0;}//返回
    }
}

void T0_srv(void) interrupt 1  //定时中断函数
{
    TH0=(65536-1000)/256;//1ms定时
    TL0=(65536-1000)%256;
    count++;
}

xwj 发表于 2008-6-7 21:29 | 显示全部楼层

呵呵,LS,8位机乱用16位的变量不是好的主意哦

而且,你的程序根本就是错的,没法正常工作哦

仔细想想吧...
 楼主| sandisker 发表于 2008-6-7 21:39 | 显示全部楼层

7楼的语句很精练。

就语句本身可以理解,只是不清楚各语句的执行时间长短。
我的理解如下:

使用时给定ms和second的值,这种结构就可以实现相应的时间的延时。
这与四楼方法在原理上也是通过软件延时的吧,只是语法结构不同,计时的精度上有差异?
还有将其编制为通用的延时子程序的话,是不是也有可能出现意外中断导致延时计时不准的问题。

感谢大伙指点!
原野之狼 发表于 2008-6-7 22:06 | 显示全部楼层

15楼老X说得对.

xwj 发表于 2008-6-7 22:10 | 显示全部楼层

LS,7楼的不是“计时的精度上有差异”,而是数值错了

从开始到判断到溢出,其实已经经过了1001次

程序是死的,指挥照着人预定好的想法去动,不会带来精度误差,
但人的想法不一定是严谨的,所以才会有BUG的存在


7楼的方法是对的,并且是规范的,但写程序时出了点疏忽罢了


我想,他们的程序应该都不算难以理解吧?
那就请在评价千多点思考,或用大脑仿真一下,不清楚可以自己去思考、试验,而不应该是盲目的猜测哦...
huangqi412 发表于 2008-6-7 22:45 | 显示全部楼层

老x的砖头真多......

xwj 发表于 2008-6-7 23:07 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

44

主题

97

帖子

1

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