;電子鐘程序
;
;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
|