当前位置:文档之家› 完美万年历(单片机汇编语言版)

完美万年历(单片机汇编语言版)

RSPIN BIT P2.6
RWPIN BIT P2.5
EPIN BIT P2.7

WEIXUAN BIT P1.0
JIAJIAN BIT P1.1
JIANJIAN BIT P1.2
FANHUI BIT P1.3
NZKG BIT P1.4
BSKG BIT P1.5
WEEK_KEY BIT P1.6

YEARQ EQU 30H
YEARB EQU 31H
YEARS EQU 32H
YEARG EQU 33H
HENGH EQU 34H
MONTHH EQU 35H
MONTHL EQU 36H
HENGL EQU 37H
DAYH EQU 38H
DAYL EQU 39H

WEEK EQU 40H

HOURH EQU 41H
HOURL EQU 42H
MAOHAOH EQU 43H
MINUTEH EQU 44H
MINUTEL EQU 45H
MAOHAOL EQU 46H
SECONDH EQU 47H
SECONDL EQU 48H
;TEMPER EQU 49H
BSCS EQU 50H
TEMP EQU 51H
TEMP1 EQU 52H
CNTA EQU 53H
CNTB EQU 54H
YEARL EQU 59H
YEARH EQU 60H
NZBZ BIT 60H
BSBZ BIT 61H
FLAG BIT 62H

ORG 0000H
LJMP MAIN
ORG 000BH
LJMP INT_T0
ORG 001BH
LJMP INT_T1
ORG 0100H

MAIN:MOV SP,#60H
MOV 30H,#02H
MOV 31H,#00H
MOV 32H,#01H
MOV 33H,#04H
MOV 34H,#2DH;-
MOV 35H,#01H
MOV 36H,#02H
MOV 37H,#2DH;-
MOV 38H,#03H
MOV 39H,#01H

MOV 40H,#07H

MOV 41H,#02H
MOV 42H,#03H
MOV 43H,#3AH;:
MOV 44H,#05H
MOV 45H,#09H
MOV 46H,#3AH;:
MOV 47H,#05H
MOV 48H,#05H

MOV 21H,#00H;闹钟时高位
MOV 22H,#00H;闹钟时低位
MOV 24H,#00H;闹钟分高位
MOV 25H,#01H;闹钟分低位

MOV CNTA,#00H
MOV CNTB,#00H

CLR FLAG
CLR NZBZ
CLR BSBZ
MOV BSCS,#00H

MOV R2,#20
MOV TMOD,#11H
MOV TH0,#3CH
MOV TL0,#0B0H
MOV TH1,#(65536-500) / 256
MOV TL1,#(65536-500) MOD 256
SETB EA
SETB ET0
SETB ET1
LCALL LCDRESET
SETB TR0

LOOP:LCALL JIANPAN
LCALL DISPLAY
LCALL DISP_WEEK
LCALL NZBF
JB NZBZ,LP1
AJMP LP2
LP1:LCALL NZBJ
LP2:LCALL BSBF
JB BSBZ,LP3
AJMP LOOP
LP3:LCALL BSBJ
AJMP LOOP

INT_T0:PUSH ACC
PUSH PSW
CLR RS0
CLR RS1
;这次的切换工作组起到了大作用,消除了令我头疼已久的延迟难题
MOV TH0,#3CH
MOV TL0,#0B0H
DJNZ R2,T0END
MOV R2,#20
INC SECONDL
MOV A,SECONDL
CJNE A,#0AH,T0END
MOV SECONDL,#00H
INC SECONDH
MOV A,SECONDH
CJNE A,#06H,T0END
MOV SECONDH,#00H
INC MINUTEL
MOV A,MINUTEL
CJNE A,#0AH,T0END
MOV MINUTEL,#00H
INC MINUTEH
MOV A,MINUTEH
CJNE A,#06H,T0END
MOV MINUTEH,#00H
INC HOURL
MOV A,HOURL
CJNE A,#04H,T01
MOV A,HOURH
CJNE A,#02H,T0END
MOV HOURL,#00H
MOV HOURH,#00H
LCALL ZDRQ
AJMP T0END
T01:CJNE A,#0AH,T0END
MOV HOURL,#00H;开始无此和下一条指令,19点无法变20点
INC HOURH
T0END:POP PSW
POP ACC
RETI

