?? clock.txt
字號:
MOV R6, A
MOV A, R2 ;補加(年-1925)中閏年補償(一年366天)的天數
MOV B, #4
DIV AB
ADD A, R7
MOV R7, A
MOV A, #0
ADDC A, R6
MOV R6, A
MOV A, R3 ;假設每月有28天,計算(月-1)個月的總天數
DEC A
MOV B, #28 ;設每月有28天
MUL AB
ADD A, R7
MOV R7, A
MOV A, B
ADDC A, R6
MOV R6, A
MOV DPTR, #0F70H ;平年月天數補償表起始地址(大月31天、小月30天、閏年2月29天)
MOV A, R2
INC A
MOV B, #4
DIV AB
MOV A, B
JNZ SETDPTREND
MOV DPTR, #0F80H ;閏年月天數補償表起始地址
SETDPTREND:
MOV A, R3 ;補加月補償天數
DEC A
MOVC A, @A+DPTR
ADD A, R7
MOV R7, A
MOV A, #0
ADDC A, R6
MOV R6, A
MOV A, R4 ;日
DEC A
ADD A, R7
MOV R7, A
MOV A, #0
ADDC A, R6
MOV R6, A
RET
;*****************************************************************************************
ORG 0580H
;計算當前是星期幾,使用第0組寄存器
;入口:R6、R7,為當天距離1925年1月1日的總天數
;出口:R5,計算結果0表示星期天,1~6分別為星期一至星期六
SETWEEKDAYS:
MOV A, R7 ;取出總天數,加4(1925年1月1日為星期四)
ADD A, #4
MOV R7, A
MOV A, #0
ADDC A, R6
MOV R6, A ;計算總天數除以7的余數
MOV B, #7
DIV AB
MOV R6, B
MOV A, R7
MOV B, #7
DIV AB
MOV A, B
RL A
RL A
RL A
MOV R7, A
MOV A, R6
RL A
RL A
RL A
MOV B, #7
DIV AB
MOV R6, B
MOV R0, #3
WEEKDAYSLOOP:
MOV A, R6
CLR CY
RRC A
MOV R6, A
MOV A, R7
RRC A
MOV R7, A
DEC R0
CJNE R0, #0, WEEKDAYSLOOP
;MOV A, R7
MOV B, #7
DIV AB
MOV R5, B
RET
;*****************************************************************************************
ORG 0700H
;計算農歷日期(年月日),第0組、第1組(00H~0FH)寄存器存儲計算中間值
;子程序段
LUNARYEARDAYS:
;計算農歷Y年的總天數
;入口,R2, Y年-1925
;出口,R4、R5,Y年的總天數
MOV R5, #5CH ;設一年29x12=348(15CH)天
MOV R4, #1
MOV DPTR, #0E00H ;資料起始地址
MOV A, R2 ;設置DPTR,原因:資料單位為字(雙字節)
ADD A, DPL
MOV DPL, A
MOV A, #0
ADDC A, DPH ;在程序設計時確定該計算不會溢出
MOV DPH, A
MOV A, R2 ;取Y年月份資料高字節(1~8月份)
MOVC A, @A+DPTR
MOV R0, #0 ;累加農歷Y年應補加的天數
MOV R1, #8 ;移位計數器
LOOPLUNARYEARDAYS1:
RLC A
JNC LUNARYEARDAY291
INC R0
LUNARYEARDAY291:
DJNZ R1, LOOPLUNARYEARDAYS1
MOV A, R2 ;取低字節資料的高四位
INC A
MOVC A, @A+DPTR
MOV R1, #4
LOOPLUNARYEARDAYS2:
RLC A
JNC LUNARYEARDAY292
INC R0
LUNARYEARDAY292:
DJNZ R1, LOOPLUNARYEARDAYS2
MOV A, R0
ADD A, R5
MOV R5, A
MOV A, #0
ADDC A, R4
MOV R4, A
LCALL LUNARLEAPDAYS ;補加Y年閏月的天數(R3)
MOV A, R3
ADD A, R5
MOV R5, A
MOV A, #0
ADDC A, R4
MOV R4, A
RET
LUNARLEAPDAYS:
;計算農歷Y年的閏月的天數
;入口:R2 Y年-1925
;出口:R3,Y年閏月的天數
LCALL LUNARLEAPMONTH ;Y年有無閏月,潤幾月。結果存在R3
CJNE R3, #0, LUNARLEAPDAYS29
MOV R3, #0
LJMP LUNARLEAPDAYSRET
LUNARLEAPDAYS29:
MOV A, R2 ;取月份資料低字節低四位(閏月天數資料)
INC A
ADD A, #2 ;取(Y年-1924),低四位表示前一年閏月天數
MOVC A, @A+DPTR
ANL A, #0FH ;取低四位
XRL A, #0FH ;如果低四位為F,則前一年閏月30天
JZ LUNARLEAPDAYS30
MOV R3, #29
LJMP LUNARLEAPDAYSRET
LUNARLEAPDAYS30:
MOV R3, #30
LUNARLEAPDAYSRET:
RET
LUNARLEAPMONTH:
;計算農歷Y年的閏月的月份
;入口:R2 Y年-1925
;出口:R3,Y年閏月的月份, 0表示Y年無閏月
MOV A, R2
INC A
MOVC A, @A+DPTR
ANL A, #0FH ;取低四位
MOV R3, A
XRL A, #0FH ;如果是F,返回0,Y年無閏月
JNZ LUNARLEAPMONTHRET
MOV R3, #0
LUNARLEAPMONTHRET:
RET
LUNARMONTHDAYS:
;計算農歷Y年的M月的天數
;入口:R2 Y年-1925, R4 M月
;出口:RX,Y年M月的天數
;MOV A, R2
;MOV DPTR, #2000H ;資料起始地址
;MOV A, R2 ;設置DPTR,原因:資料單位為字(雙字節)
;ADD A, DPL
;MOV DPL, A
;MOV A, #0
;ADDC A, DPH ;在程序設計時確定該計算不會溢出
;MOV DPH, A
MOV A, R2 ;取Y年月份資料高字節(1~8月份)
MOVC A, @A+DPTR
MOV 25H, A
MOV A, R4 ;循環計數器
MOV R0, A
MOV R1, #8
MOV A, 25H
LOOPMONTHDAYS1:
RLC A
MOV 01H, C
DEC R0
DEC R1
MOV 25H, A ;保存A寄存器的內容
MOV A, R0
JZ EXITLOOPMONTHDAYS2
MOV A, R1
JZ EXITLOOPMONTHDAYS1
MOV A, 25H ;恢復A寄存器的內容
LJMP LOOPMONTHDAYS1
EXITLOOPMONTHDAYS1:
MOV A, R2 ;取低字節資料
INC A
MOVC A, @A+DPTR
LOOPMONTHDAYS2:
RLC A
MOV 01H, C
DJNZ R0, LOOPMONTHDAYS2
EXITLOOPMONTHDAYS2:
JB 01H, LUNARMONTHDAYS30
MOV R3, #29
LJMP LUNARMONTHDAYSRET
LUNARMONTHDAYS30:
MOV R3, #30
LUNARMONTHDAYSRET:
RET
;計算農歷日期的主程序
LUNARDATECALULATE:
;計算農歷日期,使用第0組或第1組寄存器
;入口:R4、R5總天數
;出口:R2=年-1925;R4=月;R7=日
;分三段計算1925.1.24~1968.1.30、~2011.2.3、~2045.2.8、~2099.12.31
MOV A, R5
CLR C
SUBB A, #033H
MOV R7, A
MOV A, R4
SUBB A, #0B8H
MOV R6, A
MOV R2, #129
JNC EXITFENDUAN
MOV A, R5
CLR C
SUBB A, #0D4H
MOV R7, A
MOV A, R4
SUBB A, #07AH
MOV R6, A
MOV R2, #86
JNC EXITFENDUAN
MOV A, R5
CLR C
SUBB A, #076H
MOV R7, A
MOV A, R4
SUBB A, #03DH
MOV R6, A
MOV R2, #43
JNC EXITFENDUAN
MOV A, R5
CLR C
SUBB A, #017H
MOV R7, A
MOV A, R4
SUBB A, #0
MOV R6, A
MOV R2, #0
JNC EXITFENDUAN
LJMP ERRCALCULATE ;計算出錯,超出日期范圍
EXITFENDUAN: ;分段計算有效總天數R6、R7,年份R2,R4、R5失效后面的程序可以使用
LOOPCALCULATEYEAR:
LCALL LUNARYEARDAYS
MOV A, R7
CLR C
SUBB A, R5
MOV R7, A
MOV A, R6
SUBB A, R4
MOV R6, A
JC EXITLOOPCALCULATEYEAR
INC R2
MOV A, R2
XRL A, #176 ;大于175(2100年)退出循環
JNZ PASSERRCALCULATE2
LJMP ERRCALCULATE
PASSERRCALCULATE2:
LJMP LOOPCALCULATEYEAR
EXITLOOPCALCULATEYEAR:
MOV A, R7 ;加上最后一年減掉的天數,當年已經過去的天數,用于計算月份和日期
ADD A, R5
MOV R7, A
MOV A, R6
ADDC A, R4
MOV R6, A
;DEC R2 ;如果是零,為1926年
LCALL LUNARLEAPMONTH ;判斷是否有閏月,月份存在R3
MOV A, R3
MOV R5, A
CLR 00H ;是否閏月標識
MOV R4, #1 ;計算月數
LOOPCALCULATEMONTH:
MOV A, R5
JZ CALCULATEMONTH1 ;轉無閏月處理
MOV A, #1
ADD A, R5
XRL A, R4
JNZ CALCULATEMONTH1 ;轉非閏月處理
JB 00H, CALCULATEMONTH1
DEC R4
SETB 00H ;設置閏年標識
LCALL LUNARLEAPDAYS ;讀取當年閏月的天數R3
LJMP CALCULATEMONTH2 ;
CALCULATEMONTH1:
LCALL LUNARMONTHDAYS ;結果存放在R3中
CALCULATEMONTH2:
JNB 00H, CALCULATEMONTH3
MOV A, #1
ADD A, R5
XRL A, R4
JNZ CALCULATEMONTH3
CLR 00H ;解除閏月標識
CALCULATEMONTH3:
MOV A, R7
CLR C
SUBB A, R3
MOV R7, A
MOV A, R6
SUBB A, #0
MOV R6, A
JC EXITLOOPCALCULATEMONTH
INC R4
MOV A, R4 ;如果大于十二退出,提示錯誤
XRL A, #13
JZ ERRCALCULATE
LJMP LOOPCALCULATEMONTH
EXITLOOPCALCULATEMONTH:
MOV A, R5 ;判斷是否閏月
JZ CALCULATEMONTH5
MOV A, #1
ADD A, R5
XRL A, R4
JNZ CALCULATEMONTH5
JNB 00H, CALCULATEMONTH4
CLR 00H
LJMP CALCULATEMONTH5
CALCULATEMONTH4:
SETB 00H
DEC R4
CALCULATEMONTH5:
MOV A, R7 ;加最后一次減的天數,當月已經過完的天數
ADD A, R3
MOV R7, A
MOV A, #0
ADDC A, R6
MOV R6, A
;DEC R4
INC R7 ;計算日期
LJMP CALCULATERET
;計算結果:R2=年-1925;R4=月;R7=日
ERRCALCULATE: ;錯誤顯示
;錯誤處理程序
NOP
CALCULATERET:
RET
;****************************************************************************************
ORG 0900H
THEKEYDOWNSERVER:
;27H單元的位地址高位到低位:37、36、35、34、33、32、31、30(H)
;有鍵按下的位為0,本程序為按鍵處理分派
CLR TR1 ;關閉延時計數器
CLR EX0 ;關閉INT0中斷
PUSH P0
MOV P0, #0
MOV 04H, #10 ;延時單元
KEYDELAY:
MOV 05H, #200
DJNZ 05H, $
DJNZ 04H, KEYDELAY
PUSH PSW ;保護現場
PUSH A
PUSH B
MOV PSW, #00001000B
MOV A, P1
ORL A, #0FH
MOV P1, A ;讀鍵盤口,結果存儲26H第四位
MOV A, P1
CPL A
ANL A, #0FH
JZ KEYALLOT5 ;如果無鍵按下,推出
ANL 26H, #0F0H
ORL 26H, A
KEYALLOT1:
MOV A, 27H
JNZ KEYALLOT2
ACALL KEYSTATE0
AJMP KEYALLOT5
KEYALLOT2:
JNB 3CH, KEYALLOT3
ACALL KEYSTATE1
AJMP KEYALLOT5
KEYALLOT3:
JNB 3DH, KEYALLOT4
ACALL KEYSTATE2
AJMP KEYALLOT5
KEYALLOT4:
JNB 3EH, KEYALLOT8
ACALL KEYSTATE3
AJMP KEYALLOT5
KEYALLOT8:
JNB 3FH, KEYALLOT5
ACALL KEYSTATE4
;AJMP KEYALLOT5
KEYALLOT5:
POP B ;恢復現場
POP A
POP PSW
POP P0
;設置延時計數器,如果在5秒鐘內沒有按鍵動作自動轉到時間顯示狀態
MOV TH1, #0
MOV TF0, #0
MOV 03H, #255
CLR IE0
SETB EX0
SETB TR1 ;計時開始
RETI
KEYSTATE0:
;狀態0按鍵處理,時間顯示狀態
STATE0KEY0:
JNB 30H, STATE0KEY1
MOV 27H, #10H
ACALL PRESETALARMTIME
AJMP KEYSTATE0RET
STATE0KEY1:
JNB 31H, STATE0KEY2
AJMP STATE0KEY12
STATE0KEY2:
JNB 32H, STATE0KEY3
STATE0KEY12:
MOV 27H, #24H
MOV R0, 18H
MOV R1, 19H
MOV R2, 1AH
MOV R3, 1BH
MOV R6, 36H
MOV R7, 37H
MOV A, 32H
ANL A, #0F0H
ANL 26H, #0FH
ORL 26H, A
AJMP KEYSTATE0RET
STATE0KEY3:
JNB 33H, KEYSTATE0RET
MOV 27H, #48H
;AJMP KEYSTATE0RET
KEYSTATE0RET:
RET
KEYSTATE1:
;狀態1按鍵處理,鬧鐘設置狀態
STATE1KEY0:
JNB 30H, STATE1KEY1
ACALL SETALARMTIME ;SET
MOV 27H, #21H ;初始化萬年歷狀態
MOV R0, 18H
MOV R1, 19H
MOV R2, 1AH
MOV R3, 1BH
MOV R6, 36H
MOV R7, 37H
MOV A, 32H
ANL A, #0F0H
ANL 26H, #0FH
ORL 26H, A
AJMP KEYSTATE1RET
STATE1KEY1:
JNB 31H, STATE1KEY2
JB 3BH, STATE1KEY1MIN ;UP
INC R4
CJNE R4, #25, STATE1KEY1HOUR
MOV R4, #0
STATE1KEY1HOUR:
AJMP KEYSTATE1RET
STATE1KEY1MIN:
ACALL MINUTEADJUST
AJMP KEYSTATE1RET
STATE1KEY2:
JNB 32H, STATE1KEY3
JB 3BH, STATE1KEY2MIN ;DOWN
DEC R4
CJNE R4, #0FFH, STATE1KEY2HOUR
MOV R4, #24
STATE1KEY2HOUR:
AJMP KEYSTATE1RET
STATE1KEY2MIN:
ACALL MINUTEADJUST
AJMP KEYSTATE1RET
STATE1KEY3:
JNB 33H, KEYSTATE1RET
JNB 3BH, STATE1KEY3CHANGE ;RIGHT
ACALL SETALARMTIME
MOV A, 27H
ANL A, #03H
INC A
MOV B, #4
DIV AB
MOV A, B
ANL 27H, #0F0H
ORL 27H, A
ACALL PRESETALARMTIME
AJMP KEYSTATE1RET
STATE1KEY3CHANGE:
SETB 3BH ;切換到分鐘調整
;AJMP KEYSTATE1RET
KEYSTATE1RET:
RET
KEYSTATE2:
;狀態2按鍵處理,萬年歷查看狀態
STATE2KEYO:
JNB 30H, STATE2KEY1
MOV 27H, #41H ;按鍵0,SET
AJMP KEYSTATE2RET
STATE2KEY1:
JNB 31H, STATE2KEY2
JNB 38H, STATE2KEY1YEAR ;按鍵1, UP
MOV B, #10
ACALL YEARADJUST
AJMP KEYSTATE2RET
STATE2KEY1YEAR:
JNB 39H, STATE2KEY1MONTH
MOV B, #1
ACALL YEARADJUST
AJMP KEYSTATE2RET
STATE2KEY1MONTH:
JNB 3AH, STATE2KEY1DATE
ACALL MONTHADJUST
AJMP KEYSTATE2RET
STATE2KEY1DATE:
JNB 3BH, KEYSTATE2RET
ACALL DATEADJUST
AJMP KEYSTATE2RET
STATE2KEY2:
JNB 32H, STATE2KEY3
JNB 38H, STATE2KEY2YEAR ;按鍵2, DOWN
MOV B, #10
ACALL YEARADJUST
AJMP KEYSTATE2RET
STATE2KEY2YEAR:
JNB 39H, STATE2KEY2MONTH
MOV B, #1
ACALL YEARADJUST
AJMP KEYSTATE2RET
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -