本节书摘来异步社区《51单片机应用开发从入门到精通》一书中的第2章,第2.4节,作者:张华杰 ,更多章节内容可以访问云栖社区“异步社区”公众号查看
2.4 延时时间计算实例
51单片机应用开发从入门到精通
在单片机的实时控制系统中,常常需要用到延时操作,所以,延时子程序往往是编写单片机程序中不可缺少的一部分。延时方法有硬件延时和软件延时,硬件延时将在后面有关章节中介绍,本节将介绍软件延时方法。
所谓软件延时,就是让计算机重复执行一些无具体任务的程序,利用执行程序的时间来达到延时的目的。
2.4.1 机器周期和指令周期
单片机读、写操作都需要消耗一定的时间,机器周期是指单片机完成一个基本操作所用的时间,如读操作、写操作等。当石英晶体为12MHz时,1个机器周期为1s。
指令周期是指单片机执行一条指令所需要的时间,一个指令周期通常含有1~4个机器周期,其中常用的DJNZ指令周期为两个机器周期,即执行DJNZ指令需要2s;MOV指令周期为一个机器周期,即执行MOV指令需要1s。
2.4.2 单重循环短暂延时
短暂的时间延时可采取简单的单重循环结构来实现,例如,下面程序为延时540s的短暂延时子程序,程序中采取了单重循环。
此子程序中,由第3、4行代码构成单重循环结构,其中,DJNZ指令为控制转移指令,该指令每执行一次,寄存器R值减1,只要R值减1后不为0,就会转移到第3行标号DE1处去执行。
每循环一次需要的时间为3s,由于R值为180,所以要循环180次,循环花费的时间为540s。该延时子程序总的延时时间还要包括执行MOV指令时间1s和执行RET返回指令时间2s,但由于这个时间比循环时间要短很多,所以,延时时间的长短主要是由循环次数来控制。
2.4.3 多重循环较长时间延时
如果需要较长时间的延时,则需采用多重循环结构。例如下面程序为1s延时子程序,程序中采取了多重循环。
此子程序采用了3重循环结构,先运行第5行代码操作,每次减1,减到0为止;再运行第6行代码对R6进行减操作,每次减1,减1后不为0,则转移到标号DLY2处运行,此时将R7赋值为100,并再对R7进行减法内循环。
当R6减为0时,程序运行到第7行,开始外循环,R5减1不为0时转移到标号DLY1处运行。为了计算上的简便,可以忽略赋值语句的时间,只计算“DJNZ R7, $”语句的执行时间,该指令执行一次需2s,执行的次数为R5、R6和R7值的乘积,即:
总延时 = 2sR7R6R5
=2s10010050 = 1 000 000s
=1s
2.4.4 延时程序改进
从上节程序可以看出,只要改变寄存器R5、R6和R7的值,就可以获得不同延时时间。在上例中假设R6和R7值不变,只改变R5值(R5取值范围为1~255),可获得不同的延时。由于忽略了赋值语句的执行时间,实际延时时间要比计算的时间略大一些。
为了使一个延时子程序能产生不同的延时,可以将2.4.3节中的程序改进为以下的形式。其中R7、R6值不变,通过改进R5值,即改变外循环次数来改变延时时间,延时子程序的延时时间为0.02sR5。
使用时,在调用DELAY延时子程序之前,要根据对延时时间的要求,先对R5赋值,假如延时为0.5s,需将R5值赋值为25;延时为1s,需将R5值为50,R5最大值为255,这是因为R0~R7都是8位寄存器,最大存放数据为二进制数11111111,即255,在使用时注意不要超出其有效范围。改进后的延时程序使用形式如下:
MOV R5, #50
ACALL DELAY_20msR5```
延时时间为0.02sR5的延时程序如下:
1 DELAY_20msR5:
2
3 DLY1: MOV R6, #100
4 DLY2: MOV R7, #100
5 DJNZ R7, $
6 DJNZ R6, DLY2
7 DJNZ R5, DLY1
8 RET`