本程序是要求设定一个时间,精确到千分之一秒,从00.000--99.999秒可手动调整,手动调整有十个键,5个加5个减,按一下对应的位就加(减)1.时间设好开始计时,时间终结就产生中断,并且在计时过程中还要显示时间(倒计时).例如:设定时间为20.000,则一开始就显示20.000秒,按了开关启动后开始倒计时,并不断显示当前倒计时时间(从20.000一直到00.000),倒计时为0时产生中断.
程序和电路原理图如下:为了方便看程序,在程序中加了注释
;==============================================
ORG 0000H
LJMP START
;===========================================
ORG 0003H
MOV R7,A
MOV R7,A
MOV R7,A
MOV R7,A
MOV R7,A
MOV R7,A
MOV R7,A
MOV R7,A
TIME: LJMP INTERRUPT
;===========================================
START: MOV SP,#5FH
MOV TMOD,#01H ;定时器0设定为工作方式1
MOV TH0,#FCH
MOV TL0,#17H ;定时器初值为FC17H,即
;64535,当计数到65536时
;时器产生溢出中断,共计数1001次
SETB EA
SETB ET0
MOV R7,#00H
MOV R6,#00H
MOV R5,#00H
MOV R4,#00H
MOV R3,#00H
MOV P1,#FFH
MOV P2,#FFH
MOV P3,#FFH
CLR 24H.0
DETECT: ACALL DISPLAY ;连续两次检测有无按键输入,
;以消除按键抖动
MOV A,#FEH
MOV P1,A
ACALL DELAY
MOV A,P1
ORL A,#03H
CPL A
JNZ DETECT0
ACALL DISPLAY
MOV A,#FDH
MOV P1,A
ACALL DELAY
MOV A,P1
ORL A,#03H
CPL A
JNZ DETECT1
DETECT0:ACALL DISPLAY
MOV A,#FEH
MOV P1,A
ACALL DELAY
MOV A,P1
ORL A,#03H
CPL A
JNZ JUDGE0
DETECT1:ACALL DISPLAY
MOV A,#FDH
MOV P1,A
ACALL DELAY
MOV A,P1
ORL A,#03H
CPL A
JNZ JUDGE1
AJMP DETECT
JUDGE0: CJNE A,#04H,NEXT ;判断哪一位为1则表示对应的时间
;位加1
AJMP TENA
NEXT: CJNE A,#08H,NEXT1
AJMP ONEA
NEXT1: CJNE A,#10H,NEXT2
AJMP POINT1A
NEXT2: CJNE A,#20H,NEXT3
AJMP POINT2A
NEXT3: CJNE A,#40H,NEXT4
AJMP POINT3A
NEXT4: CJNE A,#80H,BACK
AJMP SAVE
BACK: AJMP DETECT
JUDGE1: CJNE A,#04H,NEXT0 ;判断哪一位为1则表示对应的时间
;位减1
AJMP TEND
NEXT0: CJNE A,#08H,NEXT5
AJMP ONED
NEXT5: CJNE A,#10H,NEXT6
AJMP POINT1D
NEXT6: CJNE A,#20H,NEXT7
AJMP POINT2D
NEXT7: CJNE A,#40H,NEXT8
AJMP POINT3D
NEXT8: CJNE A,#80H,BACK
AJMP SAVE
RELESE: ACALL DISPLAY ;确定按键是否释放
MOV A,P1
ORL A,#03H
CPL A
JNZ RELESE
AJMP DETECT
POINT3A:JB 24H.0,RELESE
CLR C
MOV A,R3
ADD A,#01H
DA A
ANL A,#0FH ;BCD十进制数只用后4位,前4位清0以防
;出错
MOV R3,A
AJMP RELESE
POINT2A:JB 24H.0,RELESE
CLR C
MOV A,R4
ADD A,#01H
DA A
ANL A,#0FH
MOV R4,A
AJMP RELESE
POINT1A:JB 24H.0,RELESE
CLR C
MOV A,R5
ADD A,#01H
DA A
ANL A,#0FH
MOV R5,A
AJMP RELESE
ONEA: JB 24H.0,RELESE
CLR C
MOV A,R6
ADD A,#01H
DA A
ANL A,#0FH
MOV R6,A
AJMP RELESE
TENA: JB 24H.0,RELESE
CLR C
MOV A,R7
ADD A,#01H
DA A
ANL A,#0FH
MOV R7,A
AJMP RELESE
POINT3D:JB 24H.0,RELESE
CLR C
MOV A,R3
DEC A,#01H
ANL A,#0FH
MOV R3,A
AJMP RELESE
POINT2D:JB 24H.0,RELESE
CLR C
MOV A,R4
DEC A,#01H
ANL A,#0FH
MOV R4,A
AJMP RELESE
POINT1D:JB 24H.0,RELESE
CLR C
MOV A,R5
DEC A,#01H
ANL A,#0FH
MOV R5,A
AJMP RELESE
ONED: JB 24H.0,RELESE
CLR C
MOV A,R6
DEC A,#01H
ANL A,#0FH
MOV R6,A
AJMP RELESE
TEND: JB 24H.0,RELESE
CLR C
MOV A,R7
DEC A,#01H
ANL A,#0FH
MOV R7,A
AJMP RELESE
SAVE: MOV A,R7 ;确定已经手动置入了数则跳转把定时数
;据保存,否则返回继续等待输入定时数
JNZ DONE
MOV A,R6
JNZ DONE
MOV A,R5
JNZ DONE
MOV A,R4
JNZ DONE
MOV A,R3
JNZ DONE
AJMP RELESE
DONE: MOV 37H,R7
MOV 36H,R6
MOV 35H,R5
MOV 34H,R4
MOV 33H,R3
SETB TR0 ;启动计数器
CLR P2.7 ;点亮计数器指示灯
SETB 24H.0
WAIT: ACALL DISPLAY
JB 24H.0,WAIT
AJMP RELESE
DISPLAY:SETB P2.4 ;以扫描显示方式显示时间
SETB P2.3
SETB P2.2
SETB P2.1
SETB P2.0
MOV DPTR,#DATAS
MOV A,R7
MOVC A,@A+DPTR
MOV P0,A
CLR P2.4
ACALL DELAY
SETB P2.4
MOV A,R6
MOVC A,@A+DPTR
MOV P0,A
CLR P0.7
CLR P2.3
ACALL DELAY
SETB P2.3
MOV A,R5
MOVC A,@A+DPTR
MOV P0,A
CLR P2.2
ACALL DELAY
SETB P2.2
MOV A,R4
MOVC A,@A+DPTR
MOV P0,A
CLR P2.1
ACALL DELAY
SETB P2.1
MOV A,R3
MOVC A,@A+DPTR
MOV P0,A
CLR P2.0
ACALL DELAY
SETB P2.0
RET
;===========================================
DELAY: MOV R1,#02H ;延时程序
LOOP: MOV R2,#FAH
DJNZ R2,$
DJNZ R1,LOOP
RET
;===========================================
DATAS: DB C0H,F9H,A4H,B0H,99H,92H,82H,F8H ;七段BCD译
;码显示表
DB 80H,90H
;===========================================
INTERRUPT:PUSH A ;定时器每经过1001*12/12M=1001微秒则
;产生一次中断,把手动置入的秒数减去
;0.001秒
PUSH PSW
MOV TH0,#FCH
MOV TL0,#17H
MOV A,R7 ;检查最高位是否已经为0,为0则跳转检查
;次高位.
JZ BITE2
MOV A,R3 ;检查最低位是否为0,不为0则跳转进行操
;作减1,为0则检查上一位是否可以借位
JNZ WRITE5
MOV A,R4 ;上一位为0则继续检查再上一位是否可借
;位,不为0则跳转把上一位减1,把最低位
;置9
JNZ WRITE4
MOV A,R5 ;与上同理
JNZ WRITE3
MOV A,R6 ;与上同理
JNZ WRITE2
AJMP WRITE1
BITE2: MOV A,R6 ;检查次高位是否已经为0,为0则跳转检查下一位.
JZ BITE3
MOV A,R3 ;检查最低位是否为0,不为0则跳转进行
;操作减1,为0则检查上一位是否可以借位
JNZ WRITE5
MOV A,R4 ;上一位为0则继续检查再上一位是否可借
;位,不为0则跳转把上一位减1,把最低位置9
JNZ WRITE4
MOV A,R5
JNZ WRITE3
AJMP WRITE2
BITE3: MOV A,R5 ;检查第三位是否已经为0,为0则跳转
;检查第四位.
JZ BITE4
MOV A,R3
JNZ WRITE5
MOV A,R4
JNZ WRITE4
AJMP WRITE3
BITE4: MOV A,R4 ;检查第四位是否已经为0,为0则跳转
;最后位减1.
JZ BITE5
MOV A,R3
JNZ WRITE5
AJMP WRITE4
BITE5: MOV A,R3 ;前四位都为0,只有最低位不为0,则
;把最低位减1
DEC A
MOV R3,A
JNZ RETURN ;最低位减1后是否也已为0,不为0则
;中断返回继续
SETB P2.7 ;为0则定时时间已到,关闭定时器,并
;把手动置入的数再次调出准备下一次定时
CLR 24H.0
CLR TR0
MOV R7,37H
MOV R6,36H
MOV R5,35H
MOV R4,34H
MOV R3,33H
MOV TH0,#FCH
MOV TL0,#17H
AJMP RETURN
WRITE5: MOV A,R3 ;最低位减1
DEC A
MOV R3,A
AJMP RETURN
WRITE4: MOV R3,#09H ;次低位借1,最低位置9
MOV A,R4
DEC A
MOV R4,A
AJMP RETURN
WRITE3: MOV R3,#09H ;第三位借1,低两位都置9
MOV R4,#09H
MOV A,R5
DEC A
MOV R5,A
AJMP RETURN
WRITE2: MOV R3,#09H ;次高位借1,后三位都置9
MOV R4,#09H
MOV R5,#09H
MOV A,R6
DEC A
MOV R6,A
AJMP RETURN
WRITE1: MOV R3,#09H ;最高位借1,后四位都置9
MOV R4,#09H
MOV R5,#09H
MOV R6,#09H
MOV A,R7
DEC A
MOV R7,A
RETURN: POP PSW
POP ACC
RETI
;===========================================