我们这些程序员很幸运,因为Microsoft公司的专家认为建立一个独立于硬件的延时器是一个好主意。显然,这样做的目的在于,无论程序运行在什么速度的计算机上,都可产生一段固定的延迟时间。下面的程序说明了如何在DOS中建立一个延时器:
#
include
<stdio
h>
#
include
%dos
h>
#
include
<stdlib
h>
void
main(int
argc,char
argv)
{
union
REGS
regs:
unsiged
long
delay;
delay
=
atoI(argv[1])
;
/
assume
that
there
is
an
argument
/
/
multiply
by
1
for
microsecond-granularity
delay
/
/
multiply
by
1000
for
millisecond-granularity
delay
/
/
multiply
by
1000000
for
second-granularity
delay
/
delay
=1000000;
regs
x
ax
=
0x8600
;
regs
x
cx=
(unsigned
int
)((delay
&
0xFFFF0000L)>>16)
;
regs
x
dx
=
(unsigned
int
)
(delay
&
0xFFFF)
int86
(0x15,
®s,
®s)
;
}
上例通过DOS中断15H的86H功能来实现延时,延迟时间以微秒为单位,因此,上述延时程序认为你可能要使用一个非常大的数字,于是它分别用CX和DX寄存器来接受延时值的高16位和低16位。上述延时程序最多可以延时49.亿微妙---大约等于12小时。
上例假设延时值以微秒为单位,它把延时值乘以一百万,因此在命令行中可以输入以秒为单位的延时值。例如,“delay
10”命令将产生10秒的延时。
单片机编程时延时程序其实就是一些循环指令组成的集合。比如:
DELAY:MOV R2,#248 ;本条指令1T执行1次
DJNZ R2,$ ;本条指令2T执行248次
NOP ;本条指令1T执行1次
RET ;本条指令2T执行1次
所以延时时间为:1+2482+1+2=500T,如果晶振是12M的话,延时500us
DELAY。
指令用来延时工业机器人的运动,最小延时时间为2,单位[ms]。程序首先执行MOVE指令,控制工业机器人ROBOT从当前点移动到目标点P2,等到工业机器人移动到P2点后开始执行DELAY指令,2ms后打印输出“ROBOTISSTOPPED”。
SLEEP指令的作用是延时程序(任务)的执行,最短延时时间为1,单位[ms]。Move指令开始执行的同时,SLEEP指令开始执行,我们假设MOVE指令执行完(工业机器人运动到P2点)的时间要200ms,那么,MOVE指令执行了100ms后,D_OUT[25]就会输出为ON,此时工业机器人还未到P2点。然后等到工业机器人运动到P2点后,整个程序执行完毕。
你写的这个延时程序的反汇编代码如下:(使用keil
3反汇编),使用12MHZ晶振,每个机器周期占用1us,那么只循环一次总共用时为18us
C:0x0800
EF
MOV
A,R7
C:0x0801
4E
ORL
A,R6
C:0x0802
6009
JZ
C:080D
C:0x0804
00
NOP
C:0x0805
00
NOP
C:0x0806
EF
MOV
A,R7
C:0x0807
1F
DEC
R7
C:0x0808
70F6
JNZ
delay(C:0800)
C:0x080A
1E
DEC
R6
C:0x080B
80F3
SJMP
delay(C:0800)
C:0x080D
22
RET
原理:只是执行一些所谓的“无实际意义的指令”,如缩放或执行一个int自加,简单地说,就像高中数学中的“乘法原理”一样,很容易迅速增加上面提到的“无意义指令”的数量
关于大小的值:如果是在C语言中,该值不仅与水晶振动、单片机本身的速度,但也与C的编译器,所以,虽然这个值可以精确计算,但大多数情况下,程序员是经验值。
当然,如果你在汇编中编程,情况就不同了,因为每条指令使用一定数量的机器周期,你当然可以根据所有指令使用的总时间来计算特定延迟的总时间。
扩展资料:
定义延迟XMS毫秒的延迟函数
Voiddelay(unsignedintXMS)//XMS表示需要延迟的毫秒数
{
无符号intx,y;
For(x=XMS;X0;X-)
For(y=110;Y”0;Y-);
}
使用:
VoidDelay10us(ucharMs)
{
Uchar数据我;
(;女士“0;------Ms)
对于(I = 26)我> 0;我-);
}
I=[(延迟值-1.75)*12/ms-15]/4
自己编。。。。 精确到1微秒没有意义
Keil C51程序设计中几种精确延时方法1
0
推荐
摘要
实际的单片机应用系统开发过程中,由于程序功能的需要,经常编写各种延时程序,延时时间从数微秒到数秒不等,对于许多C51开发者特别是初学者编制非常精确的延时程序有一定难度。本文从实际应用出发,讨论几种实用的编制精确延时程序和计算程序执行时间的方法,并给出各种方法使用的详细步骤,以便读者能够很好地掌握理解。 (注:应文章版副受限制,将部分代码省略,如要可发邮件索取:panjianping66@163com
引言
单片机因具有体积小、功能强、成本低以及便于实现分布式控制而有非常广泛的应用领域[1]。单片机开发者在编制各种应用程序时经常会遇到实现精确延时的问题,比如按键去抖、数据传输等 *** 作都要在程序中插入一段或几段延时,时间从几十微秒到几秒。有时还要求有很高的精度,如使用单总线芯片DS18B20时,允许误差范围在十几微秒以内[2],否则,芯片无法工作。用51汇编语言写程序时,这种问题很容易得到解决,而目前开发嵌入式系统软件的主流工具为C语言,用C51写延时程序时需要一些技巧[3]。因此,在多年单片机开发经验的基础上,介绍几种实用的编制精确延时程序和计算程序执行时间的方法。
实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。
1 使用定时器/计数器实现精确延时
单片机系统一般常选用11059 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达216=65 536 μs。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。
在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。但应该注意,C51编写的中断服务程序编译后会自动加上PUSH ACC、PUSH PSW、POP PSW和POP ACC语句,执行时占用了4个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去以达到最小误差的目的。
2 软件延时与时间计算
在很多情况下,定时器/计数器经常被用作其他用途,这时候就只能用软件方法延时。下面介绍几种软件延时的方法。
21 短暂延时
可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C文件中,需要时在主程序中直接调用。如延时10 μs的延时函数可编写如下:
Delay10us( )函数中共用了6个_NOP_( )语句,每个语句执行时间为1 μs。主函数调用Delay10us( )时,先执行一个LCALL指令(2 μs),然后执行6个_NOP_( )语句(6 μs),最后执行了一个RET指令(2 μs),所以执行上述函数时共需要10 μs。 可以把这一函数当作基本延时函数,在其他函数中调用,即嵌套调用\[4\],以实现较长时间的延时;但需要注意,如在Delay40us( )中直接调用4次Delay10us( )函数,得到的延时时间将是42 μs,而不是40 μs。这是因为执行Delay40us( )时,先执行了一次LCALL指令(2 μs),然后开始执行第一个Delay10us( ),执行完最后一个Delay10us( )时,直接返回到主程序。依此类推,如果是两层嵌套调用,如在Delay80us( )中两次调用Delay40us( ),则也要先执行一次LCALL指令(2 μs),然后执行两次Delay40us( )函数(84 μs),所以,实际延时时间为86 μs。简言之,只有最内层的函数执行RET指令。该指令直接返回到上级函数或主函数。如在Delay80μs( )中直接调用8次Delay10us( ),此时的延时时间为82 μs。通过修改基本延时函数和适当的组合调用,上述方法可以实现不同时间的延时。
就是为了延时啊,譬如说你让数码管从1变到10,一秒跳一下这就需要用到延时啊当然你可能会说用定时器就行了,但是定时器有限,而且他是通过中断来控制,但我不需要延时时间那么精准的时候用起中断就不够直接用延时程序方便了
延时03秒程序(12M):
DELAY3:
MOV R2,#200
DL1:
MOV R3,#250
DJNZ R3,$
MOV R3,#250
DJNZ R3,$
MOV R3,#250
DJNZ R3,$
DJNZ R2,DL1
RET
延时05秒程序:
DELAY5:
MOV R2,#5
DLY1:
MOV R3,#200
DLY2:
MOV R4,#250
DJNZ R4,$
DJNZ R3,DLY2
DJNZ R2,DLY1
RET
以上就是关于怎样在DOS程序中建立一个延时器(delay timer)全部的内容,包括:怎样在DOS程序中建立一个延时器(delay timer)、单片机汇编程序怎么计算延时、工业机器人APP延迟指令等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)