ZDRQ:PUSH ACC
INC WEEK;从此往下四条指令消除了一天时间到星期不能增一的弊端。
MOV A,WEEK
CJNE A,#8,LL0
MOV WEEK,#1
LL0: INC DAYL
MOV A,MONTHH
CJNE A,#01H,LL
MOV 55H,#0AH
MOV A,MONTHL
ADD A,55H
SJMP LL3
LL:MOV A,MONTHL
ADD A,MONTHH
LL3:MOV 56H,A
MOV DPTR,#TAB8
MOVC A,@A+DPTR
MOV 57H,A
MOV A,YEARS;增加了平闰年判断2月天数功能,已成为完美万年历
MOV B,#10
MUL AB
MOV YEARL,A
MOV A,YEARG
ADD A,YEARL
MOV YEARL,A
MOV A,YEARQ
MOV B,#10
MUL AB
MOV YEARH,A
MOV A,YEARB
ADD A,YEARH
MOV YEARH,A

YEAR_JUD:MOV A,YEARL
CJNE A,#0,L1
MOV A,YEARH
MOV B,#4
DIV AB
MOV A,B
CJNE A,#0,SAME_YEAR
AJMP LEAP_YEAR
L1:MOV B,#4
DIV AB
MOV A,

B
CJNE A,#0,SAME_YEAR
AJMP LEAP_YEAR
SAME_YEAR:AJMP PING
LEAP_YEAR:AJMP RUN
PING:MOV DPTR,#TAB9
AJMP PERFECT
RUN:MOV DPTR,#TAB10
PERFECT:MOV A,56H
MOVC A,@A+DPTR
MOV 58H,A
MOV A,DAYH
CJNE A,57H,LL2
MOV A,DAYL
CJNE A,58H,LL2
MOV DAYH,#00H
MOV DAYL,#01H
SJMP LL4
LL2:MOV A,DAYL
CJNE A,#0AH,ZDRQEND
MOV DAYL,#00H
INC DAYH
MOV A,DAYH
CJNE A,57H,ZDRQEND
MOV A,DAYL
CJNE A,58H,ZDRQEND
MOV DAYH,#00H
MOV DAYL,#01H
LL4:INC MONTHL
MOV A,MONTHL
CJNE A,#03H,ZDRQ1
MOV A,MONTHH
CJNE A,#01H,ZDRQ1
MOV MONTHL,#01H
MOV MONTHH,#00H
SJMP ZDRQ2
ZDRQ1:CJNE A,#0AH,ZDRQEND
MOV MONTHL,#00H
INC MONTHH
SJMP ZDRQEND
ZDRQ2:INC YEARG
MOV A,YEARG
CJNE A,#0AH,ZDRQEND
MOV YEARG,#00H
INC YEARS
MOV A,YEARS
CJNE A,#0AH,ZDRQEND
MOV YEARS,#00H
INC YEARB
MOV A,YEARB
CJNE A,#0AH,ZDRQEND
MOV YEARB,#00H
INC YEARQ
MOV A,YEARQ
CJNE A,#0AH,ZDRQEND
MOV YEARQ,#00H
ZDRQEND:POP ACC
RET

INT_T1:PUSH ACC
PUSH PSW
MOV TH1,#(65536-500) / 256
MOV TL1,#(65536-500) MOD 256
INC CNTA
MOV A,CNTA
CJNE A,#100,NEXT
INC CNTB
MOV A,CNTB
CJNE A,#04H,NEXT
MOV CNTA,#00H
MOV CNTB,#00H
CPL FLAG
NEXT:JB FLAG,EXIT
CPL P3.0
EXIT:POP PSW
POP ACC
RETI

