?? clock.txt
字號:
;寄存器配置:(時間和日期)
; 第3組(18~1FH)(RS1、RS0=11)R0~R3,公歷年月日;
; R4~R7,時間的時、分、秒、百分之一秒(0.01秒)
; 第2組(10~17H)(RS1、RS0=10)計算農歷日期存儲中間臨時數據
; 第1組(08~0FH)(RS1、RS0=01)鍵盤處理程序存儲
; 鬧鐘設置狀態:R4、R5設置時間時、分,R6、R7計算分鐘數
; 萬年歷狀態:R0~R3查看的公歷年月日,R6、R7農歷月日,R4、R5總天數
; 時間設置時:直接在第3組寄存器操作
; 第0組(00~07H)(RS1、RS0=00)計算中間值臨時存儲器
;
;總天數、星期、當天分鐘計數器、農歷日期寄存器
; 30H、31H--距1925.1.1日總天數
; 32H--高四位星期幾,低四位與33H當天的分鐘數
; 34~37H--農歷年月日
;寄存器配置:(鬧鐘),兩個字節為一個單位
; 低地址最高位表示是否設置鬧鐘,低四位與27H為鬧鐘時間(當天的分鐘數)
; 鬧鐘1:28H、29H,星期一到五鬧鐘
; 鬧鐘2:2AH、2BH,配置與鬧鐘1相同
; 鬧鐘3:2CH、2DH,為每日鬧鐘
; 鬧鐘4:2EH、2FH,為一次性鬧鐘
;運行狀態寄存器:27H單元,00H,正常的時間顯示模式
; 1xH,鬧鈴設置模式,0~1位第幾個鬧鐘(0~3號),第3位設置時(0)和分(1)
; 2xH,萬年歷查看模式,0~3分別加減10年、1年、1月、1日,1有效
; 4xH,時間日期設置,低四位都是0設置年,第0~3位分別為1時設置月、日、時、分(加減1)
;方波信號:位地址的07H、06H分別為1秒和0.5秒等脈寬信號,用于控制設置時閃爍顯示
;顯示緩沖區:6F~7F單元,分別為星期、年月日、時分、農歷月日,星期1個單元、年4個單元、其余2個單元
;在計算過程中所示用的位寄存器:
; 在計算農歷時用00H位(位地址)表示是否閏月
; y年m月的天數用25H單元存儲臨時數據,01H位(位地址)表示當月是29天或30天
; 05H計時滿一天后或者調整日期后請求進行農歷日期計算標志為
; 04H調整小時或分鐘后重新計算當天分鐘數請求標識
; 06H、07H周期1秒和0.5秒的方波信號,前者用于秒閃爍,后者調整項閃爍
;****************************************************************************************
ORG 0000H
;開機及復位后從第一行起運行
LJMP 0080H ;INITTHECLOCK
ORG 0003H
;INT0中斷服務程序,若有鍵按下則產轉入鍵處理
LJMP THEKEYDOWNSERVER ;900H
ORG 000BH
;定時/計數器0中斷服務程序,預計每10毫秒產生一次中斷
LJMP SETTIMEVALUE ;0300H
ORG 001BH
;定時/計數器1中斷服務程序,用于延時5秒后將狀態寄存器復位為00H
PUSH A
DEC 03H
MOV A, 03H
JNZ TIMER1RET
;按鍵后16秒中如果沒有其他按鍵操作,自動轉換為時間顯示狀態
MOV A, 27H
JZ TIMER1SERVERRET ;如果是狀態0,直接返回
TIMER1STATE1:
JNB 3CH, TIMER1STATE2
PUSH PSW ;如果是在鬧鐘設置狀態下調用鬧鐘設置程序
MOV PSW, #00001000B
LCALL SETALARMTIME
POP PSW
AJMP TIMER1SERVERRET
TIMER1STATE2:
JNB 3DH, TIMER1STATE3
AJMP TIMER1SERVERRET ;如果在萬年歷查看方式下直接換到時間顯示狀態
TIMER1STATE3:
JNB 3EH, TIMER1SERVERRET
;如果在時間設置狀態下,更改當前分鐘數
SETB 05H ;設置農歷日期計算請求標識
JNB 04H, TIMER1SERVERRET
PUSH PSW
PUSH B
MOV PSW, #00011000B ;
MOV A, R4 ;如果調整了時間,重新計算當天分鐘數
MOV B, #60
MUL AB
ADD A, R5
MOV 33H, A
MOV A, B
ADDC A, #0
MOV 32H, A
MOV R6, #0 ;秒清零
CLR 04H
POP B
POP PSW
;AJMP TIMER1SERVERRET
TIMER1SERVERRET:
MOV 27H, #00H
CLR TR1
TIMER1RET:
POP A
RETI
;****************************************************************************************
ORG 0080H
INITTHECLOCK:
MOV SP, #38H
JNB 08H, INITRESET
MOV PSW, #00011000B ;使用3組寄存器(0、1、2、3四組寄存器)
MOV R7, #00 ;初始時間:00:00:00.00
MOV R6, #00
MOV R5, #00
MOV R4, #00
MOV R3, #15 ;初始日期:2000.1.1
MOV R2, #12
MOV R1, #0D4H
MOV R0, #7
MOV 33H, #0 ;初始當天分鐘計數器,32H高4位為星期
MOV 32H, #0
MOV 27H, #0
SETB 08H; 標識上電啟動,在復位啟動時不初始化時間日期
SETB 05H ;
INITRESET:
MOV PSW, #00H
MOV R0, #28H
LOOPINIT:
MOV @R0, #00
INC R0
CJNE R0, #30H, LOOPINIT
CLR P1.7
CLR P2.2
MOV IE, #10001011B ;開定時/計數器0、1中斷,開外部中斷0,關其余中斷
SETB IT0 ;設置INT0為負邊沿觸發
MOV IP, #00000010B ;設置定時/計數器0的中斷優先級為高
MOV TMOD, #00010010B ;定義定時/計數器0計數模式,與INT0無關,計數模式為8位自動重裝模式
;定義定時/計數器1計數模式,與INT1無關,計數模式為16位計數模式
MOV TH0, #6 ;擬計數脈沖頻率為25K,計數滿250時間為10毫秒
MOV TL0, #6
SETB TR0 ;啟動定時/計數器0
MOV PSW, #00000000B
MOV P2, #11111111B
;顯示字符、鬧鈴檢測比較循環程序
DISPLAYPREPARATIVE:
JNB 05H, LUNARDATETODISPLAY
CLR 05H
PUSH PSW ;計算農歷日期
MOV PSW, #00010000B
ACALL SETLUNARDATE
POP PSW
LUNARDATETODISPLAY:
LCALL ALARMCLOCK ;鬧鈴檢測及服務程序
MOV DPTR, #0F90H ;數字1~9的共陰極顯示碼首地址
MOV A, 27H ;取運行狀態寄存器,以選擇顯示方式
JNZ DISABNORMAL
DISPLAYNORMAL:
MOV A, 32H ;正常時間顯示模式下,取星期顯示碼
SWAP A
ANL A, #0FH
JNZ DISWEEKDAY
MOV A, #8
DISWEEKDAY:
MOVC A, @A+DPTR
MOV 6FH, A
MOV R0, #19H ;取年分顯示碼,共4位
MOV R1, #70H
ACALL DISYEARCODE
MOV R0, #1AH ;取日期(月日)顯示碼,共4位
ACALL DISCODE
INC R0 ;取時間(時分)顯示碼,共4位
ACALL DISCODE
MOV R0, #36H ;取農歷日期(月日)顯示碼,共4位
ACALL DISCODE
AJMP DISPLAYRUN
DISABNORMAL: ;設置及萬年歷模式下,顯示方式
JB 3CH, DISSTATE1XH
JB 3DH, DISSTATE2XH
JB 3EH, DISSTATE3XH
JB 3FH, DISSTATE4XH
AJMP DISPLAYPREPARATIVE
DISSTATE3XH:
AJMP JMPDISSTATE3XH
DISSTATE4XH:
AJMP JMPDISSTATE4XH
DISSTATE1XH: ;狀態1(設置鬧鐘),星期欄顯示鬧鐘號(1~4),鬧鈴標志亮,時間欄顯示,其余不顯示
MOV A, 27H ;取狀態字
ANL A, #00000111B
INC A
MOVC A, @A+DPTR
MOV 6FH, A ;在星期一欄顯示鬧鐘號(1~4)
MOV R1, #70H ;陽歷的年月日日期都不顯示,送顯示碼00H到顯示緩沖區
LOOPDISSTATE1XH:
MOV @R1, #0
INC R1
CJNE R1, #78H, LOOPDISSTATE1XH
DEC R1
MOV R0, #0CH ;時間時,分顯示碼,第1組寄存器R4、R5
ACALL DISCODE
INC R1
LOOPDISSTATE1XH1: ;農歷日期蘭不顯示,送顯示碼00H到顯示緩沖區
MOV @R1, #0
INC R1
CJNE R1, #80H, LOOPDISSTATE1XH1
JB 07H, DISSTATE1XHFLICKER
AJMP DISPLAYRUN
DISSTATE1XHFLICKER: ;設置時的閃爍顯示
JB 3BH, DISSTATE1XHFLICKERMINUTE
MOV 78H, #0 ;時消隱
MOV 79H, #0
AJMP DISPLAYRUN
DISSTATE1XHFLICKERMINUTE:
MOV 7AH, #0 ;分消隱
MOV 7BH, #0
AJMP DISPLAYRUN
DISSTATE2XH: ;狀態2(萬年歷),時間欄不顯示,只顯示陰陽歷日期及星期
MOV A, 26H ;取星期顯示碼,高4位
ANL A, #0F0H
SWAP A
JNZ DISSTATE2XHWEEKDAY
MOV A, #8
DISSTATE2XHWEEKDAY:
MOVC A, @A+DPTR
MOV 6FH, A
MOV R0, #09H ;取年顯示碼,共4位
MOV R1, #70H
ACALL DISYEARCODE
MOV R0, #0AH ;取日期(月日)顯示碼,共4位
ACALL DISCODE
LOOPDISSTATE2XH: ;時間不顯示,送0為顯示碼
INC R1
MOV @R1, #0
CJNE R1, #7BH, LOOPDISSTATE2XH
MOV R0, #0EH ;取陰歷(月日)顯示碼,共4位
;MOV R1, #7BH
ACALL DISCODE
JB 07H, DISSTATE2XHFLICKER
AJMP DISPLAYRUN
DISSTATE2XHFLICKER:
JB 38H, DISSTATE2XHFLICKERYEAR10
JB 39H, DISSTATE2XHFLICKERYEAR1
JB 3AH, DISSTATE2XHFLICKERMONTH
JB 3BH, DISSTATE2XHFLICKERDATE
AJMP DISPLAYRUN
DISSTATE2XHFLICKERYEAR10:
MOV 72H, #0
AJMP DISPLAYRUN
DISSTATE2XHFLICKERYEAR1:
MOV 73H, #0
AJMP DISPLAYRUN
DISSTATE2XHFLICKERMONTH:
MOV 74H, #0
MOV 75H, #0
AJMP DISPLAYRUN
DISSTATE2XHFLICKERDATE:
MOV 76H, #0
MOV 77H, #0
AJMP DISPLAYRUN
JMPDISSTATE3XH: ;狀態3(設置時間日期),不顯示農歷的日期和星期
MOV 6FH, #0 ;星期,不顯示
MOV R0, #19H ;取年分顯示碼,共4位
MOV R1, #70H
ACALL DISYEARCODE
MOV R0, #1AH ;取日期(月日)顯示碼,共4位
ACALL DISCODE
INC R0 ;取時間(時分)顯示碼,共4位
ACALL DISCODE
LOOPDISSTATE3XH: ;時間不顯示,送0為顯示碼
INC R1
MOV @R1, #0
CJNE R1, #7FH, LOOPDISSTATE3XH
JB 07H, DISSTATE3XHFLICKER
AJMP DISPLAYRUN
DISSTATE3XHFLICKER:
JB 38H, DISSTATE3XHFLICKERYEAR
JB 39H, DISSTATE3XHFLICKERMONTH
JB 3AH, DISSTATE3XHFLICKERDATE
JB 3BH, DISSTATE3XHFLICKERHOUR
;DISSTATE3XHFLICKERINUTE:
MOV 7AH, #0
MOV 7BH, #0
AJMP DISPLAYRUN
DISSTATE3XHFLICKERYEAR:
MOV 70H, #0
MOV 71H, #0
MOV 72H, #0
MOV 73H, #0
AJMP DISPLAYRUN
DISSTATE3XHFLICKERMONTH:
MOV 74H, #0
MOV 75H, #0
AJMP DISPLAYRUN
DISSTATE3XHFLICKERDATE:
MOV 76H, #0
MOV 77H, #0
AJMP DISPLAYRUN
DISSTATE3XHFLICKERHOUR:
MOV 78H, #0
MOV 79H, #0
AJMP DISPLAYRUN
JMPDISSTATE4XH:
AJMP DISPLAYNORMAL
;AJMP DISPLAYRUN
DISPLAYRUN: ;顯示碼送顯示驅動器
MOV C, 06H
MOV P2.0, C ;
MOV C, 07H
MOV P2.1, C ;
MOV P0, 6FH
SETB P2.2
ACALL DELAY
CLR P2.2
MOV R0, #70H
MOV R2, #0
LOOPDISPLAY:
MOV P0, @R0
MOV A, R2
SWAP A
ANL P2, #0FH
ORL P2, A
CLR P2.3
ACALL DELAY
SETB P2.3
INC R0
INC R2
CJNE R2, #16, LOOPDISPLAY
LJMP DISPLAYPREPARATIVE
DELAY:
;顯示延遲
;((2*R6+1)*R7+1)機器周期
MOV R7, #5
LOOPDALAY:
MOV R6, #100
LOOPDALAY1:
DJNZ R6, LOOPDALAY1
DJNZ R7, LOOPDALAY
RET
DISYEARCODE:
MOV A, @R0 ;計算年的顯示碼
CLR C
SUBB A, #0D0H ;(2000->7D0H)
MOV B, A
DEC R0
MOV A, @R0
SUBB A, #07H
JNC DISYEAR2000
INC R0
MOV A, @R0
CLR C
SUBB A, #06CH ;(1900->76CH)
MOV B, A
;MOV A, 18H
;SUBB A, #07H
MOV A, #1
MOVC A, @A+DPTR
MOV @R1, A
MOV A, #9
MOVC A, @A+DPTR
INC R1
MOV @R1, A
AJMP DISYEAR10
DISYEAR2000:
MOV A, #2
MOVC A, @A+DPTR
MOV @R1, A
MOV A, #0
MOVC A, @A+DPTR
INC R1
MOV @R1, A
DISYEAR10:
MOV A, B
MOV B, #10
DIV AB
MOVC A, @A+DPTR
INC R1
MOV @R1, A
MOV A, B
MOVC A, @A+DPTR
INC R1
MOV @R1, A
RET
DISCODE:
MOV A, @R0
MOV B, #10
DIV AB
MOVC A, @A+DPTR
INC R1
MOV @R1, A
MOV A, B
MOVC A, @A+DPTR
INC R1
MOV @R1, A
INC R0
MOV A, @R0
MOV B, #10
DIV AB
MOVC A, @A+DPTR
INC R1
MOV @R1, A
MOV A, B
MOVC A, @A+DPTR
INC R1
MOV @R1, A
RET
;****************************************************************************************
SETLUNARDATE:
MOV A, 19H ;設置計算總天數程序的入口參數,(年-1925)送R2
SUBB A, #85H ;1925D=785H
MOV R2, A
MOV R3, 1AH ;月送R3
MOV R4, 1BH ;日送R4
LCALL CALCULATETOTALDAYS ;計算距離1925年1月1日的總天數
MOV 30H, R6 ;計算結果送30H、31H單元保存
MOV 31H, R7
LCALL SETWEEKDAYS ;計算星期幾
MOV A, R5
SWAP A
ANL 32H, #0FH
ORL 32H, A ;計算結果送32H單元高四位保存
MOV R4, 30H ;計算農歷日期程序入口參數,總天數送R4、R5
MOV R5, 31H
LCALL LUNARDATECALULATE
MOV 37H, R7 ;
MOV 36H, R4 ;
MOV A, R2
ADD A, #85H ;1925D=785H
MOV 35H, A
MOV A, #0
ADDC A, #07H
MOV 34H, A
RET
;****************************************************************************************
ORG 0300H
;時間計數器累加,設置當前時間,年月日、時分秒、0.01秒
;設置時間
SETTIMEVALUE:
PUSH PSW ;壓棧保護現場PSW、A、B
PUSH A
PUSH B
MOV PSW, #00011000B ;使用第三組寄存器
INC 24H ;250微秒計數器
MOV A, 24H
CJNE A, #40, RETTIME
MOV 24H, #00H
INC R7 ;百分之一秒(0.01秒)時間計數器
;產生周期為1秒及0.5秒的方波脈沖信號
MS250:
CJNE R7, #25, MS500
CPL 07H
MS500:
CJNE R7, #50, MS750
CPL 07H
CPL 06H
MS750:
CJNE R7, #75, MS1000
CPL 07H
MS1000:
CJNE R7, #100, RETTIME
CPL 07H
CPL 06H
MOV R7, #0 ;滿一秒鐘,百分秒計數器清零
INC R6 ;秒計數器
CJNE R6, #60, RETTIME
MOV R6, #0 ;滿一分鐘,分計數器清零
INC R5 ;分鐘計數器
MOV A, 33H ;當天分鐘數計數器(32H低四位、33H)
ADD A, #1
MOV 33H, A
MOV A, #0
ADDC A, 32H
MOV 32H, A
CJNE R5, #60, RETTIME
MOV R5, #0 ;滿一小時,分鐘計數器清零
INC R4 ;時計數器
CJNE R4, #24, RETTIME
MOV R4, #0 ;滿一天,時計數器清零
MOV 33H, #0 ;當天分鐘計數器清零
MOV 32H, #0
ACALL SETDATEVALUE ;設置日期計數器
;計算日期入口條件設置
SETB 05H ;設置請求計算農歷日期指示
RETTIME:
POP B ;出棧恢復現場B、A、PSW
POP A
POP PSW
RETI
;設置日期
SETDATEVALUE:
INC R3 ;天計數器
MOV A, R2 ;判斷月份以確定當月的天數
DEC A
JZ DAY31;1月
DEC A
JZ DAY28;2月
DEC A
JZ DAY31;3月
DEC A
JZ DAY30;4月
DEC A
JZ DAY31;5月
DEC A
JZ DAY30;6月
DEC A
JZ DAY31;7月
DEC A
JZ DAY31;8月
DEC A
JZ DAY30;9月
DEC A
JZ DAY31;10月
DEC A
JZ DAY30;11月
DEC A
JZ DAY31;12月
DAY31:
CJNE R3,#32,RETDATE ;大月,31天
AJMP SETMONTH
DAY30:
CJNE R3,#31,RETDATE ;小月,30天
AJMP SETMONTH
DAY28: ;2月,平年28天,閏年29天
MOV A, R1;計算當年-1925年
SUBB A, #84H ;
MOV B, #4
DIV AB
MOV A, B
JZ DAY29
CJNE R3, #29, RETDATE;平年2月28天
AJMP SETMONTH
DAY29:
CJNE R3,#30,RETDATE ;閏年2月29天
;AJMP SETMONTH
SETMONTH:
MOV R3, #1 ;滿一個月,日計數器設置為1
INC R2 ;月計數器
CJNE R2, #13, RETDATE
MOV R2, #1 ;滿一年,月計數器設置為1
MOV A, #1 ;年計數器(R0、R1)
ADD A, R1
MOV R1, A
MOV A, #0
ADDC A, R0
MOV R0, A
RETDATE:
RET
;*****************************************************************************************
ORG 0400H
;*****************************************************************************************
ORG 0500H
;計算當天距離1925年1月1日的總天數,使用第2組寄存器
;入口:R2=年-1925,R3=月,R4=日
;出口:R6、R7=總天數
CALCULATETOTALDAYS:
MOV A, R2 ;假設1年有365天,計算(年-1925)年的總天數
MOV B, #6DH ;16DH(365)的低位字節
MUL AB
MOV R7, A
MOV A, R2
ADD A, B
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -