/*************************************************************************************** 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