LCDRESET: ;初始化程序
LCALL DELAY5MS ;延时15MS
LCALL DELAY5MS
LCALL DELAY5MS
MOV A,#38H ;显示模式设置(不检测忙信号)
LCALL LCDWCN ;共三次
LCALL DELAY5MS
MOV A,#38H
LCALL LCDWCN
LCALL DELAY5MS
MOV A,#38H
LCALL LCDWCN
MOV A,#38H ;显示模式设置(以后均检测忙信号)
LCALL LCDWC
MOV A,#08H ;显示关闭
LCALL LCDWC
MOV A,#01H ;显示清屏
LCALL LCDWC
MOV A,#06H ;显示光标移动设置
LCALL LCDWC
MOV A,#0CH ;显示开及光标设置
LCALL LCDWC
RET
;==============================写指令===================================
LCDWC: ;送控制字子程序(检测忙信号)
LCALL WAITIDLE
;******写指令*******;送控制字子程序(不检测忙信号)
LCDWCN: CLR RSPIN ;RS=0 RW=0 E=高脉冲
CLR RWPIN
MOV P0,A
SETB EPIN ;(
NOP ;给高电平脉冲
CLR EPIN ;)
RET
;==========================写数据=======================================
LCDWD: ;写字符子程序
LCALL WAITIDLE
SETB RSPIN ;RS=1 RW=0 E=高脉冲
CLR RWPIN
MOV P0,A
SETB EPIN
NOP
CLR EPIN
RET
;===============================等待控制器空闲========================

==========
WAITIDLE:
PUSH ACC ;正常读写操作之前必须检测LCD控制器状态
MOV P0,#0FFH
LCALL DELAY5MS ;4566666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666
CLR RSPIN ;RS=0 RW=1 E=高电平
SETB RWPIN
SETB EPIN
LCALL DELAY5MS ;465555546465464654648791313848946113134849845461313579641613131354649498
WTD_PA: NOP ;DB7: 0 LCD控制器空闲
JB P0.7,WTD_PA ; 1 LCD控制器忙
CLR EPIN
POP ACC
RET
;日期、时间显示
DISPLAY:PUSH ACC
PUSH PSW
SETB RS0
CLR RS1
MOV A,#82H
LCALL LCDWC
MOV R1,#2FH;不能写成29H,否则会显示不正常,年月日左移
MOV R6,#02H
MOV TEMP,#39H
PLAY:INC R1
CJNE R1,#34H,PLY
MOV A,HENGH
SJMP PLAY1
PLY:CJNE R1,#37H,PLY1
MOV A,HENGL
SJMP PLAY1
PLY1:CJNE R1,#43H,PLY2
MOV A,MAOHAOH
SJMP PLAY1
PLY2:CJNE R1,#46H,PLY3
MOV A,MAOHAOL
SJMP PLAY1
PLY3:MOV A,@R1
MOV DPTR,#TAB_NUM
MOVC A,@A+DPTR
PLAY1:LCALL LCDWD
MOV A,R1
CJNE A,TEMP,PLAY
MOV A,#0C4H
LCALL LCDWC
MOV R1,#40H
MOV TEMP,#48H
DJNZ R6,PLAY
POP PSW
POP ACC
RET
;显示星期几
DISP_WEEK:MOV A,#8DH
LCALL LCDWC
MOV A,40H
W1:CJNE A,#1,W2
MOV DPTR,#TAB1
W11:CLR A
MOVC A,@A+DPTR
JZ W_END
LCALL LCDWD
INC DPTR
AJMP W11
W2:CJNE A,#2,W3
MOV DPTR,#TAB2
W21:CLR A
MOVC A,@A+DPTR
JZ W_END
LCALL LCDWD
INC DPTR
AJMP W21
W3:CJNE A,#3,W4
MOV DPTR,#TAB3
W31:CLR A
MOVC A,@A+DPTR
JZ W_END
LCALL LCDWD
INC DPTR
AJMP W31
W4:CJNE A,#4,W5
MOV DPTR,#TAB4
W41:CLR A
MOVC A,@A+DPTR
JZ W_END
LCALL LCDWD
INC DPTR
AJMP W41
W5:CJNE A,#5,W6
MOV DPTR,#TAB5
W51:CLR A
MOVC A,@A+DPTR
JZ W_END
LCALL LCDWD
INC DPTR
AJMP W51
W6:CJNE A,#6,W7
MOV DPTR,#TAB6
W61:CLR A
MOVC A,@A+DPTR
JZ W_END
LCALL LCDWD
INC DPTR
AJMP W61
W7:CJNE A,#7,W_END
MOV DPTR,#TAB7
W71:CLR A
MOVC A,@A+DPTR
JZ W_END
LCALL LCDWD
INC DPTR
AJMP W71
W_END:RET

