⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wnl.asm

📁 万年历汇编源程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
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 + -