延时程序模块
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
延时程序
(1)、介绍:
延时程序用来在程序中提供一段时间的“空操作”,添加延时程序的目的有很多,譬如在做流水灯的时候,点亮一个LED后,必须延时一段时间然后熄灭这颗LED再点亮另外一颗LED,我们才能看到流水效果。否则因为人眼的视觉暂留效应,我们实际看到的效果是所有LED都是一直亮着的。
(2)、示例代码及解析:
F_DELAY1S: ;子程序标号
MOV R7,#0A7H ;设定第1层循环次数
L_DELAY1: ;第一层循环标号
MOV R6,#0ABH ;设定第2层循环次数
L_DELAY2: ;第二层循环标号
MOV R5,#10H ;设定第3层循环次数
L_DELAY3: ;第三层循环标号
DJNZ R5,L_DELAY3 ;第三层循环控制
DJNZ R6,L_DELAY2 ;第二层循环控制
DJNZ R7,L_DELAY1 ;第一层循环控制
RET ;子程序返回
解析:首行的F_DELAY1S:是子程序标号,该标号以F_开头来命名是为了表明其为一个函数的标号(F代表Function,同样的L_DELAY1等的L_表示其为单纯的标号(L代表Label))。
延时程序本身为一个典型的循环程序结构,如本示例即为1S的一个软件延时(使用软件延时一词来表示这种延时,以区分后面将会遇到的定时器延时)。延时时间由层数和各层的循环次数来决定,如本例为一个三层循环延时。
程序具体是如何执行的,请按照DJNZ指令特点、结合上课知识自己分析,并且用Keil 软件仿真的单步执行来验证。
(3)、针对具体需要的延时时间,譬如0.5ms,如何确定R7、R6等延时初值:
延时程序中循环控制寄存器初值的确定有三种常用方法。
方法一:自己计算
因为延时的原理即为使用循环结构,通过指令本身的执行来消耗时间已达到延时目的,因此可通过计算程序中各条指令被执行的次数、再分别乘以这个指令对应的指令周期,即可得到程序对应的延时时间。如下面这个简单的延时程序:
(注:以下计算时均默认机器周期为1us,即外部使用12M晶振)
程序语句执行次数指令周期语句总执行时间DELAY:
MOV R6,#1 1 1 1*1 us
DL0:
MOV R5,#47 1 1 1*1 us
DJNZ R5,$ 47 2 47*2 us
DJNZ R6,DL0 1 2 1*2 us
RET 1 2 1*2 us
可见,该延时程序能够实现的精确延时时间为:1+1+47*2+2+2=100us。
解释一下DJNZ R5,$一句,$符号在汇编语言中表示所在行的行首地址,因此该语句等同于L_DL1:DJNZ R5,L_DL1,使用$符号是为了书写简单清晰而已。
仔细分析及实际演练这种计算延时的方法,有助于初学者理解程序的执行、熟悉指令等,但该种方法的实用性非常不好。当延时时间较小,譬如几十微妙的时候还比较好计算,但随着延时时间的增加(譬如秒级延时)需要两层三层循环时,计算将非常麻烦,往往需要试很多次才能得到一个比较接近需要的初值组合。实战中我们一般不适用这种延时计算方法。
方法二:利用Keil软件仿真计算。
Keil的软件仿真提供程序执行时间的计算功能,因此我们可以利用此功能来计算一段程序的延时时间。具体执行过程如下:
①、在Keil编译器中输入延时程序,输入时根据估算在R7等寄存器中大概填入一些数字。
②、点击菜单栏Project->Options for target,或者在图标栏点击相应图标,以打开Options for target对话框,在第一行选择Target分选栏,在上方中间处Xtal(MHz)后面的方框内填入相应的晶振频率(根据实际使用的晶振频率填写,本教程一般选择用12M晶振),在最下面一行点击OK即可。
③、点击Project->Build all target files,或者点击相应图标,以对文档进行编译。
④、点击菜单栏Debug->Start or Stop Debug Session,或在图标栏点击相应图标,以切换到调试模式。此时会发现图标栏内很多关于调试的图标从不可用的灰色变成了可用状态,同时编译图标由可用变为了不可用。
⑤、注意屏幕左面Registor一栏中Sys->sec项目,这条记录的即是程序运行的累积时间。利用单步运行指令将程序运行到需要测试的延时子程序开始位置,记录下此时的累积时间,然后在延时程序结束的下一条语句处打断点(breakpoint),然后点击图标栏Run(全速执行),运行会在断点处自动停止,记录此时的累积时间,减去初始的累计时间,即为延时程序运行的时间。
⑥、调整。一般来说,我们估算的延时时间不会很精确,这时即可以根据仿真的实际时间去调整R7等寄存器的值,再次重复③~⑤测试执行时间,反复调整直到实际测试的时间与期望延时时间吻合。
需要强调的一点是,在每次修改R7等寄存器的值后(实际上只要对程序进行了任何修改),都要退出调试模式进行重新编译,然后再次进入调试模式进行调试。如果在修改了程序后没有重新编译就再次仿真运行时间,则得到的结果仍然是修改前的运行结果。
这种延时程序计算方法利用了Keil的仿真功能,相对来说计算时间较长的延时初值时比方法一有效。而且练习使用该方法非常有助于学习Keil的软件仿真功能,推荐初学者使用该方法实际去演练几个练习。那么,在实际应用中还有没有更简单有效的方法呢?
方法三:使用辅助工具。
软件延时是程序中经常用到的模块,因此有人专门就此模块编了一些使用的小软件,这类软件功能很类似,即输入晶振频率、需要的延时时间等,软件即可自动生成相应的延时代码,直接复制生成的代码使用即可,这种软件可在网上下载到。
总结:以上三种方法中,建议前两种初学者均亲自实践练习,务必要通过练习深刻理解延时程序的里里外外相关的知识。达到理解的目的后,以后的工作中使用延时程序时为了提高效率,即可使用方法三快速高效的得到需要的代码。