;键盘扫描
JIANPAN:CLR RS0
SETB RS1
JB WEIXUAN,ZJ_JIANEND
PUSH ACC
JNB WEIXUAN,$

BEGIN:JNB NZBZ,XSSJ
LCALL XSNZSJ
MOV R4,#0C4H
MOV R5,#2
MOV TEMP1,#0CAH
MOV R0,#21H
SJMP GIVEN

XSSJ:CLR TR0
MOV R4,#82H
MOV R5,#2
MOV TEMP1,#8CH
MOV R0,#30H

GIVEN:MOV A,#0FH
LCALL LCDWCN
MOV A,R4
LCALL LCDWC

FAN_SCAN:JB FANHUI,JIA_SCAN
JNB FANHUI,$
SJMP GOBACK

ZJ_JIANEND:SJMP JIAN_END

JIA_SCAN:JB JIAJIAN,JIAN_SCAN
JNB JIAJIAN,$
LCALL JIAYI
AJMP GIVEN;开始无此指令,时分秒加一后光标回不到当前位上

JIAN_SCAN:JB JIANJIAN,WEI_SCAN
JNB JIANJIAN,$
LCALL JIANYI
AJMP GIVEN

WEI_SCAN:JB WEIXUAN,WEEK_SCAN
JNB WEIXUAN,$
INC R0
INC R4
LCALL JIAO
MOV A,R4
CJNE A,TEMP1,GIVEN
JB NZBZ,BEGIN
MOV R4,#0C4H
MOV R0,#41H;开始无此指令,调时间时仅年月日能增加,时分秒均不能增加,
MOV TEMP1,#0CCH
DJNZ R5,GIVEN
LJMP BEGIN

WEEK_SCAN:JB WEEK_KEY,FAN_SCAN
JNB WEEK_KEY,$


INC WEEK
MOV A,WEEK
CJNE A,#08H,WEEKSCAN1
MOV WEEK,#01H
WEEKSCAN1:LCALL DISP_WEEK
AJMP WEEK_SCAN

XSNZSJ:MOV A,#0C4H
LCALL LCDWC
MOV R1,#20H
XS1:INC R1
CJNE R1,#23H,XS2
MOV A,#3AH
SJMP XS3
XS2:MOV A,@R1
MOV DPTR,#TAB_NUM
MOVC A,@A+DPTR
XS3:LCALL LCDWD
CJNE R1,#25H,XS1
RET

GOBACK:MOV A,#0CH
LCALL LCDWCN
POP ACC
JIAN_END:SETB TR0
RET

JIAO:CJNE R4,#86H,J1
INC R0
INC R4
SJMP J_END
J1:CJNE R4,#89H,J2
INC R0
INC R4
SJMP J_END
J2:CJNE R4,#0C6H,J3
INC R0
INC R4
SJMP J_END
J3:CJNE R4,#0C9H,J_END
INC R0
INC R4
J_END:RET

JIAYI:INC @R0
CJNE @R0,#0AH,JIAYI_END
MOV @R0,#00H
JIAYI_END:JNB NZBZ,JIAYI11
LCALL XSNZSJ
SJMP JIAYI22
JIAYI11:LCALL DISPLAY
JIAYI22:RET

JIANYI:CJNE @R0,#00H,JIANYI_09
MOV @R0,#09H
AJMP JIANYI_END
JIANYI_09:DEC @R0
JIANYI_END:JNB NZBZ,JIANYI11
LCALL XSNZSJ
SJMP JIANYI22
JIANYI11:LCALL DISPLAY
JIANYI22:RET
;闹钟是否开启在LCD上的标志K
NZBF:JB NZKG,NZBF_END
JNB NZKG,$
CPL NZBZ
JB NZBZ,NZBF_LL
MOV A,#01H
LCALL LCDWC
LCALL DISPLAY

