刁一峰,杨培刚,刘丽萍,刘兴旺
(湖南生物机电职业技术学院车辆工程学院,湖南长沙410126)
单片机软件延时程序是一种循环程序,即中央处理器通过执行占用固定时间的循环体来完成延时。在进行单片机应用系统设计的过程中,有时会发现实际结果和预期目标不符。以跳马灯设计为例进行说明,具体Proteus仿真系统如图1所示。
要求P1口连接8个LED灯,从D1开始,依次点亮。但是把表1所示的跳马灯程序下载到AT89S51单片机上后,发现8个LED灯一直亮,和预期要求不符。
图1 跳马灯仿真系统
通过分析,发现没有延时程序对每一个灯亮的状态进行延时[1]。因此,延时程序对于系统程序来说是至关重要的。
软件延时程序就是单片机程序的每条指令被CPU执行时都要占用一定的机器周期,并且通过多次循环来实现延时的目的。因此,只要知道了执行每条指令所占用的机器周期以及循环控制变量,就能算出延时的时间长度。
振荡周期(TC):也叫时钟周期,一个振荡周期等于晶振频率的倒数,即
TC=1/fosc
表1 跳马灯程序与功能
机器周期(T):1个机器周期等于12个时钟周期,即
T=12TC
指令周期:指CPU执行一条指令所需要的时间,指令周期以机器周期为单位,分为单周期指令、双周期指令和四周期指令3种,如表2所示。
表2 指令周期与机器周期的关系
单片机AT89S51汇编延时程序中经常用到的指令有以下几种:
1)数据传送指令MOV Rn,#X
把立即数X传送到通用寄存器Rn中去,双周期指令。
2)循环转移指令DJNZ Rn,L1
将通用寄存器Rn中的内容减1后判断是否为0,如果为0顺序执行,不为0转移到L1处,双周期指令。
3)返回指令RET
返回主程序,双周期指令。
4)空操作指令NOP
不进行任何操作,单周期指令。
1)单层循环延时程序
DEL:MOV R0,#X;1周期
L1:DJNZ R0,L1;2周期
RET;2周期
程序延时时间t=T+2XT+2T=(2X+3)T。
因为0≤X≤255(其中X=1时,延时时间最短),所以整个程序的延时时间范围为5T≤t≤515T,具体延时时间与X的关系如表3所示。
2)双层循环延时程序
DEL:MOV R1,#Y;1周期
L2:MOV R0,#X;1 周期
L1:DJNZ R0,L1;2周期
DJNZ R1,L2;2周期
RET;2周期
延时时间t=T+YT+2XYT+2YT+2T=[(2X+3)Y+3]T,整个程序的延时时间范围为8T≤t≤131843T,具体延时时间与X的关系如表3所示。
3)三层循环延时程序
DEL:MOV R2,#Z;1 周期
L3:MOV R1,#Y;1 周期
L2:MOV R0,#X;1 周期
L1:DJNZ R0,L1;2周期
DJNZ R1,L2;2周期
DJNZ R2,L3;2周期
RET;2周期
延时时间t=T+ZT+YZT+2XYZT+2YZT+2ZT+2T={[(2X+3)Y+3]Z+3)}T,整个程序的的延时时间范围为11T≤t≤33751811T,具体延时时间与X的关系如表3所示。
通过上面分析可以总结出N层循环程序的延时时间长度的计算公式为
其中,Xi是装入通用寄存器Ri的立即数,T是机器周期。
要设计精确的延时程序只有 MOV、DJNZ、RET这些功能指令是不行的,还要在循环程序段中增加哑指令(如NOP等)对延时时间进行调整,丰富延时程序的选择项,实现延时程序的精确设计。
DEL:MOV R2,#Z;1周期 1
NOP;1周期1
L3:MOV R1,#Y;1周期 Z
NOP;1周期 Z
L2:MOV R0,#X;1周期 YZ
NOP;1周期 YZ
L1:DJNZ R0,L1;2周期 2XYZ
DJNZ R1,L2;2周期 2YZ
DJNZ R2,L3;2周期 2Z
RET;2周期2
在数据传送MOV指令后增加空操作指令NOP,则延时时间变为
表3 不同层数延时时间简表
t=T+T+ZT+ZT+YZT+YZT+2XYZT+2YZT+2ZT+2T=(2XYZ+4YZ+4Z+4)T。
延时时间长度的计算公式变为
以晶振频率focs为12 MHz的单片机为例,设计1个100 ms延时时间的延时程序。已知机器周期T=1 μs,100 ms=100 000 μs,根据延时时间计算公式可选择双层或多层循环。假如选择双层延时,Y取值200,X 取值249,延时时间为 100.203 ms,和预设值相差较大。若进行调整,Y取值200,X取值248,在指令MOV R1,#X后加NOP指令,延时时间变为100.003 ms,也不够精确。
若选择六层延时,加调整可得延时程序如下:
DEL:MOV R5,#5
NOP
NOP
L6:MOV R4,#5
NOP
L5:MOV R3,#5
NOP
L4:MOV R2,#5
NOP
L3:MOV R1,#4
L2:MOV R0,#198
L1:DJNZ R0,L1
DJNZ R1,L2
DJNZ R2,L3
DJNZ R3,L4
DJNZ R4,L5
DJNZ R5,L6
RET;
延时时间为t=(((((2*198+3)*4+3)*5+4)*5+4)*5+4)*5+5=100 000 μs=100 ms。
通过100 ms精确延时程序设计发现,延时程序占用了大量的通用寄存器资源,然而真正进行精确延时程序设计时,还应该考虑实际的晶振频率、主程序运行指令和调用指令ACALL、LCALL等诸多因素,实现起来相当困难。另外,软件延时程序是通过牺牲CPU的时间来实现时间延时,中断服务程序的执行不能出现在延时程序的执行过程中,以免延时时间受到影响,引起主程序整体功能的错乱,使主程序的正常运行受到影响。所以,单片机在进行实时性、多任务的工作时,要安排好延时程序的时序,否则会影响任务调度,造成程序不能正常运行。
实际上延时参数数值的设定只能根据具体的时间长度和晶振频率的参数计算,依据模块化延时程序所总结出的方法和技巧是十分不便的。
因为设计者都有不同的设计习惯,面对不同的实际影响因素,公式会有所差异,然而分析和解决问题的方法和技巧是相似的。通过对单片机不同的延时程序模式的分析,总结出了延时时间的计算公式和办法,设计了精确的延时程序,在教学和程序开发上具有良好的应用效果。
[1]张迎新.单片机原理及应用[M].第2版.北京:电子工业出版社,2009:86-87.
[2]吴挺运,林成何.Keil C51精确延时程序设计[J].电子科技,2012(12):103-106.
[3]张德芳,雷国亮,张晓冰.LPC21xx C程序的精确延时方法[J].单片机与嵌入式系统应用,2010(10):73-75.
[4]赵月静,张永弟,翟卫贺.Proteus和Keil C在开发单片机控制系统中的应用[J].实验科学与技术,2013(2):31-34.
[5]郭兆正,尹作友.单片机系统模块化设计方法教学研究[J].沈阳师范大学学报(自然科学版),2013(1):112-114.
[6]向继文.以应用为目标的单片机原理教学[J].计算机教育,2013(22):49-54.