/***************************************************************************************
008.ASM
用八位数码管显示时间,通过两个按键改变显示内容及修改时间
接线:J15.J16短接,P0接八位数码管,P2接独立键盘
2010.09.06
***************************************************************************************/
ORG 0000H
LJMP MAIN
ORG 001BH
LJMP INT_T1
ORG 0040H
MAIN:
LCALL FRIST ;上电初始化
LOOP: ;主循环
LCALL KEY_READ ;读键盘
JBC 00H,N
LJMP N0 ;无键,则跳到N0
N:
LCALL CHAUNG ;有键则去刷新显示状态
LJMP LOOP
N0: ;输出当前时分秒
MOV R0,#60H
MOV R1,#07H
MOV R5,#08H
LCALL COUNT_OUTPUT ;刷新输出
LCALL SHOW ;输出
LCALL CHANG_TIME ;按秒改变输出时间
LJMP LOOP
FRIST:
MOV SP,#30H ;设置堆栈
MOV 45H,#01H ;设置初始状态为00H
MOV P1,#0FFH ;初始化P1口
MOV TMOD,#21H ;设置定时器工作模式,T0为工作模式2,T1为工作模式1
MOV 50H,#06H ;初始化年月日 数码管显示
MOV 51H,#00H
MOV 52H,#09H
MOV 53H,#00H
MOV 54H,#00H
MOV 55H,#01H
MOV 56H,#00H
MOV 57H,#02H
MOV 46H,#14H ;初始化年月日
MOV 47H,#0AH
MOV 48H,#09H
MOV 49H,#06H
MOV 60H,#00H ;初始化时 分 秒 数码管显示
MOV 61H,#00H
MOV 62H,#08H
MOV 63H,#05H
MOV 64H,#02H
MOV 65H,#02H
MOV 66H,#00H
MOV 67H,#00H
MOV 58H,#16H ;初始化时分秒
MOV 59H,#3AH
MOV 68H,#00H
MOV R6,#19H ;定时T1计数
MOV R7,#28H
MOV TH0,#15H ;赋T0定时初值
MOV TL0,#0A0H
MOV TH1,#06H ;赋T1定时初值
MOV TL1,#06H
SETB TR1
CLR 00H ;初始化按键标志为“0” , 即 无 键
CLR 01H ;初始化键值为“0”,即A
CLR 02H ;初始化按键长短为“0”,即短按键
CLR 03H ;初始化定时T1标志
CLR 04H ;初始时间更改标志位(秒,分,时,日,月,年)
CLR 05H
CLR 06H
CLR 07H
CLR 08H
CLR 09H
CLR 0AH
CLR 0BH ;01状态标志位,表示为01状态
MOV IE,#88H ;开定时中断
RET
/*输出计算子程序*/
COUNT_OUTPUT:
JBC 04H,COUNT_S ;秒改变,则计算出显示值送相应内存
LJMP COUNT_M
COUNT_S: ;否则去计算分
MOV B,#0AH ;秒/10。商送61H,余数送60H
MOV A,68H
DIV AB
MOV 61H,A
MOV 60H,B
COUNT_M:
JBC 05H,COUNT_M0 ;分改变,则计算出显示值送相应内存
LJMP COUNT_H ;否则去计算时
COUNT_M0:
MOV B,#0AH ;分/10,商送63H,余数送62H
MOV A,59H
DIV AB
MOV 63H,A
MOV 62H,B
COUNT_H:
JBC 06H,COUNT_H0 ;时改变,则计算出显示值送相应内存
LJMP COUNT_D ;否则去计算日
COUNT_H0:
MOV B,#0AH ;时/10,商送65H,余数送64H
MOV A,58H
DIV AB
MOV 65H,A
MOV 64H,B
COUNT_D: ;日改变,则计算出显示值送相应内存
JBC 07H,COUNT_D0 ;否则去计算月
LJMP COUNT_MON
COUNT_D0: ;日/10,商送51H,余数送50H
MOV B,#0AH
MOV A,49H
DIV AB
MOV 51H,A
MOV 50H,B
COUNT_MON:
JBC 08H,COUNT_MON0 ;月改变,则计算出显示值送相应内存
LJMP COUNT_YL ;否则去计算年(L)
COUNT_MON0:
MOV B,#0AH ;月/10,商送53H,余数送52H
MOV A,48H
DIV AB
MOV 53H,A
MOV 52H,B
COUNT_YL:
JBC 09H,COUNT_YL0 ;年低位改变,则计算出显示值送相应内存
LJMP COUNT_YH ;否则去计算年(H)
COUNT_YL0:
MOV B,#0AH ;年(L)/10,商送55H,余数送54H
MOV A,47H
DIV AB
MOV 55H,A
MOV 54H,B
COUNT_YH: ;年高改变,则计算出显示值送相应内存
JBC 0AH,COUNT_YH0 ;否则子程序返回
LJMP COUNT_RETURN
COUNT_YH0:
MOV B,#0AH ;年(H)/10,商送57H,余数送56H
MOV A,46H
DIV AB
MOV 57H,A
MOV 56H,B
COUNT_RETURN:
RET
/*时间修改子程序*/
CHAUNG:
STAR:
MOV A,45H ;读状态值
CJNE A,#01H,CHAUNG0 ;状态值=01H,则转H_M_S0,否则进行下一个判断
LCALL H_M_S0
LJMP CHAUNG10
CHAUNG0:
CJNE A,#02H,CHAUNG1 ;状态值=02H,则转H_M_S1,否则进行下一个判断
LCALL H_M_S1
LJMP CHAUNG10
CHAUNG1:
CJNE A,#04H,CHAUNG3 ;状态值=04H,则转H_M_S2,否则进行下一个判断
LCALL H_M_S2
LJMP CHAUNG10
CHAUNG3:
CJNE A,#03H,CHAUNG4 ;状态值=03H,则转Y_M_D0,否则进行下一个判断
LCALL Y_M_D0
LJMP CHAUNG10
CHAUNG4:
CJNE A,#06H,CHAUNG5 ;状态值=06H,则转Y_M_D1,否则进行下一个判断
LCALL Y_M_D1
LJMP CHAUNG10
CHAUNG5:
CJNE A,#0CH,CHAUNG6 ;状态值=0cH,则转Y_M_D2,否则进行下一个判断
LCALL Y_M_D2
CHAUNG6:
CJNE A,#18H,CHAUNG7 ;状态值=18H,则转Y_M_D3,否则进行下一个判断
LCALL Y_M_D3
LJMP CHAUNG10
CHAUNG7:
CJNE A,#07H,CHAUNG8 ;状态值=07H,则转S_CLOCK0,否则进行下一个判断
LCALL S_CLOCK0
LJMP CHAUNG10
CHAUNG8:
CJNE A,#0EH,CHAUNG9 ;状态值=0eH,则转S_CLOCK1,否则进行下一个判断
LCALL S_CLOCK1
LJMP CHAUNG10
CHAUNG9:
CJNE A,#1CH,CHAUNG10 ;状态值=07H,则转S_CLOCK2,否则进行下一个判断
LCALL S_CLOCK2
LJMP CHAUNG10
CHAUNG10: ;子程序返回
JBC 0BH,STAR
RET
/*状态01修理子程序*/
H_M_S0:
JB 01H,S_01 ;判断A键,B键
MOV 45H,#02H ;A键,状态转为02H
LJMP S_01_RETURN
S_01: ;B键,状态转为03H
MOV 45H,#03H
S_01_RETURN:
SETB 0BH
RET
/*状态02修理子程序*/
H_M_S1:
MOV 69H,#00H ;定时标志,定时到,回到A状态
LOOP_02:
MOV R0,#64H ;设置显示内容
MOV R1,#03H
MOV R5,#02H
LCALL COUNT_OUTPUT ;计算显示数据
LCALL SHOW ;显示
LCALL KEY_READ ;读键盘
JBC 00H,S_02 ;有键,则去判断长按短按
INC 69H ;无键,定时标志+1
MOV A,69H
CJNE A,#0FFH,LOOP_02 ;定时到,状态转为01H,子程序返回
MOV 45H,#01H
LJMP S_02_RETURN
S_02:
MOV 69H,#00H ;有按键,清零定时标志
JBC 02H,S_02_0 ;长按,去判断A键B键
JBC 01H,S_02_1 ;短按,去判断A键B键
INC 58H ;A键,时+1
SETB 06H ;置位,时改变标志
LJMP LOOP_02
S_02_0:
JBC 01H,S_02_2 ;长按,B键,状态变为了01H,并子程序返回
MOV 45H,#04H ;A键,状态转为04H
SETB 0BH
LJMP S_02_RETURN
S_02_1: ;短按B键,时-1,并置位时改变标志
DEC 58H
SETB 06H
LJMP LOOP_02
S_02_2:
MOV 45H,#01H
S_02_RETURN:
MOV 68H,#00H
RET
/*状态04处理子程序*/
H_M_S2:
MOV 69H,#00H ;定时标志,定时到,回到A状态
LOOP_04:
MOV R0,#62H ;设置显示内容
MOV R1,#05H
MOV R5,#02H
LCALL COUNT_OUTPUT ;计算显示数据
LCALL SHOW ;显示
LCALL KEY_READ ;读键盘
JBC 00H,S_04 ;有键,则去判断长按短按
INC 69H ;无键,定时标志+1
MOV A,69H
CJNE A,#0FFH,LOOP_04 ;定时到,状态转为01H,子程序返回
MOV 45H,#01H
LJMP S_02_RETURN
S_04:
MOV 69H,#00H ;有按键,清零定时标志
JBC 02H,S_04_0 ;长按,去判断A键B键
JBC 01H,S_04_1 ;短按,去判断A键B键
INC 59H ;A键,分+1
SETB 05H ;置位,分改变标志
LJMP LOOP_04
S_04_0:
JBC 01H,S_04_2 ;长按,B键,状态变为了01H,并子程序返回
MOV 45H,#01H ;A键,状态转为08H
LJMP S_04_RETURN
S_04_1: ;短按B键,分-1,并置位分改变标志
DEC 59H
SETB 05H
LJMP LOOP_04
S_04_2:
MOV 45H,#01H
S_04_RETURN:
MOV 68H,#00H
RET
/*状态03修理子程序*/
Y_M_D0:
MOV R0,#50H
MOV R1,#07H
MOV R5,#08H
LCALL COUNT_OUTPUT
LCALL SHOW
LCALL KEY_READ
JB 01H,S_03 ;判断A键,B键
MOV 45H,#06H ;A键,状态转为02H
LJMP S_03_RETURN
S_03: ;B键,状态转为03H
MOV 45H,#07H
S_03_RETURN:
SETB 0BH
RET
/*状态06修理子程序*/
Y_M_D1:
MOV 69H,#00H ;定时标志,定时到,回到A状态
LOOP_06:
MOV R0,#54H ;设置显示内容
MOV R1,#03H
MOV R5,#04H
LCALL COUNT_OUTPUT ;计算显示数据
LCALL SHOW ;显示
LCALL KEY_READ ;读键盘
JBC 00H,S_06 ;有键,则去判断长按短按
INC 69H ;无键,定时标志+1
MOV A,69H
CJNE A,#0FFH,LOOP_06 ;定时到,状态转为01H,子程序返回
MOV 45H,#01H
LJMP S_06_RETURN
S_06:
MOV 69H,#00H ;有按键,清零定时标志
JBC 02H,S_06_0 ;长按,去判断A键B键
JBC 01H,S_06_1 ;短按,去判断A键B键
INC 47H ;A键,年+1
MOV A,47H
CJNE A,#64H,S_066
MOV 47H,#00H
INC 46H
SETB 0AH
S_066:
SETB 09H ;置位,年改变标志
LJMP LOOP_06
S_06_0:
JBC 01H,S_06_2 ;长按,B键,状态变为了01H,并子程序返回
MOV 45H,#01H ;A键,状态转为08H
LJMP S_06_RETURN
S_06_1: ;短按B键,年-1,并置位年改变标志
DEC 47H
MOV A,47H
CJNE A,#-1,S_0666
MOV 47H,#00H
DEC 46H
SETB 0AH
S_0666:
SETB 09H
LJMP LOOP_06
S_06_2:
MOV 45H,#01H
S_06_RETURN:
RET
/*状态0C修理子程序*/
Y_M_D2:
MOV 69H,#00H ;定时标志,定时到,回到A状态
LOOP_0C:
MOV R0,#52H ;设置显示内容
MOV R1,#05H
MOV R5,#02H
LCALL COUNT_OUTPUT ;计算显示数据
LCALL SHOW ;显示
LCALL KEY_READ ;读键盘
JBC 00H,S_0C ;有键,则去判断长按短按
INC 69H ;无键,定时标志+1
MOV A,69H
CJNE A,#0FFH,LOOP_0C ;定时到,状态转为01H,子程序返回
MOV 45H,#01H
LJMP S_0C_RETURN
S_0C:
MOV 69H,#00H ;有按键,清零定时标志
JBC 02H,S_0C_0 ;长按,去判断A键B键
JBC 01H,S_0C_1 ;短按,去判断A键B键
INC 48H ;A键,月+1
SETB 08H ;置位,月改变标志
LJMP LOOP_0C
S_0C_0:
JBC 01H,S_0C_2 ;长按,B键,状态变为了01H,并子程序返回
MOV 45H,#01H ;A键,状态转为08H
LJMP S_0C_RETURN
S_0C_1: ;短按B键,月-1,并置位月改变标志
DEC 48H
SETB 08H
LJMP LOOP_0C
S_0C_2:
MOV 45H,#01H
S_0C_RETURN:
RET
/*状态18修理子程序*/
Y_M_D3:
MOV 69H,#00H ;定时标志,定时到,回到A状态
LOOP_18:
MOV R0,#50H ;设置显示内容
MOV R1,#07H
MOV R5,#02H
LCALL COUNT_OUTPUT ;计算显示数据
LCALL SHOW ;显示
LCALL KEY_READ ;读键盘
JBC 00H,S_18 ;有键,则去判断长按短按
INC 69H ;无键,定时标志+1
MOV A,69H
CJNE A,#0FFH,LOOP_18 ;定时到,状态转为01H,子程序返回
MOV 45H,#01H
LJMP S_18_RETURN
S_18:
MOV 69H,#00H ;有按键,清零定时标志
JBC 02H,S_18_0 ;长按,去判断A键B键
JBC 01H,S_18_1 ;短按,去判断A键B键
INC 49H ;A键,日+1
SETB 07H ;置位,日改变标志
LJMP LOOP_18
S_18_0:
JBC 01H,S_18_2 ;长按,B键,状态变为了01H,并子程序返回
MOV 45H,#01H ;A键,状态转为08H
LJMP S_18_RETURN
S_18_1: ;短按B键,日-1,并置位日改变标志
DEC 49H
SETB 07H
LJMP LOOP_18
S_18_2:
MOV 45H,#01H
S_18_RETURN:
MOV 68H,#00H
RET
/*状态07修理子程序*/
S_CLOCK0:
JB 01H,S_07 ;判断A键,B键
MOV 45H,#01H ;A键,状态转为02H
LJMP S_07_RETURN
S_07: ;B键,状态转为03H
MOV 45H,#07H
S_07_RETURN:
SETB 0BH
RET
/*状态0E修理子程序*/
S_CLOCK1:
LOOP_0E:
MOV R0,#62H ;设置显示内容
MOV R1,#05H
MOV R5,#02H
LCALL COUNT_OUTPUT ;计算显示数据
LCALL SHOW ;显示
LCALL KEY_READ ;读键盘
JBC 00H,S_0E ;有键,则去判断长按短按
INC 69H ;无键,定时标志+1
MOV A,69H
CJNE A,#0FFH,LOOP_0E ;定时到,状态转为01H,子程序返回
MOV 45H,#01H
LJMP S_18_RETURN
S_0E:
MOV 69H,#00H ;有按键,清零定时标志
JBC 02H,S_0E_0 ;长按,去判断A键B键
JBC 01H,S_0E_1 ;短按,去判断A键B键
INC 59H ;A键,分+1
SETB 05H ;置位,时改变标志
LJMP LOOP_0E
S_0E_0:
JBC 01H,S_0E_2 ;长按,B键,状态变为了01H,并子程序返回
MOV 45H,#01H ;A键,状态转为08H
LJMP S_0E_RETURN
S_0E_1: ;短按B键,分-1,并置位时改变标志
DEC 59H
SETB 05H
LJMP LOOP_0E
S_0E_2:
MOV 45H,#01H
S_0E_RETURN:
MOV 68H,#00H
RET
/*状态1C修理子程序*/
S_CLOCK2:
LOOP_1C:
MOV R0,#62H ;设置显示内容
MOV R1,#05H
MOV R5,#02H
LCALL COUNT_OUTPUT ;计算显示数据
LCALL SHOW ;显示
LCALL KEY_READ ;读键盘
JBC 00H,S_1C ;有键,则去判断长按短按
INC 69H ;无键,定时标志+1
MOV A,69H
CJNE A,#0FFH,LOOP_1C ;定时到,状态转为01H,子程序返回
MOV 45H,#01H
LJMP S_1C_RETURN
S_1C:
MOV 69H,#00H ;有按键,清零定时标志
JBC 02H,S_1C_0 ;长按,去判断A键B键
JBC 01H,S_1C_1 ;短按,去判断A键B键
INC 59H ;A键,分+1
SETB 05H ;置位,时改变标志
LJMP LOOP_1C
S_1C_0:
JBC 01H,S_1C_2 ;长按,B键,状态变为了01H,并子程序返回
MOV 45H,#01H ;A键,状态转为08H
LJMP S_1C_RETURN
S_1C_1: ;短按B键,分-1,并置位时改变标志
DEC 59H
SETB 05H
LJMP LOOP_1C
S_1C_2:
MOV 45H,#01H
S_1C_RETURN:
MOV 68H,#00H
RET
/*时间按秒增长子程序*/
CHANG_TIME:
JBC 03H,C_TIME ;秒定时标志是否为1,为1则去改变时间,否则子程序返回
LJMP C_RETURN
C_TIME:
MOV A,68H ;读出秒,加1,判断是否大于等于60,是则送#00H到68H,否则将秒写回68H
INC A
SETB 04H
CJNE A,#3CH,S ;仅当秒大于等于60时,才去改变分
MOV 68H,#00H
LJMP M0
S:
MOV 68H,A
LJMP C_RETURN
M0:
MOV A,59H ;读出分,加1,判断是否大于等于60,是则送#00H到59H,否则将秒写回59H
INC A
SETB 05H
CJNE A,#3CH,M1 ;仅当分大于等于60时,才去改变时
MOV 59H,#00H
LJMP H0
M1:
MOV 59H,A
LJMP C_RETURN
H0:
MOV A,58H ;读出时,加1,判断是否大于等于24,是则送#00H到58H,否则将秒写回58H
INC A
SETB 06H
CJNE A,#18H,H1 ;仅当时大于等于24时,才去改变日
MOV 58H,#00H
LJMP DAY0
H1:
MOV 58H,A
LJMP C_RETURN
DAY0:
MOV A,49H ;读出日,加1,判断是否大于等于31,是则送#01H到49H,否则将秒写回49H
INC A
SETB 07H
CJNE A,#1EH,DAY1 ;仅当日大于等于30时,才去改变月
MOV 49H,#01H
LJMP MON0
DAY1:
MOV 49H,A
LJMP C_RETURN
MON0:
MOV A,48H ;读出月,加1,判断是否大于等于13,是则送#01H到48H,否则将秒写回48H
INC A
SETB 08H
CJNE A,#0CH,MON1 ;仅当月大于等于13时,才去改变年
MOV 48H,#01H
LJMP YEARL0
MON1:
MOV 48H,A
LJMP C_RETURN
YEARL0:
MOV A,47H ;读出年(L),加1,判断是否大于等于100,是则送#00H到48H,否则将秒写回47H
INC A
SETB 09H
CJNE A,#64H,YEARL1 ;仅当年(L)大于等于100时,才去改变年(H)
MOV 47H,#00H
LJMP YAERH0
YEARL1:
MOV 47H,A
LJMP C_RETURN
YAERH0:
MOV A,46H ;读出年(H),加1,判断是否大于等于100,是则送#00H到48H,否则将秒写回46H
INC A
SETB 0AH
CJNE A,#64H,YEARH1
MOV 46H,#00H
LJMP C_RETURN
YEARH1:
MOV 46H,A
C_RETURN:
RET
/*数码管显示子程序,R0存显示内容首址,R1存位选首址 ,*/
SHOW:
MOV DPTR,#LED_DATA
S2:
MOV A,R1
RL A
RL A
MOV P2,A
MOV A,@R0
MOVC A,@A+DPTR
CPL A
MOV P0,A
INC R0
DEC R1
MOV R4,#01H
LCALL DELAY
DJNZ R5,S2
MOV R4,#01H
LCALL DELAY
RET
/*键盘扫描子程序*/
KEY_READ:
JB P1.0,NEXT
MOV R4,#64H
LCALL DELAY
JB P1.0,NEXT
SETB TR0
SETB 00H
CLR 01H
JNB P1.0,$
CLR TR0
JNB TF0,KEY_RETUN
SETB 02H
LJMP KEY_RETUN
NEXT:
JB P1.2,KEY_RETUN
MOV R4,#64H
LCALL DELAY
JB P1.2,KEY_RETUN
SETB TR0
SETB 00H
SETB 01H
JNB P1.2,$
CLR TR0
JNB TF0,KEY_RETUN
SETB 02H
LJMP KEY_RETUN
KEY_RETUN:
MOV TH0,#15H ;重赋T0定时初值
MOV TL0,#0A0H
CLR TF0
RET
/*定时器T1中断服务子程序*/
INT_T1:
PUSH ACC
DJNZ R6,INT_1
MOV R6,#50H
DJNZ R7,INT_1
MOV R7,#32H
SETB 03H
INT_1:
POP ACC
RETI
/*延时子程序,R2,R3为定时常数,R4为定时变量*/
DELAY:
D: MOV R2,#0AH
D0: MOV R3,#0AH
D1: DJNZ R3,D1
DJNZ R2,D0
DJNZ R4,D
RET
/*数码管显示代码,0~F*/
LED_DATA:
DB 03H,9FH,25H,0DH,99H,49H,41H,1FH
DB 01H,09H,11H,0C1H,63H,85H,61H,71H
END