JB BSBZ,PRO_BSBZ
AJMP NZBF_END
PRO_BSBZ:MOV A,#0C1H
LCALL LCDWC
MOV A,#25H;%
LCALL LCDWD
SJMP NZBF_END

NZBF_LL:MOV A,#0C2H
LCALL LCDWC
MOV A,#4BH;K
LCALL LCDWD
NZBF_END:RET
;闹钟比较子程序
NZBJ:JB NZBZ,NZBJ_LL
SJMP NZBJ_END
NZBJ_LL:MOV A,25H
CJNE A,45H,NZBJ_END
MOV A,24H
CJNE A,44H,NZBJ_END
MOV A,22H
CJNE A,42H,NZBJ_END
MOV A,21H
CJNE A,41H,NZBJ_END
SETB TR1
JB NZKG,$
JNB NZKG,$
CLR NZBZ
MOV A,#0C2H
LCALL LCDWC
MOV A,#10H
LCALL LCDWD
NZBJ_END:CLR TR1
RET
;报时部分
BSBF:JB BSKG,BSBF_END
JNB BSKG,$
CPL BSBZ
JB BSBZ,BSBF_LL
MOV A,#01H
LCALL LCDWC
LCALL DISPLAY
JB NZBZ,PRO_NZBZ
AJMP BSBF_END

PRO_NZBZ:MOV A,#0C2H
LCALL LCDWC
MOV A,#4BH
LCALL LCDWD
SJMP BSBF_END

BSBF_LL:MOV A,#0C1H
LCALL LCDWC
MOV A,#25H
LCALL LCDWD
BSBF_END:RET

BSBJ:JB BSBZ,BSBJ_LL
SJMP BSBJ_END
BSBJ_LL:MOV A,44H
CJNE A,#0,BSBJ_END
MOV A,45H
CJNE A,#0,BSBJ_END
MOV A,47H
CJNE A,#0,BSBJ_END
MOV A,48H
CJNE A,#0,BSBJ_END
MOV A,41H
CJNE A,#0,WRONG;从此往下三条指令消除了00:00:00报时时无限报时的弊端。
AJMP WRONG1
WRONG1:MOV A,42H
CJNE A,#0,WRONG
MOV BSCS,#24
AJMP BS
WRONG:MOV A,HOURH
MOV B,#10
MUL AB
ADD A,HOURL
MOV BSCS,A
LCALL BS
BSBJ_END:RET

BS:
SETB RS0
SETB RS1
MOV R3,BSCS
BS1:LCALL BZ
LCALL DELAY1S
DJNZ R3,BS1
RET

BZ:MOV R6,#250
B1:ACALL DEX
CPL P3.0
DJNZ R6,B1
MOV R5,#50
ACALL DELAY
RET
DELAY:MOV R6,#10
D1:MOV R7,#100
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,DELAY
RET
DEX:MOV R7,#180
DE1:NOP
DJNZ R7,DE1
RET

DELAY5MS:PUSH PSW
SETB RS0
SETB RS1
MOV R6,#25
DEL1:MOV R7,#100
DJNZ R7,$
DJNZ R6,DEL1
POP PSW;去掉该句指令后,LCD开却无任何显示,加上后正常

显示
RET

DELAY1S:MOV R5,#100
D22:MOV R6,#20
D11:MOV R7,#248
DJNZ R7,$
DJNZ R6,D11
DJNZ R5,D22
RET

TAB1:DB "MON",00H
TAB2:DB "TEU",00H
TAB3:DB "WEN",00H
TAB4:DB "THU",00H
TAB5:DB "FRI",00H
TAB6:DB "SAT",00H
TAB7:DB "SUN",00H
TAB_NUM:DB "0123456789"
TAB8: DB 00H,03H,02H,03H,03H,03H,03H,03H,03H,03H,03H,03H,03H;用于平年天数十位比较
TAB9: DB 00H,02H,09H,02H,01H,02H,01H,02H,02H,01H,02H,01H,02H;用于平年天数个位比较
TAB10:DB 00H,02H,0AH,02H,01H,02H,01H,02H,02H,01H,02H,01H,02H;用于闰年天数个位比较
END

相关主题
文本预览
相关文档 最新文档