时间控制器,灯可以亮,时间是正常走的,但就是蜂鸣器不响
- ORG 0000H
- LJMP MAIN
- ORG 000BH
- LJMP TIME
- ORG 0100H
-
- ;宏定义
- ;键位
- K0 BIT 20H.0
- K1 BIT 20H.1
- K2 BIT 20H.2
- K3 BIT 20H.3
- K4 BIT 20H.4
- ;暂存区
- ST DATA 68H
- MT DATA 69H
- HT DATA 6AH
- DT DATA 6BH
- MOUT DATA 6CH
- YLT DATA 6DH
- YHT DATA 6EH
- SPT DATA 21H ;移位指针
- ;时钟时间寄存区
- S DATA 60H
- M DATA 61H
- H DATA 62H
- D DATA 63H
- MOU DATA 64H
- YL DATA 65H
- YH DATA 66H
- FLAG DATA 67H
- ;闹钟时间寄存区
- SC DATA 50H
- MC DATA 51H
- HC DATA 52H
- DC DATA 53H
- MOUC DATA 54H
- YLC DATA 55H
- YHC DATA 56H
-
- ;时间显示缓冲区
- //存放数码管显示16位的数据
- SDL DATA 70H
- SDH DATA 71H
- POINT1 DATA 72H
- MDL DATA 73H
- MDH DATA 74H
- POINT2 DATA 75H
- HDL DATA 76H
- HDH DATA 77H
- DDL DATA 78H
- DDH DATA 79H
- MOUDL DATA 7AH
- MOUDH DATA 7BH
- YD0 DATA 7CH
- YD1 DATA 7DH
- YD2 DATA 7EH
- YD3 DATA 7FH
-
- //主程序
- MAIN:
- MOV TMOD,#01H ;T0工作方式1
- MOV TL0,#0B0H
- MOV TH0,#3CH ;50ms
- MOV R7,#20 ;20*50ms = 1s
- MOV S,#50
- MOV M,#59
- MOV H,#11
- MOV D,#11
- MOV MOU,#12
- MOV YL,#20
- MOV YH,#20
- MOV POINT1,#10 ;在TABLE中第10个对应“-”
- MOV POINT2,#10
- MOV SPT,#1 ;移位指针初始最低位为1
- SETB K0
- CLR K1 ;K1置1 (非暂停状态)
- CLR K2 ;K2置1 默认修改模式
- CLR P3.5 ;默认蜂鸣器非工作状态
- CLR P3.6 ;默认LED非工作状态
- SETB ET0
- SETB EA
- SETB TR0 ;开启定时器
-
- ;不断循环
- GO_ON:
- LCALL CHECK_KEY
- LCALL DISPLAY
- LCALL CHECK_CLOCK ;闹铃
- LCALL LIGHT_ON ;开灯
- LCALL LIGHT_OFF ;关灯
- SJMP GO_ON ;跳转循环
-
- ;定时子程序
- TIME:
- MOV TL0,#0B0H
- MOV TH0,#3CH
- DJNZ R7,TIME_END
- MOV R7,#20 ;循环20次 定时1s
- LCALL TIME_INC ;跳转到计时
- LCALL SAVE0 ;跳转到数据转移
- LCALL SEND_TO_DIS ;储存时间寄存器中的BCD
- TIME_END:
- RETI
- ;数码管显示子程序
- DISPLAY:
- MOV R0,#SDL ;数据缓存区指针
- MOV DPTR,#TABLE ;七段共阴数码管0-9显示
- MOV R1,#0 ;R1存放表示第几位的数字
-
- //P0口实现片选
- NEXT: MOV P0,R1 ;显示位连接P0
- MOV A,R1
- CLR C
- SUBB A,#8 //实现前8个向HMS跳转,后8个向YMD跳转
- JC HMS
- //P2口实现年月日
- DIAN1: //先判断是否位第10位,第10位需要有小数点
- CJNE R1,#10,DIAN2 ;跳转判断DIAN2
- MOV DPTR,#TABLE1
- MOV A,@R0 ;取显示数字
- MOVC A,@A+DPTR
- MOV P2,A ;显示年月日
- LCALL DELAY ;调用延时
- MOV DPTR,#TABLE
- SJMP GO
- DIAN2: //再判断是否位第12位,第12位也需要有小数点
- CJNE R1,#12,YMD ;若不是第10,12位,跳转YMD
- MOV DPTR,#TABLE1
- MOV A,@R0 ;取显示数字
- MOVC A,@A+DPTR
- MOV P2,A ;显示年月日
- LCALL DELAY ;调用延时
- MOV DPTR,#TABLE
- SJMP GO
-
- YMD: //正常输出没小数点的数字
- MOV A,@R0 ;取显示数字
- MOVC A,@A+DPTR
- MOV P2,A ;显示年月日
- LCALL DELAY ;调用延时
- SJMP GO
- //P1口实现时分秒
- HMS: MOV A,@R0 ;取显示数字
- MOVC A,@A+DPTR
- MOV P1,A ;显示时分秒
- LCALL DELAY ;调用延时
- SJMP GO
-
- GO: INC R1 ;显示位左移
- INC R0
- CJNE R1,#16,NEXT
- RET
- //共阳极,0亮1灭,共阴极,1亮0灭
- TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H ;七段共阴数码管0-9
- TABLE1: DB 0BFH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,87H,0FFH,0EFH,40H ;带小数点的七段共阴数码管0-9
- ;计时程序
- TIME_INC:
- SEC: INC S ;+1S
- MOV R6,S
- CJNE R6,#60,INC_END ;满60秒进位
- MOV R6,#0
- MOV S,R6
- SJMP MIN
- MIN: INC M ;+1M
- MOV R6,M
- CJNE R6,#60,INC_END ;满60分钟进位
- MOV R6,#0
- MOV M,R6
- SJMP HOUR
- HOUR: INC H ;+1H
- MOV R6,H
- CJNE R6,#24,INC_END ;满24小时进位
- MOV R6,#0
- MOV H,R6
- DAY: LCALL CHECK_Y ;检查平闰年
- MOV R6,FLAG
- CJNE R6,#1,PING
- MOV DPTR,#R_YEAR ;调用闰年月份表
- SJMP YGO
- PING: MOV DPTR,#P_YEAR ;调用平年月份表
- YGO: MOV A,MOU
- MOVC A,@A+DPTR
- INC A
- INC D ;+1D
- CJNE A,D,INC_END
- MOV R6,#1
- MOV D,R6
- SJMP MOUN
- MOUN: INC MOU ;+1M
- MOV R6,MOU
- CJNE R6,#13,INC_END ;第13个月进位
- MOV R6,#0
- MOV MOU,R6
- SJMP YEAR
- YEAR:
- INC YL ;+1Y低位
- MOV R6,YL
- CJNE R6,#100,INC_END
- MOV R6,#0
- MOV YL,R6
- INC YH ;+1Y高位
- MOV R6,YH
- CJNE R6,#100,INC_END
- MOV R6,#0
- MOV YH,R6
- INC_END:
- RET
- ;检查平闰年子程序
- CHECK_Y:
- MOV A,YL
- MOV B,#4
- DIV AB
- MOV A,B
- JNZ SET_FLAG
- MOV FLAG,#1
- SJMP CHECK_END
- SET_FLAG:
- MOV FLAG,#0
- CHECK_END:
- RET
- P_YEAR: DB 0,31,28,31,30,31,30,31,31,30,31,30,31 ;平年月份表
- R_YEAR: DB 0,31,29,31,30,31,30,31,31,30,31,30,31 ;闰年月份表
-
- ;将暂存区中的数据转为BCD码存入显示缓冲区
- SEND_TO_DIS:
- MOV A,ST
- LCALL H2B
- MOV SDL,R4
- MOV SDH,R5 ;存秒
-
- MOV A,MT
- LCALL H2B
- MOV MDL,R4
- MOV MDH,R5 ;存分
-
- MOV A,HT
- LCALL H2B
- MOV HDL,R4
- MOV HDH,R5 ;存时
-
- MOV A,DT
- LCALL H2B
- MOV DDL,R4
- MOV DDH,R5 ;存天
-
- MOV A,MOUT
- LCALL H2B
- MOV MOUDL,R4
- MOV MOUDH,R5 ;存月
-
- MOV A,YLT
- LCALL H2B
- MOV YD0,R4
- MOV YD1,R5 ;存年(低位)
-
- MOV A,YHT
- LCALL H2B
- MOV YD2,R4
- MOV YD3,R5 ;存年(高位)
- RET
-
- ;1ms延时子程序
- DELAY:
- MOV R3,#4
- DEL: MOV R2,#250
- DJNZ R2,$
- DJNZ R3,DEL
- RET
- ;
- H2B: MOV B,#10
- DIV AB
- MOV R5,A ;个位存到R5
- MOV R4,B ;十位存到R4
- RET
-
- ;查询按键子程序
- CHECK_KEY:
- MOV A,P3 ;读取P3按键状态
- CPL A;
- JZ CHECK_EXIT
- ACALL KEY_DELAY
- MOV A,P3 ;读取P3按键状态 确认是否有键按下
- CPL A
- JZ CHECK_EXIT
- JB ACC.0,ACT0 ;暂停/恢复键
- JB ACC.1,ACT1 ;闹钟键
- JB ACC.2,ACT2 ;换位键
- JB ACC.3,ACT3 ;+
- JB ACC.4,ACT4 ;-
- CHECK_EXIT:
- RET
-
- ;按键子程序
- ACT:
- ACT0: MOV A,P3 ;检测按键是否释放
- JNB ACC.0,ACT0 ;键未释放,则继续等待
- CPL K0 ;K0取反,在暂停/继续中转换
- JB K0,START
- CLR TR0 ;TR0=0,停止计时
- LJMP EXIT
- START: SETB TR0 ;TRO=1,开始计时
- CLR K1 ;默认回修改功能
- RET
-
- ;定时/修改按钮
- ACT1: MOV A,P3 ;检测按键是否释放
- JNB ACC.1,ACT1 ;键未释放,则继续等待
- CPL K2 ;取反闹铃使能开关
- JB K0,EXIT ;若K0未在暂停状态,则返回
- CPL K1 ;K1取反,0为修改,1为闹钟定时
- RET
-
- ;移位按钮
- ACT2:
- MOV A,P3 ;检测按键是否释放
- JNB ACC.2,ACT2 ;键未释放,则继续等待
- JB K0,EXIT ;若K0未在暂停状态,则返回
- MOV A,SPT
- RL A ;SPT移动(RL循环左移,RLC带进位左移,RL不带进位)
- MOV SPT,A
- JNB ACC.7,EXIT ;最多移到01000000
- MOV SPT,#1
- RET
-
- ;加
- ACT3: MOV A,P3 ;检测按键是否释放
- JNB ACC.3,ACT3 ;键未释放,则继续等待
- JB K0,EXIT ;若K0未在暂停状态,则返回
- JB K1,CL_INC
- SJMP UP_INC
- RET
-
- CL_INC: ;闹钟
- LCALL KEY_INC
- LCALL SEND_TO_DIS
- LCALL SEND1
- RET
-
- UP_INC: LCALL SAVE0
- LCALL KEY_INC
- LCALL SEND_TO_DIS
- LCALL SEND0
- RET
-
- ;减
- ACT4: MOV A,P3 ;检测按键是否释放
- JNB ACC.4,ACT4 ;键未释放,则继续等待
- JB K0,EXIT ;若K0未在暂停状态,则返回
- JB K1,CL_DEC
- SJMP UP_DEC
- RET
-
- CL_DEC: ;闹钟
- LCALL KEY_DEC
- LCALL SEND_TO_DIS
- LCALL SEND1
- RET
-
- UP_DEC: LCALL SAVE0
- LCALL KEY_DEC
- LCALL SEND_TO_DIS
- LCALL SEND0
- RET
-
- EXIT: RET
- KEY_DELAY:
- MOV R3,#24
- KEY_DEL:MOV R2,#0FAH
- DJNZ R2,$
- DJNZ R3,KEY_DEL
- RET
- ;数据转移子程序
- SAVE0: MOV ST,S
- MOV MT,M
- MOV HT,H
- MOV DT,D
- MOV MOUT,MOU
- MOV YLT,YL
- MOV YHT,YH
- RET
- ;将数据传给计时数据寄存器
- SEND0: MOV S,ST
- MOV M,MT
- MOV H,HT
- MOV D,DT
- MOV MOU,MOUT
- MOV YL,YLT
- MOV YH,YHT
- RET
- ;将数据传给闹钟数据寄存器
- SEND1: MOV SC,ST
- MOV MC,MT
- MOV HC,HT
- MOV DC,DT
- MOV MOUC,MOUT
- MOV YLC,YLT
- MOV YHC,YHT
- RET
-
- //按下按键年月日时分秒的加减处理
- ;+按键子程序
- KEY_INC:
- JB SPT.0,S_INC ;未按换位键 默认更改秒
- JB SPT.1,M_INC ;按一次更改分
- JB SPT.2,H_INC ;按两次更改小时
- JB SPT.3,D_INC ;按三次更改日
- JB SPT.4,MOU_INC ;按四次更改月
- JB SPT.5,YL_INC ;按五次更改年的个十位
- JB SPT.6,YH_INC ;按六次更改年的百千位
-
- S_INC: INC ST ;+1S
- MOV R6,ST
- CJNE R6,#60,EXIT_INC
- MOV R6,#0
- MOV ST,R6
- RET
-
- M_INC: INC MT ;+1M
- MOV R6,MT
- CJNE R6,#60,EXIT_INC
- MOV R6,#0
- MOV MT,R6
- RET
-
- H_INC: INC HT ;+1H
- MOV R6,HT
- CJNE R6,#24,EXIT_INC
- MOV R6,#0
- MOV HT,R6
- RET
-
- D_INC: LCALL CHECK_Y
- MOV R6,FLAG
- CJNE R6,#1,PING1
- MOV DPTR,#R_YEAR
- SJMP YGO1
- PING1: MOV DPTR,#P_YEAR ;暂存本月天数上限
- YGO1: MOV A,MOUT
- MOVC A,@A+DPTR
- INC A
- INC DT ;+1D
- CJNE A,DT,EXIT_INC
- MOV R6,#1
- MOV DT,R6
- RET
-
- MOU_INC:
- INC MOUT ;+1M
- MOV R6,MOUT
- CJNE R6,#13,EXIT_INC
- MOV R6,#1
- MOV MOUT,R6
- RET
-
- YL_INC: INC YLT ;+1Y低位
- MOV R6,YLT
- CJNE R6,#100,EXIT_INC
- MOV R6,#0
- MOV YLT,R6
- RET
-
- YH_INC: INC YHT ;+1Y高位
- MOV R6,YHT
- CJNE R6,#100,EXIT_INC
- MOV R6,#0
- MOV YHT,R6
- RET
-
- EXIT_INC:
- RET
-
- ;-按键子程序
- KEY_DEC:
- //根据移位指针SPT哪一位是1
- JB SPT.0,S_DEC ;未按换位键 默认更改秒
- JB SPT.1,M_DEC ;按一次更改分
- JB SPT.2,H_DEC ;按两次更改小时
- JB SPT.3,D_DEC ;按三次更改日
- JB SPT.4,MOU_DEC ;按四次更改月
- JB SPT.5,YL_DEC ;按五次更改年的个十位
- JB SPT.6,YH_DEC ;按六次更改年的百千位
- S_DEC:
- DEC ST ;-1s
- MOV R6,ST
- CJNE R6,#0FFH,EXIT_DEC
- MOV R6,#59
- MOV ST,R6
- RET
- M_DEC:
- DEC MT ;-1m
- MOV R6,MT
- CJNE R6,#0FFH,EXIT_DEC
- MOV R6,#59
- MOV MT,R6
- RET
- H_DEC:
- DEC HT ;-1h
- MOV R6,HT
- CJNE R6,#0FFH,EXIT_DEC
- MOV R6,#23
- MOV HT,R6
- RET
-
- D_DEC: LCALL CHECK_Y
- MOV R6,FLAG
- CJNE R6,#1,PING2
- MOV DPTR,#R_YEAR
- SJMP YGO2
- PING2: MOV DPTR,#P_YEAR
- YGO2: MOV A,MOUT
- MOVC A,@A+DPTR ;暂存本月天数上限
- DEC DT ;-1D
- MOV R6,DT
- CJNE R6,#0,EXIT_INC
- MOV R6,A
- MOV DT,R6
- RET
-
- MOU_DEC:
- DEC MOUT ;-1MO
- MOV R6,MOUT
- CJNE R6,#0,EXIT_DEC
- MOV R6,#12
- MOV MOUT,R6
- RET
- YL_DEC:
- DEC YLT ;-1Y(低位)
- MOV R6,YLT
- CJNE R6,#0FFH,EXIT_DEC
- MOV R6,#99
- MOV YLT,R6
- RET
- YH_DEC:
- DEC YHT ;-1Y(低位)
- MOV R6,YHT
- CJNE R6,#0FFH,EXIT_DEC
- MOV R6,#99
- MOV YHT,R6
- RET
- EXIT_DEC:
- RET
-
- ;闹钟响铃子程序
- CHECK_CLOCK: ;判断是否响铃
- MOV R0,#M
- MOV R1,#MC
- MOV R2,#5
- CHECK_NEXT: ;
- MOV A,@R0
- SUBB A,@R1 ;判断当前时刻是否是闹铃时刻
- CLR C
- JNZ CLOC_EXIT
- INC R0
- INC R1
- DJNZ R2,CHECK_NEXT
- LCALL TIMEOUT ;分 时 日 月 年均满足则调用响铃程序
- RET
-
- CLOC_EXIT:
- CLR P3.5
- RET
- ;响铃程序
- TIMEOUT:
- JNB K2,BUZ_END ;按下按键停止响铃
- BUZ: SETB P3.5
- LCALL BUZ_DELAY
-
- BUZ_DELAY: ;延时
- MOV R3,#250
- BUZ_T: MOV R2,#40
- DJNZ R2,$
- DJNZ R3,BUZ_T
- RET
- BUZ_END:
- CLR P3.5
- RET
-
- ;亮灯子程序
- LIGHT_ON:
- MOV A,#12
- CJNE A,H,TTE3
- MOV A,#00
- CJNE A,M,TTE3
- MOV A,#00
- CJNE A,S,TTE3
- SETB P3.6 ;从12:00:00开始亮
- TTE3:
- RET
- LIGHT_OFF:
- MOV A,#23;CMP_LED_START
- CJNE A,H,TTE4
- MOV A,#00
- CJNE A,M,TTE4
- MOV A,#00
- CJNE A,S,TTE4
- CLR P3.6 ;到21:00:00关灯
- TTE4:
- RET
-
- END
- R_YEAR: DB 0,31,29,31,30,31,30,31,31,30,31,30,31 ;
- TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H ;
-
- END
复制代码 |