DELAY:MOV
R3,#14H
;循环20次
MOV
TMOD,#10H
;定时器1工作于模式1(16位定时器)
MOV
TH1,#3CH
;赋初值,50毫秒溢出一次
MOV
TL1,#0B0H
SETB
TR1
;启动定时器1
LP1:
JBC
TF1,LP2
;溢出位为1,则清0后转移到LP2
SJMP
LP1
;否则等待TF1置1
LP2
:MOV
TH1,#3CH
;重新赋初值
MOV
TL1,#0B0H
DJNZ
R3,LP1
;20次循环完成则退出,否则转LP1
RET
;综述:以上共延时1秒。
自己编。。。。 精确到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、首先,在电脑中打开keil软件,创建好工程,然后添加c文件,如下图所示。
2、然后添加c文件,接下来输入代码,先输入一个头文件命令。
3、然后,进行宏定义,代码如图所示。
4、然后声明P1口,如下图所示。
5、最后,将延时语句全部添加进去,代码按照图中所示的直接敲入即可。
6、最后,点击编译,生成HEX文件就可以了,这样51单片机延时语句就完成了。
H_DATA BIT P32 将p32引脚命名为H_DATA,以后用H_DATA就能代表P32
H_CLK BIT P34 同上,将P34命名为H_CLK
PRDELAY30US SEGMENT CODE 函数DELAY30US声明
PUBLIC DELAY30US
RSEG PRDELAY30US
; abc XDATA 0A00H
;358US
DELAY30US: 函数体
PUSH 05H ;2因为函数用到R5,所以将进入函数之前的R5压入堆栈,返回前提出
MOV r5,#50 ;25 为R5赋值
DE30S1:
DJNZ r5,DE30S1 ;214=28 对R5减一,判断不等于零跳到DE30S1;等于零退出
POP 05h ;2把进入函数前的R5恢复
RET 函数返回
;
PRDELAY10US SEGMENT CODE 声明DELAY10US函数
PUBLIC DELAY10US
RSEG PRDELAY10US
;163US
DELAY10US: DELAY10US函数体
PUSH 05H ;2因为函数用到R5,所以将进入函数之前的R5压入堆栈,返回前提出
MOV r5, #20 ;10为R5赋值
DE10S1:
DJNZ r5, DE10S1 ;52=10对R5减一,判断不等于零跳到DE10S1;等于零退出
POP 05H ;2把进入函数前的R5恢复
RET 函数返回
PRCLSSIGNAL SEGMENT CODE 声明函数CLSSIGNAL
PUBLIC CLSSIGNAL
RSEG PRCLSSIGNAL
CLSSIGNAL:
;WHEN SYSTEM SEND INFORMATION TO PINPAD, SEND STOP BIT AT END, THEN NEXT A
;SEND OPERATION SO WAITTING STOP BIT FINISHED
CLSL1:
PUSH 05H 因为函数用到R5,所以将进入函数之前的R5压入堆栈,返回前提出
CLSL1_U:
MOV R5, #6EH 对R5赋值
CLSL2: JNB H_DATA, CLSL1_U 判断p32不为零跳转,继续赋初值
JNB H_CLK, CLSL1_U 判断p34不为零,继续赋初值
DJNZ R5, CLSL2 如果两个输入都为零对r5减一,不为零跳到clsl2
POP 05H
RET
END
要设置多个初值,可以使用“状态存储器”模块,其设置多个初始状态块。一旦你添加好状态存储器模型,可以调整状态定义的变量的值,以及设置初始值。
另外,可以使用“多址状态转换矩阵”模块,它会列出所有可能的状态序列。选择不同的状态,可以设置每个状态的初始值,以及其转换关系。
楼上的,你是不是写错了,DJNZ R6,L1
然后L1:MOV R6,#100成了死循环了不是?看看这个
DELAY:MOV R5,#100
L1: MOV R6,#100
L2: DJNZ R6,L2
DJNZ R5,L1
RET
具体延时多久看你预置的计数初值了
以上就是关于请问这段单片机汇编语言程序(关于定时器延时)是什么意思全部的内容,包括:请问这段单片机汇编语言程序(关于定时器延时)是什么意思、单片机 编写延时一分钟程序 fosc=6Mhz、请帮忙在51系列单片机系统中,编写一个延时1ms的子程序。谢谢。。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)