
任务:实现年、月、日、时间、星期的显示,通过单键转换实现日期与时间的调换调整,同时可通过按键来调整日期与时间。
硬件:STCC52型单片机、一片频率为11.0592MHz的晶振片、三片74HC573锁存器、6块共阴极数码管、8个发光二极管、4个按键、一个压电式蜂鸣器等。
硬件参数:(1)发光二极管采用共阳极排列方式,一般普通发光二极管的工作电压为1.6~2.1V,工作电流为5~20mA。在这个单片机系统上,发光二极管的工作电压约为1.8V,工作电流约为4.5mA。
(2)74HC573为8输入8输出锁存器,工作电压为5伏,OE为片选端,LE为锁存允许端。OE为低电平,LE为高电平时锁存数据;当LE变为低电平时不允许新数据输入,输出不变;当OE为高电平时,不选中此芯片。
(3)压电式蜂鸣器是以压电陶瓷的压电效应,来带动金属片的振动而发声的,压电式蜂鸣器是以方波来驱动,所以在程序中改变P2.5引脚输出波形的频率,就可以调整控制蜂鸣器音调,产生各种不同音色、音调的声音。另外,改变输出电平的高低电平占空比,则可以控制蜂鸣器的声音大小。
(4)LED 数码管中各段发光二极管的伏安特性和普通二极管类似,只是正向压降较大,正向电阻也较大。在一定范围内,其正向电流与发光亮度成正比。由于常规的数码管起辉电流只有1~2 mA,最大极限电流也只有10~30 mA,所以它的输入端在5 V电源的电路信号相接时,一定要串加限流电阻,以免损坏器件。此板用的是共阴7段数码管,由公共端控制位。
操作说明:上电后6个数码管显示为时间12.00.00,8个数码管显示为星期一。按下按键2不动,数码管转而显示日期00.01.01,前两位表示年份,中间两位表示月份,后面两位表示日,松开按键2回到时间显示;按下按键3不动,数码管转而显示设置闹钟的时间00.00. 0,前两位为闹钟的小时,中间为闹钟的分,后面一位为是否开启闹铃的标志,“0”表示关闹钟,“1”表示开闹钟,松开按键3回到时间显示;按键4供用户调整时间,按下按键4大约1秒钟,当听到“嘀”的一声说明已进入时间调整程序,此时按键1用来调整小时,按一下小时加1,按键2用来调整分钟,按一下分钟加1,按键3用来调整星期,按一下星期加1;继续按一下按键4,则进入调整日期程序,此时按键1用来调整年份,按键2用来调整月份,按键3用来调整日,按下其中一个按键相应的位加1;继续按一下按键4,则进入设置闹钟程序,按键1用来调整闹钟的小时,按键2用来调整闹钟的分钟,按键3用来开启或是关闭闹钟,按下其中一个按键相应的位加1;再按一下按键4,则跳出调整时间程序,在此情况下如果时间到达设定的闹铃时间,闹铃响起,要想关掉闹铃可按一下按键1即可停止闹铃。
硬件图:
总程序流程图如下:
本组总程序如下:
SECOND EQU 30H
MINITE EQU 31H
HOUR EQU 32H
DAY EQU 33H
MOON EQU 34H
YEAR_L EQU 35H
YEAR_H EQU 36H
MINCLK EQU 37H
HOURCLK EQU 38H
XQ EQU 39H
TZK1 BIT P3.4 ;位P3.4为按键1
TZK2 BIT P3.5 ;位P3.5为按键2
TZK3 BIT P3.6 ;位P3.6为按键3
SWITCH BIT P3.7 ;位P3.7为按键4
DISPBUF1 EQU 40H
DISPBIT EQU 48H
T2SCNTA EQU 49H
T2SCNTB EQU 4AH
DISPBUF2 EQU 50H
DISPBUF3 EQU 60H
dula BIT P2.6
wala BIT P2.7
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP INT_T0
START: MOV SECOND,#0 ;设置初始时间值
MOV MINITE, #0
MOV HOUR, #12
MOV DAY, #1
MOV MOON, #1
MOV YEAR_L, #00H
MOV YEAR_H, #20H
MOV HOURCLK, #0
MOV MINCLK, #0
MOV DISPBIT, #6
MOV T2SCNTA, #0
MOV T2SCNTB, #0
MOV 60H,#0
MOV 61H,#0
LCALL DISP
MOV TMOD,#01H ;定时器0工作在方式1
MOV TH0,#0F7H ;定时器初值设置
MOV TL0, #0AH
SETB TR0 ;开启定时器
SETB ET0
SETB EA
MOV XQ, #0
CLR F0 ;显示标志位
MAIN: JB TZK1, CHANGE1
LCALL DELY10MS
JB TZK1, CHANGE1
SETB P2.3 ;按键1按下停止响铃
CHANGE1:JB TZK2,CHANGE2 ;年月日切换
LCALL DELY10MS
JB TZK2, CHANGE2
MOV 60H, #1
JNB TZK2, $
MOV 60H, #0
CHANGE2:JB TZK3,ADJUST ;闹钟切换
LCALL DELY10MS
JB TZK3, ADJUST
MOV 60H, #2
JNB TZK3, $
MOV 60H, #0
ADJUST: JB SWITCH, MAIN
LCALL DELAY1S
JB SWITCH,MAIN ;按键4按下1秒确定要调整时间
CLR P2.3 ;发出提示音可开始调整时间
ACALL DELY10MS
SETB P2.3
ACALL ADJUST_1
ACALL ADJUST_2
ACALL ADJUST_3
AJMP MAIN ;返回主程序
;.......小时、分、星期键盘调整程序............
ADJUST_1:JNB SWITCH,$ ;小时调整
JB TZK1, NK4
LCALL DELY10MS
JB TZK1,NK4 ;按键1按下
INC HOUR ;小时寄存器加1
MOV A, HOUR
CJNE A, #24, NH24
MOV HOUR,#0 ;小时寄存器满24变为0
NH24: LCALL DISP ;调用时间变更子程序
JNB TZK1, $
NK4: JB TZK2,NK5 ;分调整
LCALL DELY10MS
JB TZK2,NK5 ;按键2按下
INC MINITE ;分钟寄存器加1
MOV A, MINITE
CJNE A, #60, NM60
MOV MINITE,#0 ;分钟满60变为0
NM60:LCALL DISP ;调用时间变更子程序
JNB TZK2, $
NK5: JB TZK3,NK6 ;星期调整
LCALL DELY10MS
JB TZK3,NK6 ;按键3按下
INC XQ ;星期寄存器加1
MOV A,XQ
CJNE A, #7,NXQ7
MOV XQ,#0 ;星期寄存器满7变为0
NXQ7: LCALL DISP ;调用时间变更子程序
JNB TZK3,$
NK6: JB SWITCH, ADJUST_1
LCALL DELY10MS
JB SWITCH,ADJUST_1 ;退出小时、分、星期调整程序
INC 60H ;显示标志寄存器加1
RET
;.......年、月、日键盘调整程序..........
ADJUST_2:JNB SWITCH,$ ;年低两位调整
JB TZK1, NK1
LCALL DELY10MS
JB TZK1,NK1 ;按键1按下
INC YEAR_L ;年低位加1
MOV A, YEAR_L
CJNE A, #H, NY100
MOV YEAR_L,#00H ;年低位到100变为0
NY100: LCALL DISP ;调用时间变更子程序
JNB TZK1, $
NK1: JB TZK2,NK2 ;月调整
LCALL DELY10MS
JB TZK2,NK2 ;按键2按下
INC MOON ;月寄存器加1
MOV A, MOON
CJNE A, #13,NM12
MOV MOON,#01H ;月寄存器满13变为0
NM12: LCALL DISP
JNB TZK2, $
NK2:JB TZK3,NK3 ;日调整
LCALL DELY10MS
JB TZK3,NK3 ;按键3按下
INC DAY ;日寄存器加1
MOV A, MOON
CJNE A, #2, N1
LCALL JUDGE_Y1 ;2月则调用润、平年判断子程序
AJMP NS
N1:LCALL JUDGE_M1 ;不是2月则调用月判断子程序
NS:LCALL DISP ;调用时间变更子程序
JNB TZK3, $
NK3:JB SWITCH,ADJUST_2
LCALL DELY10MS
JB SWITCH,ADJUST_2 ;退出年、月、日调整程序
INC 60H ;显示标志寄存器加1
RET
;........闹钟小时、分钟调整程序........
ADJUST_3:JNB SWITCH,$ ;设置闹钟小时
JB TZK1, NK7
LCALL DELY10MS
JB TZK1,NK7 ;按键1按下
INC HOURCLK ;闹钟小时寄存器加1
MOV A, HOURCLK
CJNE A, #24, NHC24
MOV HOURCLK,#0 ;闹钟小时寄存器满24清0
NHC24: LCALL DISP
JNB TZK1, $
NK7:JB TZK2,NK8 ;设置闹钟分钟
LCALL DELY10MS
JB TZK2,NK8 ;按键2按下
INC MINCLK ;闹钟分钟寄存器加1
MOV A, MINCLK
CJNE A, #60, NMC60
MOV MINCLK,#0 ;闹钟分钟寄存器满60清0
NMC60: LCALL DISP
JNB TZK2, $
NK8:JB TZK3,NK9 ;设置是否开启闹钟,1表示开,0表示关
LCALL DELY10MS
JB TZK3,NK9 ;按键3按下
JB F0, CLOSE
SETB F0 ;闹钟标志位置1
MOV 61H,#1 ;闹钟开启显示1
LCALL DISP ;调用时间变更子程序
JNB TZK3, $
AJMP NK9
CLOSE: CLR F0
MOV 61H, #0
LCALL DISP
JNB TZK3, $
NK9: JB SWITCH, ADJUST_3
LCALL DELY10MS
JB SWITCH, ADJUST_3
MOV 60H,#0
RET
;.......键盘抖动10毫秒延时子程序程序...........
DELY10MS: MOV R6, #10
D1: MOV R7, #248
DJNZ R7, $
DJNZ R6, D1
RET
;.......延时1秒子程序..............
DELAY1S: MOV R5, #30
D2: MOV R4, #100
D3: MOV R3, #248
DJNZ R3, $
DJNZ R4, D3
DJNZ R5, D2
RET
;.......时间变更子程序...........
DISP: MOV A,#DISPBUF1 ;小时、分、秒的顺序存储
ADD A, #6
MOV R1, A
MOV A, HOUR
MOV B, #10
DIV AB
MOV @R1,A ;小时高位数据存到46H
DEC R1
MOV A, B
ORL A, #10H
MOV @R1,A ;小时低位数据存到45H
DEC R1
MOV A, MINITE
MOV B, #10
DIV AB
MOV @R1,A ;分钟高位数据存到44H
DEC R1
MOV A, B
ORL A, #10H
MOV @R1,A ;分钟低位数据存到43H
DEC R1
MOV A, SECOND
MOV B, #10
DIV AB
MOV @R1,A ;秒高位数据存到42H
DEC R1
MOV A, B
MOV @R1,A ;秒低位数据存到41H
MOV A,#DISPBUF2 ;年月日的顺序存储
ADD A, #6
MOV R1, A
MOV A, YEAR_L
MOV B, #10
DIV AB
MOV @R1,A ;年份高位数据存到56H
DEC R1
MOV A, B
ORL A, #10H
MOV @R1,A ;年份低位数据存到55H
DEC R1
MOV A, MOON
MOV B, #10
DIV AB
MOV @R1,A ;月份高位数据存到54H
DEC R1
MOV A, B
ORL A, #10H
MOV @R1,A ;月份低位数据存到53H
DEC R1
MOV A, DAY
MOV B, #10
DIV AB
MOV @R1,A ;日高位数据存到52H
DEC R1
MOV A, B
MOV @R1,A ;日低位数据存到51H
MOV A,#DISPBUF3 ;闹钟小时、分的顺序存储
ADD A, #6
MOV R1, A
MOV A, HOURCLK
MOV B, #10
DIV AB
MOV @R1,A ;闹钟小时高位存到66H
DEC R1
MOV A, B
ORL A, #10H
MOV @R1,A ;闹钟小时低位存到65H
DEC R1
MOV A, MINCLK
MOV B, #10
DIV AB
MOV @R1,A ;闹钟分钟高位存到H
DEC R1
MOV A, B
MOV @R1,A ;闹钟分钟低位存到63H
RET
;.......中断程序............
INT_T0: MOV TH0,#0F7H ;重新设置初值
MOV TL0, #0AH
INC T2SCNTA
MOV A, T2SCNTA
CJNE A, #40, DISPLAY
MOV T2SCNTA, #00H
INC T2SCNTB
MOV A, T2SCNTB
CJNE A, #10, DISPLAY
MOV T2SCNTB,#00H ;到达1秒T2SCNTB清0
LCALL DISP
INC SECOND ;秒寄存器加1
MOV A, SECOND
CJNE A, #60, DISPLAY
MOV SECOND,#00H ;秒寄存器满60清0
; SETB P2.3
INC MINITE ;分钟寄存器加1
JNB F0,NEXT ;闹钟标志位为0则跳转至NEXT
MOV 27H, HOUR
MOV A, HOURCLK
CJNE A,27H,NEXT ;时间小时与闹钟小时不一样则跳NEXT
MOV 28H, MINITE
MOV A, MINCLK
CJNE A,28H,NEXT ;时间分钟与闹钟分钟不一样则跳NEXT
CLR P2.3 ;符合设定时间则响铃
NEXT: MOV A, MINITE
CJNE A, #60, DISPLAY
MOV MINITE,#00H ;分钟寄存器满60清0
INC HOUR ;小时寄存器加1
MOV A, HOUR
CJNE A, #24, DISPLAY
MOV HOUR,#00H ;小时寄存器满24清0
INC DAY ;日寄存器加1
INC XQ ;星期寄存器加1
MOV A, XQ
CJNE A, #7, NEXT1
MOV XQ,#0 ;星期寄存器清0
NEXT1: MOV A, MOON
CJNE A,#2,NEXT2 ;不是二月则跳到NEXT2
LCALL JUDGE_Y ;二月则跳到JUDGE_Y子程序
AJMP NEXT3
NEXT2: LCALL JUDGE_M ;跳到JUDGE_M子程序
NEXT3: MOV A, MOON
CJNE A,#13,DISPLAY ;月份寄存器不等于13则跳DISPLAY
MOV MOON,#1 ;月份到13变为1
INC YEAR_L ;年份低位寄存器加1
MOV A, YEAR_L
CJNE A,#100,DISPLAY ;不到100则跳DISPLAY
INC YEAR_H ;年份高位寄存器加1
MOV A, YEAR_H
CJNE A, #100, DISPLAY
MOV YEAR_H, #20
AJMP DONE
DISPLAY: CLR P2.5
MOV A, XQ
MOV DPTR, #TABLEXQ
MOVC A,@A+DPTR
MOV P1, A
SETB P2.5
CLR P2.5
MOV A, 60H
CJNE A, #0,Y1
;.......小时、分、秒显示程序..........
MOV A, #DISPBUF1
ADD A, DISPBIT
MOV R0, A
MOV A,@R0
MOV DPTR, #TABLE
MOVC A,@A+DPTR
MOV P0, A
SETB dula
CLR dula
MOV A, DISPBIT
MOV DPTR, #TAB
MOVC A,@A+DPTR
MOV P0, A
SETB wala
CLR wala
DEC DISPBIT
MOV A, DISPBIT
CJNE A, #00H, DONE
MOV DISPBIT, #06H
AJMP DONE
;.........年月日显示程序..........
Y1: CJNE A, #1,Y2
MOV A, #DISPBUF2
ADD A, DISPBIT
MOV R0, A
MOV A,@R0
MOV DPTR, #TABLE
MOVC A,@A+DPTR
MOV P0, A
SETB dula
CLR dula
MOV A, DISPBIT
MOV DPTR, #TAB
MOVC A,@A+DPTR
MOV P0, A
SETB wala
CLR wala
DEC DISPBIT
MOV A, DISPBIT
CJNE A, #00H,DONE
MOV DISPBIT, #06H
AJMP DONE
;.........闹钟显示程序..........
Y2: MOV A, #DISPBUF3
ADD A, DISPBIT
MOV R0, A
MOV A,@R0
MOV DPTR, #TABLE
MOVC A,@A+DPTR
MOV P0, A
SETB dula
CLR dula
MOV A, DISPBIT
MOV DPTR, #TAB1
MOVC A,@A+DPTR
MOV P0, A
SETB wala
CLR wala
DEC DISPBIT
MOV A, DISPBIT
CJNE A, #00H, DONE
MOV DISPBIT, #06H
DONE: RETI
;.......判断闰年子程序。。。
JUDGE_Y: MOV A, YEAR_L
ANL A,#01H ;年低位寄存器数值存到A中
CJNE A,#00H,L1 ;不为0跳L1
MOV A,YEAR_H
MOV B,#4 ;为0判断是否能被4整除
DIV AB
MOV A, B
CJNE A,#0,PINGNIAN ;年份不能被4整除即平年则跳PINGNIAN1
LJMP L2 ;闰年则跳到L22
L1: MOV A, YEAR_L
MOV B, #4
DIV AB
MOV A, B
CJNE A, #0, PINGNIAN
L2: MOV A,DAY ;为0则为闰年
CJNE A,#30,L3 ;闰年为29天
MOV DAY, #1
INC MOON
PINGNIAN: MOV A, DAY
CJNE A,#29,L3 ;平年为28天
MOV DAY, #1
INC MOON
L3: RET
;.......判断月份大小。。。
JUDGE_M: MOV A, MOON
CJNE A,#4,V1 ;不是4月则跳到V1
AJMP V0
V1: CJNE A,#6,V2 ;不是6月则跳到V2
AJMP V0
V2: CJNE A,#9,V3 ;不是9月则跳到V3
AJMP V0
V3: CJNE A,#11,V4 ;不是11月则跳V4
V0: MOV A, DAY
CJNE A,#31,V5 ;小月为30天
MOV DAY, #1
INC MOON ;月寄存器加1
AJMP V5
V4: MOV A, DAY
CJNE A,#32,V5 ;大月为31天
MOV DAY, #1
INC MOON ;月寄存器加1
V5: RET
;......调整2月份里日子程序1........
JUDGE_Y1:MOV A,YEAR_L ;年低位寄存器数值存到A中
CJNE A,#0,L11 ;不为0跳L11
MOV A,YEAR_H
MOV B,#4 ;为0判断是否能被4整除
DIV AB
MOV A, B
CJNE A,#0,PINGNIAN1 ;年份不能被4整除即平年则跳PINGNIAN1
LJMP L22 ;闰年则跳到L22
L11: MOV A, YEAR_L
MOV B, #4
DIV AB
MOV A, B
CJNE A, #0, PINGNIAN1
L22: MOV A,DAY ;为0则为闰年
CJNE A,#30,L33 ;闰年为29天
MOV DAY, #1
PINGNIAN1: MOV A, DAY
CJNE A,#29,L33 ;平年为28天
MOV DAY, #1
L33: RET
;......调整日子程序2.........
JUDGE_M1: MOV A, MOON
CJNE A,#4,V11 ;不是4月则跳到V11
AJMP V00
V11: CJNE A,#6,V22 ;不是6月则跳到V22
AJMP V00
V22: CJNE A,#9,V33 ;不是9月则跳到V33
AJMP V00
V33: CJNE A,#11,V44 ;不是11月则跳V44
V00: MOV A, DAY
CJNE A,#31,V55 ;小月为30天
MOV DAY, #1
AJMP V55
V44: MOV A, DAY
CJNE A,#32,V55 ;大月为31天
MOV DAY, #1
V55: RET
TABLEXQ: DB 0F9H, 0A4H, 0B0H, 99H, 92H, 82H, 0F8H
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,00H,00H,00H,00H
DB 00H,00H,0BFH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,87H,0FFH,0EFH
TAB1: DB 0FFH, 0DFH, 0FFH, 0F7H, 0FBH, 0FDH, 0FEH
TAB: DB 0FFH, 0DFH, 0EFH, 0F7H, 0FBH, 0FDH, 0FEH
END
