从零开始学51单片机定时器
程序 2:用中断实现
ORG 0000H
AJMP START
ORG 000BH ;定时器 0 的中断向量地址
AJMP TIME0 ;跳转到真正的定时器程序处
ORG 30H
START:
MOV P1,#0FFH ;关所 灯
MOV TMOD,#00000001B ;定时/计数器 0 工作于方式 1
MOV TH0,#15H
MOV TL0,#0A0H ;即数 5536
SETB EA ;开总中断允许
SETB ET0 ;开定时/计数器 0 允许
SETB TR0 ;定时/计数器 0 开始运行
LOOP: AJMP LOOP ;真正工作时,这里可写任意程序
TIME0: ;定时器 0 的中断处理程序
PUSH ACC
PUSH PSW ;将 PSW 和 ACC 推入堆栈保护
CPL P1.0
MOV TH0,#15H
MOV TL0,#0A0H ;重置定时常数
POP PSW
POP ACC
RETI
END
上面的例程中,定时时间一到,TF0 由 0 变 1,就会引发中断,CPU 将自动转至 000B处寻找程序并执行,由于留给定时器中断的空间只有 8 个字节,显然不足以写下所有有中断处理程序,所以在 000B 处安排一条跳转指令,转到实际处理中断的程序处,这样,中断程序能写在任意地方,也能写任意长度了。进入定时中断后,首先要保存当前的一些状态,程序中只 演示了保存存 ACC 和 PSW,实际工作中应该根据需要将可能会改变的单元的值都推入堆栈进行保护(本程序中实际不需保存护任何值,这里只作个演示)。
上面的两个单片机程序运行后,我们发现灯的闪烁非常快,根本分辨不出来,只是视觉上感到灯有些晃动而已,为什么呢?我们能计算一下,定时器中预置的数是 5536,所以每计 60000 个脉冲就是定时时间到,这 60000 个脉冲的时间是多少呢?我们的晶体震荡器 是12M,所以就是 60000 微秒,即 60 毫秒,因此速度是非常快的。如果我想实现一个 1S 的定时,该怎么办呢?在该晶体震荡器濒率下,最长的定时也就是 65。536 个毫秒啊!上面给出 一个例程。
ORG 0000H
AJMP START
ORG 000BH ;定时器 0 的中断向量地址
AJMP TIME0 ;跳转到真正的定时器程序处
ORG 30H
START:
MOV P1,#0FFH ;关所 灯
MOV 30H,#00H ;软件计数器预清 0
MOV TMOD,#00000001B ;定时/计数器 0 工作于方式 1
MOV TH0,#3CH
MOV TL0,#0B0H ;即数 15536
SETB EA ;开总中断允许
SETB ET0 ;开定时/计数器 0 允许
SETB TR0 ;定时/计数器 0 开始运行
LOOP: AJMP LOOP ;真正工作时,这里可写任意程序
TIME0: ;定时器 0 的中断处理程序
PUSH ACC
PUSH PSW ;将 PSW 和 ACC 推入堆栈保护
INC 30H
MOV A,30H

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW
或用微信扫描左侧二维码