;电子钟程序
;
;STC12C5A60S2 12MC 12T
;
;
;以下定义中断向量地址
ORG 0000H
LJMP CHUSI
ORG 0003H
RETI
ORG 000BH ;定时器0中断向量
LJMP DSQ0
ORG 0013H
RETI
ORG 001BH
RETI
ORG 0023H
RETI
ORG 002BH ;定时器2中断向量
RETI
NOP
NOP
NOP
NOP
ORG 0064H
;初始化和定义寄存器用途
CHUSI: CLR A ;清零
MOV 87H,A ;置CPU功率方式
MOV IE,A ;禁止中断
MOV IP,A ;禁止中断优先控制
MOV SCON,A ;关闭串行控制
MOV TMOD,A ;计数器控制
MOV TCON,A ;计数器控制
MOV SP,#080H ;设置栈底
;
MOV P0,#0FFH ;显示划驱动低有效
MOV P2,#0FFH ;显示位驱动,低有效
MOV P3,#0FFH ;按键,低电平有效
MOV 21H,#0 ;62.5mS计数器
MOV 22H,#0 ;
MOV 23H,#0 ;秒计数暂存位
MOV 24H,#10 ;分计数暂存位
MOV 25H,#9 ;时计数暂存位
MOV 26H,#2 ;日计数暂存位,上电为16
MOV 27H,#7 ;月计数暂存位,上电为7
MOV 28H,#1 ;星期计数器
CLR 0H ;时间/日期标志,0=时间,1=日期
MOV 30H,#0 ;
MOV 31H,#0 ;
MOV 32H,#0 ;
MOV 33H,#0H ;
;设置定时器0为16位计数器方式(65536-62500)
MOV TL0,#213 ;重装定时器0寄存器低位(T0=62.5毫微秒)
MOV TH0,#0BH ;重装定时器0高位重装入寄存器
NOP ;
;
NOP ; TMOD GATE C/T M1 M0 GATE C/T M1 M0
MOV TMOD,#01H ;定时/计数 0 0 0 0 0 0 0 1
;
NOP ; TCON TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
MOV TCON,#00H ;启动定时器0 0 0 0 0 0 0 0 0
;
;
MOV IP,#0H ;中断优先控制 X X PT2 PS PT1 PX1 PT0 PX0
; 0 0 0 0 0 0 0 0
;
;中断控制 EA -- ET2 ES ET1 EX1 ET0 EX0
MOV IE,#10001010B; 1 0 0 1 0 1 0
LJMP XIANSHI
NOP
NOP
ORG 0100H ;
XIANSHI:NOP
JNB P3.2,AJS4 ;查询按键 显示日期
MOV A,23H ;23H里有秒计数器
CJNE A,#5,M6 ;每分钟第5秒到第10秒显示日期
SETB 0H
LJMP D1
M6: CJNE A,#6,M7
SETB 0H
LJMP D1
M7: CJNE A,#7,M8
SETB 0H
LJMP D1
M8: CJNE A,#8,M9
SETB 0H
LJMP D1
M9: CJNE A,#9,M10
SETB 0H
LJMP D1
M10: CLR 0H ;非5 6 7 8 9 显示时间
LJMP D1 ;S4=1 没按
AJS4: SETB 0H ;S4=0 按下
SETB TR0 ;启动用
D1: MOV P0,#0FFH ;关闭显示划驱动,准备显示第一位
MOV P2,#0FFH ;关闭显示位驱动
JB 0,XSRQ1 ;BIT0为1显示日期
MOV B,#10 ;小时计数器0-23
MOV A,25H ;小时计数器
DIV AB ;小时计数器除10,商在A,余数在B
CJNE A,#0,SWW0 ;十位为0不显示
LCALL YSQ1 ;调用延时器1
LJMP D2
XSRQ1: MOV B,#10 ;月份计数器1-12
MOV A,27H ;月份计数器计数器
DIV AB ;小时计数器除10,商在A,余数在B
CJNE A,#0,SWW0 ;十位为0不显示
LCALL YSQ1 ;调用延时器1
LJMP D2
SWW0: LCALL YMQ ;调用译码器
MOV P0,A ;显示划驱动
CLR P2.0 ;显示第一位
LCALL YSQ1 ;调用延时器1
NOP
NOP
NOP
D2: MOV P0,#0FFH ;关闭显示划驱动,准备显示第二位
MOV P2,#0FFH ;关闭显示位驱动
JB 0,XSRQ2 ;BIT0为1显示日期
MOV B,#10 ;小时计数器0-23
MOV A,25H ;小时计数器
DIV AB ;小时计数器除10,商在A,余数在B
MOV A,B ;个位数在B
LCALL YMQ ;调用译码器
MOV P0,A ;显示划驱动
CLR P2.1 ;显示第二位
LCALL YSQ1 ;调用延时器1
LJMP D3
XSRQ2: MOV B,#10 ;月份计数器1-12
MOV A,27H ;月份计数器计数器
DIV AB ;小时计数器除10,商在A,余数在B
MOV A,B ;个位数在B
LCALL YMQ ;调用译码器
MOV P0,A ;显示划驱动
CLR P2.1 ;显示第二位
LCALL YSQ1 ;调用延时器1
NOP
NOP
NOP
D3: MOV P0,#0FFH ;关闭显示划驱动,准备显示第三位
MOV P2,#0FFH ;关闭显示位驱动
JB 0,XSRQ3 ;BIT0为1显示日期
MOV A,#0BFH ;中间划
MOV P0,A ;显示划驱动
CLR P2.2 ;显示第三位
LCALL YSQ1 ;调用延时器1
LJMP D4
XSRQ3: MOV A,#0F7H ;下边划
MOV P0,A ;显示划驱动
CLR P2.2 ;显示第三位
LCALL YSQ1 ;调用延时器1
NOP
NOP
NOP
D4: MOV P0,#0FFH ;关闭显示划驱动,准备显示第四位
MOV P2,#0FFH ;关闭显示位驱动
JB 0,XSRQ4 ;BIT0为1显示日期
MOV B,#10 ;分位计数器0-59
MOV A,24H ;分计数器
DIV AB ;分计数器除10,商在A,余数在B
LCALL YMQ ;调用译码器
MOV P0,A ;显示划驱动
CLR P2.3 ;显示第四位
LCALL YSQ1 ;调用延时器1
LJMP D5
XSRQ4: MOV B,#10 ;日期计数器1-31
MOV A,26H ;日期计数器计数器
DIV AB ;小时计数器除10,商在A,余数在B
CJNE A,#0,SWW4 ;十位为0不显示
LCALL YMQ ;调用译码器
MOV P0,A ;显示划驱动
CLR P2.3 ;显示第四位
LCALL YSQ1 ;调用延时器1
LJMP D5
SWW4: LCALL YMQ ;调用译码器
MOV P0,A ;显示划驱动
CLR P2.3 ;显示第位
LCALL YSQ1 ;调用延时器1
NOP
NOP
NOP
D5: MOV P0,#0FFH ;关闭显示划驱动,准备显示第五位
MOV P2,#0FFH ;关闭显示位驱动
JB 0,XSRQ5 ;BIT0为1显示日期
MOV B,#10 ;小时计数器0-23
MOV A,24H ;小时计数器
DIV AB ;小时计数器除10,商在A,余数在B
MOV A,B ;个位数在B
LCALL YMQ ;调用译码器
MOV P0,A ;显示划驱动
CLR P2.4 ;显示第五位
LCALL YSQ1 ;调用延时器1
LJMP D6
XSRQ5: MOV B,#10 ;月份计数器1-12
MOV A,26H ;月份计数器计数器
DIV AB ;小时计数器除10,商在A,余数在B
MOV A,B ;个位数在B
LCALL YMQ ;调用译码器
MOV P0,A ;显示划驱动
CLR P2.4 ;显示第五位
LCALL YSQ1 ;调用延时器1
NOP
NOP
NOP
D6: MOV P0,#0FFH ;关闭显示划驱动,准备显示第六位
MOV P2,#0FFH ;关闭显示位驱动
JB 0,XSRQ6 ;BIT0为1显示日期
MOV A,#0BFH ;中间划
MOV P0,A ;显示划驱动
CLR P2.5 ;显示第六位
LCALL YSQ1 ;调用延时器1
LJMP D7
XSRQ6: MOV A,#0F7H ;下边划
MOV P0,A ;显示划驱动
CLR P2.5 ;显示第六位
LCALL YSQ1 ;调用延时器1
NOP
NOP
NOP
D7: MOV P0,#0FFH ;关闭显示划驱动,准备显示第七位
MOV P2,#0FFH ;关闭显示位驱动
JB 0,XSRQ7 ;BIT0为1显示日期
MOV B,#10 ;秒计数器0-59
MOV A,23H ;秒计数器
DIV AB ;秒计数器除10,商在A,余数在B
LCALL YMQ ;调用译码器
MOV P0,A ;显示划驱动
CLR P2.6 ;显示第七位
LCALL YSQ1 ;调用延时器1
LJMP D8
XSRQ7: MOV A,#0F7H ;星期计数器
MOV P0,A ;显示划驱动
CLR P2.6 ;显示第七位
LCALL YSQ1 ;调用延时器1
NOP
NOP
D8: MOV P0,#0FFH ;关闭显示划驱动,准备显示第八位
MOV P2,#0FFH ;关闭显示位驱动
JB 0,XSRQ8 ;BIT0为1显示日期
MOV B,#10 ;秒计数器0-59
MOV A,23H ;秒计数器
DIV AB ;秒计数器除10,商在A,余数在B
MOV A,B ;个位数在B
LCALL YMQ ;调用译码器
MOV P0,A ;显示划驱动
CLR P2.7 ;显示第八位
LCALL YSQ1 ;调用延时器1
LJMP XIANSHI
XSRQ8: MOV A,28H ;星期计数器计数器
LCALL YMQ ;调用译码器
MOV P0,A ;显示划驱动
CLR P2.7 ;显示第八位
LCALL YSQ1 ;调用延时器1
LJMP XIANSHI
NOP
NOP
NOP
LJMP XIANSHI
LJMP XIANSHI
DSQ0: PUSH PSW ;程序状态字入栈
PUSH ACC ;累加器入栈
NOP ;空操作 每插入一个操作可增大每日误差115.2毫秒 每8天一秒
NOP ;
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV TL0,#197 ;重装定时器0寄存器低位(T0=62.5毫秒)( 减小变慢 增大变快)
MOV TH0,#0BH ;重装定时器0高位重装入寄存器(每调整一个数日误差1.3824秒)
SETB TR0 ;启动定时器0
INC 21H ;定时器0的第1计数器(62.5mS)
LCALL S30 ;查询调秒按键
MOV A,21H ;62.5毫秒+1
CJNE A,#8,P16 ;不到8 半秒则返回
LCALL AJ ;到半秒查询调时分键
LJMP DSQ0W
P16: CJNE A,#16,DSQ0W ;不到整秒时间则返回
MOV 21H,#0 ;62.5毫秒重新计数
INC 23H ;分计数+1
LCALL AJ ;调用按键
MOV A,23H ;比较
CJNE A,#60,DSQ0W ;60秒吗
MOV 23H,#0 ;秒重新计数
INC 24H ;分计数
MOV A,24H ;
CJNE A,#60,DSQ0W ;不到时间则返回
MOV 24H,#0 ;分重新计数
INC 25H ;小时计数
MOV A,25H ;
CJNE A,#24,DSQ0W ;24吗
MOV 25H,#0 ;重新计数
INC 28H ;星期加1
MOV A,28H
CJNE A,#7,RQJS ;每星期7天 显示 0 1 2 3 4 5 6
MOV 28H,#0
RQJS: INC 26H ;日期计数
MOV DPTR,#TSZS ;设置每月天数指示
MOV A,27H ;把当前月数送A
MOVC A,@A+DPTR ;读取该月应有天数
CJNE A,26H,DSQ0W ;比较,如相等,满月了,否则从中断返回
MOV 26H,#1 ;日寄存器置1
INC 27H ;月寄存器加1
MOV A,27H
CJNE A,#13,DSQ0W; 如等于13,月寄存器置1,否则从中断返回
MOV 27H,#1 ;
DSQ0W: POP ACC ;程序状态字出栈
POP PSW ;累加器出栈
RETI ;从定时器0中断返回
NOP
NOP
NOP
YMQ: MOV DPTR,#YMSJ ;设置译码数据地址指针
MOVC A,@A+DPTR ;读取译码数据
RET
RET
YMSJ: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0
NOP
NOP
RET ;返回
NOP
YSQ1: CLR P3.1
MOV 30H,#255 ;延时3
YSQ: NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ 30H,YSQ ;5
SETB P3.1
RET
TSZS: DB 0H,32,29,32,31 ;月中天数数据(+1)
DB 32,31,32,32,31
DB 32,31,32
NOP
NOP
NOP
AJ: NOP ;查询按键程序
JNB P3.3,S1 ;查询按键 小时 月
JNB P3.6,S2 ;查询按键 分钟 日
JNB P3.7,S3 ;查询按键 秒 星期
RET ;没有按键 返回
S1: JNB P3.2,S14 ;检查日期显示键 如有效调月份
MOV A,25H ;读取小时到A
CJNE A,#24,XY23 ;小于23吗
MOV 25H,#0 ;23+1=24(0)
RET
XY23: INC 25H ;
RET
NOP
S14: MOV A,27H ;读取月份到A
CJNE A,#12,XY12 ;小于12吗
MOV 27H,#1 ;12+1=1
RET
XY12: INC 27H ;
RET
RET
RET ;
NOP
S2: JNB P3.2,S24 ;检查日期显示键 如有效调月份
MOV A,24H ;读取分到A
CJNE A,#59,XY59 ;小于23吗
MOV 24H,#0 ;59+1=60(0)
RET
XY59: INC 24H ;
RET
NOP
S24: MOV DPTR,#TSZS ;设置每月天数指示
MOV A,27H ;把当前月数送A
MOVC A,@A+DPTR ;读取该月应有天数
DEC A
CJNE A,26H,XYDQY ;比较,如相等,满月了,
MOV 26H,#1 ;12+1=1
RET
XYDQY: INC 26H ;
RET
RET
RET ;
S3: JNB P3.2,S34 ;检查日期显示键 如有效调月份
RET
S34: MOV A,28H ;读取星期到A
CJNE A,#6,XY6 ;小于6吗
MOV 28H,#0 ;6+1=0
RET
XY6: INC 28H ;
RET
RET
RET ;
NOP
S30: JB P3.7,AJFH ;查询按键 秒 星期
JNB P3.2,AJFH ;检查日期显示键 如有效调月份
S31: MOV A,23H ;读取秒到A
CJNE A,#30,XY33 ;等于30吗
S331: MOV 23H,#0 ;等于30退到0
MOV 21H,#0
RET
XY33: JC S331
MOV 23H,#0
MOV 21H,#0
INC 24H ;分计数
MOV A,24H ;
CJNE A,#60,AJFH ;不到时间则返回
MOV 24H,#0 ;分重新计数
INC 25H ;小时计数 ;
AJFH: RET
NOP
RET
RET
RET ;
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
END
|