📄 wnl.asm
字号:
start_year EQU 01; 定义查询表起始年份,01--199 表示1901-2099 年
;以下三单元为需转换的公历日期是子程序的入口数据
time_year DATA 5CH
time_month DATA 5DH ;BIT7 表示世纪,为1 表示19 世纪,为0 表示20 世纪
time_date DATA 5EH
;以下三单元存转换后农历日期与入口单元重叠,如要保留入口信息,请重定义出口地址
CONvert_yeAr DATA 5FH
CONvert_mONth DATA 60H ;BIT7 为1 表示闰月
CONvert_dAte DATA 61H
temp_Byte1 DATA 62H
temp_Byte2 DATA 63H
temp_Byte3 DATA 64H
temp_Byte4 DATA 65H
temp_Byte5 DATA 66H
time_week DATA 67H ;星期天出口
TEMPER_L EQU 29H ;用于保存读出温度的低8位
TEMPER_H EQU 28H ;用于保存读出温度的高8位
FLAG1 EQU 68H ;是否检测到DS18B20标志位
YJ EQU 5BH
;HT1380
BitCnt EQU 48H ;数据位计数器
ByteCnt EQU 49H ;数据字节计数器
Command EQU 4AH ;命令字节地址
RcvDat EQU 4BH ;接收数据缓冲区
XmtDat EQU 53H ;发送数据缓冲区
;--->5B
IO_DATA Bit P3.3 ;数据传送总线
SCLK Bit P3.5 ;时钟控制总线
RST Bit P3.2 ;复位总线
DAT Bit P2.0
CLK Bit P2.1
ORG 0000H
LJMP START
ORG 0003H
RETI
ORG 000BH
RETI
ORG 0013H
RETI
ORG 001BH
RETI
ORG 0023H
RETI
ORG 0030H
START: MOV TMOD,#11H ; 定时器0与1方式都为1
MOV PSW,#00H
MOV SP,#69H
MOV SCON,#00H
MOV P1,#0FFH
MOV 20H,#00H
MOV 21H,#00H
MOV 22H,#00H
MOV 23H,#00H
MOV R7,#00H
CLR P3.7
CLR 21H.0
ACALL Write_Enable
ACALL HT1380
;MOV 32H,#08H ;日个位
;MOV 33H,#04H
;MOV 34H,#05H ;星期
;MOV 35H,#06H ;日十位
;MOV 36H,#09H ;农历日个位
;MOV 37H,#08H ;秒个位
;MOV 38H,#09H ;月个位
;MOV 39H,#02H ;农历日十位
;MOV 3AH,#01H ;秒十位
;MOV 3BH,#02H ;月十位
;MOV 3CH,#02H ;农历月个位
;MOV 3DH,#04H ;分个位
;MOV 3EH,#05H ;年个位
;MOV 3FH,#00H ;农历月十位
;MOV 40H,#07H ;分十位
;MOV 41H,#08H ;年十位
;MOV 42H,#09H ;温度个位
;MOV 43H,#01H ;时个位
MOV 44H,#00H ;年百位
;MOV 45H,#03H ;温度十位
;MOV 46H,#00H ;时十位
MOV 47H,#02H ;年千位
ZC1: ACALL DISP
ACALL Read_Multiplebyte
INC 20H
ACALL SS0
CLR P1.0
SETB P1.1
JB P3.7,ZC3
SETB P1.0
CLR P1.1
JB P3.7,ZC4
ZC2: SJMP ZC1
ZC3: AJMP KEY1
ZC4: AJMP KEY2
SS0: MOV R4,20H
CJNE R4,#20H,SS1
MOV 20H,#00H
JB 21H.0,SS3
ACALL SS2
SS1: RET
SS2: SETB 21H.0
ACALL ONN
ACALL SCC
RET
SS3: CLR 21H.0
ACALL OFF
ACALL SCC1
RET
SCC: MOV 30H,#0EH
MOV 31H,#0BH
RET
SCC1: MOV 30H,#0AH ;定闹
MOV 31H,#0AH ;秒闪
RET
ONN: ACALL NONGLI
ACALL WEEK
ACALL GET_TEMPER ;温度
;显示范围00到99度,显示精度为1度
;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位
;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度
;这个转化温度的方法可是我想出来的哦~~非常简洁无需乘于0.0625系数
PUSH ACC
MOV A,29H
MOV C,40H ;将28H中的最低位移入C
RRC A
MOV C,41H
RRC A
MOV C,42H
RRC A
MOV C,43H
RRC A
ACALL HBCD
MOV 29H,A
ANL 29H,#0FH
MOV 42H,29H
SWAP A
ANL A,#0FH
MOV 45H,A
POP ACC
ACALL HT1380
MOV 5CH,51H
MOV 5DH,4FH
MOV 5EH,4EH
RET
OFF: ACALL Read_Multiplebyte
MOV A,R7
CJNE A,#01H,L01
ACALL HT1380
RET
L01: CJNE A,#02H,L02
MOV 51H,#0AAH ;关年
ACALL HT1380
RET
L02: CJNE A,#03H,L03
MOV 4FH,#0AAH ;关月
ACALL HT1380
RET
L03: CJNE A,#04H,L04
MOV 4EH,#0AAH ;关日
ACALL HT1380
RET
L04: CJNE A,#05H,L05
MOV 4DH,#0AAH ;关时
ACALL HT1380
RET
L05: CJNE A,#06H,L06
MOV 4CH,#0AAH ;关分
ACALL HT1380
RET
L06: MOV R7,#01H
RET
KEY1: ACALL DL20MS
INC R7
KEYS2: JNB P3.7,KEYS3 ;按键释放退出
AJMP KEY1
KEYS3: AJMP ZC2
KEY2: ACALL DL20MS
KEYY1: INC R5
MOV A,R7
CJNE A,#02H,KEYY3 ;加1年
MOV R6,#32H
MOV Command,#8Ch
ACALL BJ00
AJMP KEYY7
KEYY3: CJNE A,#03H,KEYY4 ;加1月
MOV R6,#0CH
MOV Command,#88h
ACALL BJ00
AJMP KEYY7
KEYY4: CJNE A,#04H,KEYY5 ;加1日
MOV R6,#1FH
MOV Command,#86h
ACALL BJ00
AJMP KEYY7
KEYY5: CJNE A,#05H,KEYY6 ;加1时
MOV R6,#18H
MOV Command,#84h
ACALL BJ00
AJMP KEYY7
KEYY6: CJNE A,#06H,KEYY7 ;加1分
MOV R6,#3CH
MOV Command,#82h
ACALL BJ00
KEYY7: MOV XmtDat,A
KEYY8: ACALL Write_Singlebyte
JB P3.7,KEY2 ;按键释放退出
AJMP ZC2
BJ00: MOV A,R5
CJNE A,R6,BJ01
AJMP HBCD
BJ01: JC HBCD
MOV R5,#01H
MOV A,R5
HBCD: MOV B,#100 ;分离出百位,存放在R3中
DIV AB
MOV A,#10 ;余数继续分离十位和个位
XCH A,B
DIV AB
SWAP A
ORL A,B ;将十位和个位拼装成BCD码
HBCD1: RET
HT1380:PUSH ACC
;秒
MOV A,4BH
ANL 4BH,#0FH
MOV 37H,4BH
SWAP A
ANL A,#0FH
MOV 3AH,A
;分
MOV A,4CH
ANL 4CH,#0FH
MOV 3DH,4CH
SWAP A
ANL A,#0FH
MOV 40H,A
;时
MOV A,4DH
ANL 4DH,#0FH
MOV 43H,4DH
SWAP A
ANL A,#0FH
CJNE A,#00H,SI11
MOV A,#0AH
SI11: MOV 46H,A
;日
MOV A,4EH
ANL 4EH,#0FH
MOV 32H,4EH
SWAP A
ANL A,#0FH
CJNE A,#00H,RI11
MOV A,#0AH
RI11: MOV 35H,A
;月
MOV A,4FH
ANL 4FH,#0FH
MOV 38H,4FH
SWAP A
ANL A,#0FH
CJNE A,#00H,YE11
MOV A,#0AH
YE11: MOV 3BH,A
;年
NIAN: MOV A,51H
ANL 51H,#0FH
MOV 3EH,51H
SWAP A
ANL A,#0FH
MOV 41H,A
POP ACC
RET
DISP: PUSH ACC
PUSH PSW
SETB RS0
CLR RS1
MOV R0,#30H
MOV R5,#08H
MOV R4,#03H
MOV R2,#08H
MOV DPTR,#TAB
MOV YJ,#0FEH
DISP1: MOV P1,#0FFH
MOV A,@R0
CLR C
MOVC A,@A+DPTR
XS1: RRC A ;左移一位
JC JK1 ;C等于1转移
CLR DAT
SJMP JK2
JK1: SETB DAT
NOP
JK2: CLR CLK
SETB CLK ;CLK产生上升沿
DJNZ R2,XS1
MOV R2,#08H
INC R0
DJNZ R4,DISP1
MOV P1,YJ
ACALL YJQH
ACALL DELAY
MOV R4,#03H
DJNZ R5,DISP1
MOV P1,#0FFH
POP PSW
POP ACC
RET
YJQH: PUSH ACC
MOV A,YJ
RL A
MOV YJ,A
YJQH1: POP ACC
RET
;0,1,2,3,4,5,6,7,8,9,关,秒闪,定闹,蜂鸣器D
TAB: DB 80H,0EBH,12H,0AH,68H,0CH,04H,0ABH,00H,08H,0FFH,0F3H,0F7H,0BEH
;以下为公历转农历子程序
NONGLI: PUSH PSW
MOV time_year,51H ;公历年
MOV time_month,4FH ;公历月
MOV time_date,4EH ;公历日
CONvert:MOV A,time_year ;将年月日转化为HEX 格式
MOV B,#16
DIV AB
MOV CONvert_yeAr,B
MOV B,#10
MUL AB
ADD A,CONvert_yeAr
MOV CONvert_yeAr,A
MOV A,time_month
MOV C,ACC.7 ;ACC.7世纪标志
MOV f0,C ;f0暂存世纪标志,仅用于数据表定位
CLR ACC.7
JNB ACC.4,CON_02
CLR ACC.4 ;ACC.4 为1 表示大于10 月
ADD A,#10
CON_02: MOV CONvert_mONth,A
MOV A,time_date
MOV B,#16
DIV AB
MOV CONvert_dAte,B
MOV B,#10
MUL AB
ADD A,CONvert_dAte
MOV CONvert_dAte,A
MOV DPTR,#mONth_dAtA;以下定位本年数据在表格中的位置
MOV A,CONvert_yeAr
JB f0,CON_06 ;当前为19 世纪年跳转
ADD A,#01 ;从19 世纪起定义表格起始年,20 世纪要加100 年
CON_06: CLR C
SUBB A,#stArt_yeAr
MOV B,#3 ;表格每年3 字节
MUL AB
ADD A,dpl
MOV dpl,A
MOV A,B
ADDC A,dph
MOV dph,A
MOV A,#2
MOVC A,@A+dptr ;读本年表格最后一字节(春节日期)
CLR ACC.7 ;ACC.7 是闰年第13 个月大小,在此不用
MOV B,#32
DIV AB
MOV temp_Byte1,A ;春节月份
MOV temp_Byte2,B ;春节日
; 以下计算当前日期距元旦天数
MOV temp_Byte3,#0 ;设距元旦天数高位为0
MOV A,CONvert_mONth
CJNE A,#10,CON_08
CON_08: JC CON_09 ;9月以前日子数小于256 天,高字节为0(9 月份过去的整月为8 个月)
MOV temp_Byte3,#1
CON_09: MOV A,CONvert_yeAr
ANL A,#03h ;ACC 为除4 的余数
JNZ CON_10 ;转常年处理
; 年除4 余数为0 是闰年
MOV A,CONvert_mONth
ACALL get_ruN_dAys_lOw ;取得闰年过去月的天数的低字节
SJMP CON_12
CON_10: MOV A,CONvert_mONth
ACALL get_dAys_lOw ;取得常年过去月的天数的低字节
CON_12: MOV B,CONvert_dAte ;当前日
DEC B ;因为日期从1 日起,而不是0 日起
ADD A,B ;过去的整月天数加当月天数
MOV temp_Byte4,A
JNC CON_14
INC temp_Byte3 ;temp_Byte3,temp_Byte4 分别为公历年过去的天数的高低字节
; 以下求春节距元旦天数,因肯定小于256 天所以只用一字节表示
CON_14: MOV A,temp_Byte1
ACALL get_dAys_lOw ;春节不会在3 月份,不用考虑闰年
DEC A ;因为日期从1 日起
ADD A,temp_Byte2
MOV temp_Byte5,A ;temp_Byte5,为春节距元旦天数
MOV A,CONvert_mONth
CJNE A,temp_Byte1,CON_20 ;转换月与春节月比较***
MOV A,CONvert_dAte
CJNE A,temp_Byte2,CON_20 ;转换日与春节日比较
CON_20: JC CON_22
AJMP CON_60 ;当前日大于等于春节日期,公历年与农历年同年份转CON_60
CON_22: MOV A,CONvert_yeAr ;不到春节,农历年比公历年低一年***************
MOV A,#01 ;年有效数0-99
CON_24: DEC A
MOV CONvert_yeAr,A
MOV A,dpl
CLR C
SUBB A,#3
MOV dpl,A
JNC CON_26
DEC dph ;表格指针指向上一年
CON_26: MOV A,temp_Byte5
CLR C
SUBB A,temp_Byte4
MOV temp_Byte3,A ;temp_Byte3 中为当前日离春节的天数
MOV CONvert_mONth,#12;农历月为12 月
CLR f0 ;1901-2099 年没有闰12 月,清闰月标志
CLR A
MOVC A,@A+dptr
ANL A,#0f0h
SWAP A
MOV temp_Byte4,A ;temp_Byte4 中为闰月
JZ CON_30 ;没有闰月转移
MOV A,#2 ;有闰月,取第13 个月天数
MOVC A,@A+dptr
MOV C,ACC.7
MOV A,#1
MOVC A,@A+dptr
RLC A ;ACC 中为最后6 个月的大小值
SJMP CON_34
CON_30: MOV A,#1
MOVC A,@A+dptr ;ACC 中为最后6 个月的大小值
CON_34: MOV temp_Byte5,A
CON_40: MOV A,temp_Byte5
RRC A
MOV temp_Byte5,A
JC CON_42
MOV B,#29 ;小月29 天
SJMP CON_44
CON_42: MOV B,#30 ;大月30 天
CON_44: MOV A,temp_Byte3
CLR C
SUBB A,B
JZ CON_46 ;正好够减,就是农历日1 日
JNC CON_50
;不够减一月天数,结束农历月调整
CPL A ;求补取绝对值
INC A
CON_46: INC A ;加1 即为农历日
MOV B,#10 ;转换并保存农历日,月,年
DIV AB
SWAP A
ORL A,B
MOV CONvert_dAte,A ;转换后的农历日
ANL CONvert_dAte,#0FH
MOV 36H,CONvert_dAte
SWAP A
ANL A,#0FH
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -