单片机的精确延时问题,请各位作答!

byahui   2007-5-18 09:35 楼主
最近学习单片机,因为要用到红外解码,所以对单片机的延时要求特别高,找了很久,问了许多人,看了很多代码,到处都是用for循环来进行延时(用c51的c语言),好好想了想,这样作只能在对延时精度要求不高的场合才能随便用用,但要是在有其他中断或其他干扰时这种做法就很不准确,所以我想了两种方法:

1.这种方法最主要了:定时器的初值,也就是对TH1,TL1(T0也是如此)重装初值,这种方法需要先计算(一定要注意波特率和PCON的初始化)。

2.就是用汇编来实现,我先贴一段汇编的延时子程序大家看看:

;1s的延时程序

delay1s: mov r1,#50

    del0:mov r2,#100

    del1:mov r3,$

          djne r2,del1

         djnz r1,del0

  ret

抱歉得很,没有注释,因为我也不太明白这种延时是不是很准确,这是我在电子制作这本杂志上看到的,当时如获至宝抄了下来,不过在网上看了很多汇编程序都是这样,不过要是在C语言上使用还是要内嵌这段汇编代码。

所以我想问问各位要用到精确延时时究竟该怎么做?

回复评论 (32)

哦对了,上面汇编代码有点问题。具体是这样的:
delay1s:  mov r1,#50

    del0: mov r2,#100

    del1: mov r3,#100
          djnz r3,$

          djnz r2,del1

          djnz r1,del0

  ret
点赞  2007-5-18 09:38
这种方法应该还是比较精确的
它是用每一条语句运行的时间,时钟每跳一次的时间来算的
点赞  2007-5-18 10:37
谢谢
点赞  2007-5-18 11:12
用循环还是会受中断干扰,用定时器是较可靠的,但软件复杂些
点赞  2007-5-19 20:41
同意楼上的意见,用软件循环延时在关中断的情况下可以实现精确定时,因为每条指令的执行时间是已知的。用定时器来实现一般较为精确,但是涉及到中断和主程序的协调和同步问题,程序结构较为复杂。
点赞  2007-5-23 14:29
用定时器吧...不过我不懂
点赞  2007-5-23 14:36
你的汇编代码主要是应用了DJNZ的2个时钟周期,靠这2个时钟周期定时.在KEIL下C语言也可以实现,具体代码我没有,你可以一边调试(反汇编),一边测试.KEIL是很强大的,它的优化功能做的很好.在"中山单片机"有人专门写了个贴子是关于用c语言写的延时,精确度较高.



调试是一种很好的方法
点赞  2007-5-24 18:30
上述汇编代码其实也是通过循环来延时,只不过汇编指令的时间比较精确。不过不同的晶振频率对应于不同循环计数。用定时器的话,要使用一个定时器,并且禁止定时器中断。如果单片机有多余的定时器的话,可以优先考虑这种方法。
点赞  2007-5-29 18:59
最近看了看书有点明白了上面的汇编延时原理是这样的,一个mov语句是耗时2个周期,例如我经常用的11.0592的晶振,一个单片机周期约1us,那么一个mov语句为2us,djnz r3,$就是在本行不停地作减1,r3为100,那就要在本句做100次执行,明白这两句话的含义上面的延时时间就好算了,具体为:50*(2+2+100*2+(2*100+2)*100)+2=1020200us大约为1s的延时,不知我算得对不对?
点赞  2007-5-30 16:24
精确的话就用定时器啦
我只会C语言的,还没学好汇编的
所以就给个C的吧
void time() interrupt ?(0~4) //中断函数 ?表示中断号,0到4分别为外部中断,定时器中断,串口中断
{TH?=0x??;//重装初值
TL?=0x??;
}
main()
{
TMOD=0x??; //定时器工作模式
TH0=0x??;  //装初值
TL0=0x??;
TR0=1;    //开定时器 使之工作
EA=1;    //开所有中断
ET?=1; //开定时器中断
for(;;){;}//无限循环 等待中断
}
点赞  2008-10-7 10:02
定时器延时精确
点赞  2008-10-10 10:27
同意定时器
点赞  2008-10-30 21:12
定时器是最佳选择
点赞  2008-10-30 22:40
定时器也不是很准确,也在找更好的方法。
点赞  2008-10-31 10:48
本身晶振也是存在误差的。
点赞  2008-11-4 13:33
写好延时函数后,用定时器测试一下 看看具体是多长时间哈
点赞  2008-11-4 15:11
每条语句执行的时间是一定的   你把 tr1  th1 重新装初始值     delay函数的延迟时间 一般情况还是很精确的在毫秒级内
点赞  2008-11-4 21:39
用定时器还是比较好的
点赞  2008-11-9 00:57
其实红外协议根本不用那么精确的延时,可以在一段延时之后判断i/o口的方法做。
我在3.8M定时器时钟下都能正常解码。
点赞  2010-1-3 12:43
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复