📄 wnl.asm
字号:
CJNE A,#00H,CON_460
MOV A,#0AH
CON_460:MOV 39H,A
MOV A,CONvert_mONth
MOV B,#10
DIV AB
SWAP A
ORL A,B
MOV C,f0
MOV ACC.7,C
MOV CONvert_mONth,A
ANL CONvert_mONth,#0FH
MOV 3CH,CONvert_mONth
SWAP A
ANL A,#01H
CJNE A,#00H,CON_461
MOV A,#0AH
CON_461:MOV 3FH,A ;转换后的农历月
POP PSW
RET ;结束转换
CON_50: MOV temp_Byte3,A ;temp_Byte3 存减去一月后的天数
JB f0,CON_52 ;是闰月,前推一月,月份不减
DEC CONvert_mONth
CON_52: MOV A,CONvert_mONth
CJNE A,temp_Byte4,CON_54
CPL f0 ;当前月与闰月相同,更改闰月标志
CON_54: SJMP CON_40
CON_60: MOV A,temp_Byte4 ;春节日小于当前日,农历年同公历年
CLR C
SUBB A,temp_Byte5
MOV temp_Byte4,A
JNC CON_62
DEC temp_Byte3 ;temp_Byte3 temp_Byte4 中为公历日离春节的天数****
CON_62: MOV CONvert_mONth,#1;农历月为1 月
CLR A
MOVC A,@A+dptr
MOV temp_Byte5,A
ANL A,#0f0h
SWAP A
XCH A,temp_Byte5 ;temp_Byte5 中为闰月,ACC 为当年农历表第一字节
CLR f0 ;第一个月肯定不是闰月
ANL A,#0fh
MOV temp_Byte1,A ;temp_Byte1 为1---4月的月大月小信息*
MOV A,#1
MOVC A,@A+dptr
MOV temp_Byte2,A ;temp_Byte2 为农历表的第二个字节*
ANL A,#0f0h ;取前四位月大月小信息*
ORL A,temp_Byte1 ;前8个月的月大月小信息*
SWAP A
MOV temp_Byte1,A
MOV A,#2
MOVC A,@A+dptr
MOV C,ACC.7
MOV A,temp_Byte2
ANL A,#0fh
SWAP A
MOV ACC.3,C
MOV temp_Byte2,A ;以上temp_Byte1,temp_Byte2 各BIT 存农历年大小
CON_70: MOV A,temp_Byte2
RLC A
MOV temp_Byte2,A
MOV A,temp_Byte1
RLC A
MOV temp_Byte1,A
JC CON_72
MOV B,#29 ;小月29 天处理
SJMP CON_74
CON_72: MOV B,#30 ;大月30 天
CON_74: MOV A,temp_Byte4
CLR C
SUBB A,B
JNC CON_78 ;低字节够减跳转
MOV B,A ;低字节不够减, B 暂存减后结果,
MOV A,temp_Byte3
JZ CON_76 ;高字节为0,不够减
DEC temp_Byte3
MOV temp_Byte4,B
SJMP CON_80
CON_76: MOV A,temp_Byte4 ;不够减结束月调整
LJMP CON_46 ;转日期加1 后,处理并保存转换后农历年月日
CON_78: MOV temp_Byte4,A ;temp_Byte3 temp_Byte4 天数为减去一月后天数
CON_80: MOV A,CONvert_mONth
CJNE A,temp_Byte5,CON_82
CPL f0 ;当前月与闰月相同,更改闰月标志
JNB f0,CON_82 ;更改标志后是非闰月,月份加1
SJMP CON_70
CON_82: INC CONvert_mONth;
SJMP CON_70
get_dAys_lOw: MOVC A,@A+PC ;取得常年过去月的天数的低字节
RET
DB 0,31,59,90,120,151,181,212,243,17,48,78
get_ruN_dAys_lOw:MOVC A,@A+PC ;取得闰年过去月的天数的低字节
RET
DB 0,31,60,91,121,152,182,213,244,18,49,79
mONth_dAtA:
;公历年对应的农历数据,每年三字节,
;格式第一字节BIT7-4 位表示闰月月份,值为0 为无闰月,BIT3-0 对应农历第1-4 月的大小
;第二字节BIT7-0 对应农历第5-12 月大小,第三字节BIT7 表示农历第13 个月大小
;月份对应的位为1 表示本农历月大(30 天),为0 表示小(29 天).
;第三字节BIT6-5 表示春节的公历月份,BIT4-0 表示春节的公历日期
DB 00Ch,096h,045h; 2000
DB 04dh,04Ah,0B8h; 2001
DB 00dh,04Ah,04Ch; 2002
DB 00dh,0A5h,041h; 2003
DB 025h,0AAh,0B6h; 2004
DB 005h,06Ah,049h; 2005
DB 07Ah,0Adh,0Bdh; 2006
DB 002h,05dh,052h; 2007
DB 009h,02dh,047h; 2008
DB 05Ch,095h,0BAh; 2009
DB 00Ah,095h,04eh; 2010
DB 00Bh,04Ah,043h; 2011
DB 04Bh,055h,037h; 2012
DB 00Ah,0d5h,04Ah; 2013
DB 095h,05Ah,0Bfh; 2014
DB 004h,0BAh,053h; 2015
DB 00Ah,05Bh,048h; 2016
DB 065h,02Bh,0BCh; 2017
DB 005h,02Bh,050h; 2018
DB 00Ah,093h,045h; 2019
DB 047h,04Ah,0B9h; 2020
DB 006h,0AAh,04Ch; 2021
DB 00Ah,0d5h,041h; 2022
DB 024h,0dAh,0B6h; 2023
DB 004h,0B6h,04Ah; 2024
DB 069h,057h,03dh; 2025
DB 00Ah,04eh,051h; 2026
DB 00dh,026h,046h; 2027
DB 05eh,093h,03Ah; 2028
DB 00dh,053h,04dh; 2029
DB 005h,0AAh,043h; 2030
DB 036h,0B5h,037h; 2031
DB 009h,06dh,04Bh; 2032
DB 0B4h,0Aeh,0Bfh; 2033
DB 004h,0Adh,053h; 2034
DB 00Ah,04dh,048h; 2035
DB 06dh,025h,0BCh; 2036
DB 00dh,025h,04fh; 2037
DB 00dh,052h,044h; 2038
DB 05dh,0AAh,038h; 2039
DB 00Bh,05Ah,04Ch; 2040
DB 005h,06dh,041h; 2041
DB 024h,0Adh,0B6h; 2042
DB 004h,09Bh,04Ah; 2043
DB 07Ah,04Bh,0Beh; 2044
DB 00Ah,04Bh,051h; 2045
DB 00Ah,0A5h,046h; 2046
DB 05Bh,052h,0BAh; 2047
DB 006h,0d2h,04eh; 2048
DB 00Ah,0dAh,042h; 2049
DB 035h,05Bh,037h; 2050
;以下子程序用于从当前公历日期,推算星期,
;入口:time_yeAr,time_month ,time_date ,定义公历年月日,BCD 码,其中月的
;BIT7 表示世纪,0 表示20 世纪,1 表示19 世纪,与PCF8563 一致
;出口time_week, 0-6 表示星期日-星期六,与PCF8563 一致,程序不改变入口数据
;使用资源:ACC,B,psw,temp_Byte1,temp_Byte2,temp_Byte3
WEEK: PUSH PSW
MOV time_year,51H ;公历年
MOV time_month,4FH ;公历月
MOV time_date,4EH ;公历日
GetWeek:MOV A,time_yeAr
MOV B,#16
DIV AB
MOV temp_Byte1,B
MOV B,#10
MUL AB
ADD A,temp_Byte1
MOV temp_Byte1,A ;temp_Byte1=年
MOV A,time_month
JB ACC.7,getw02
MOV A,#100
ADD A,temp_Byte1
MOV temp_Byte1,A ;20世纪年+100
MOV A,time_month
CLR ACC.7
getw02: JNB ACC.4,getw04
ADD A,#10
CLR ACC.4
getw04: MOV temp_Byte2,A ;temp_Byte2=月
MOV A,time_date
MOV B,#16
DIV AB
MOV temp_Byte3,B
MOV B,#10
MUL AB
ADD A,temp_Byte3
MOV temp_Byte3,A ;temp_Byte3=日
MOV A,temp_Byte1
ANL A,#03h
JNZ getw10 ;非闰年转移
MOV A,temp_Byte2
CJNE A,#3,getw06
getw06: JNC getw10 ;月大于2 转移
DEC temp_Byte3 ;份小于等于2,又是闰年,日减1
getw10: MOV A,temp_Byte2;
ACALL get_CorreCt ;取月校正表数据
ADD A,temp_Byte1
MOV B,#7
DIV AB ;B放年加校正日数之和后除7 的余数不先做这一步
;有可能数据溢出
MOV A,temp_Byte1
ANL A,#0fCh
RR A
RR A ;以上年除4 即闰年数
ADD A,B
ADD A,temp_Byte3
MOV B,#7
DIV AB
MOV A,B
MOV 34H,B
CJNE A,#00H,XQZY ;0为星期日
MOV 34H,#08H
XQZY: POP PSW
RET
get_COrreCt: MOVC A,@A+PC
RET
DB 0,3,3,6,1,4,6,2,5,0,3,5
;温度检测
;读出转换后的温度值
GET_TEMPER:
PUSH PSW
SETB P3.4
ACALL INIT_1820 ;先复位DS18B20
JB FLAG1,TSS2
POP PSW
RET ;判断DS1820是否存在?若DS18B20不存在则返回
TSS2: MOV A,#0CCH ;跳过ROM匹配
ACALL WRITE_1820
MOV A,#44H ;发出温度转换命令
ACALL WRITE_1820
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
ACALL DISP
ACALL INIT_1820 ;准备读温度前先复位
MOV A,#0CCH ;跳过ROM匹配
ACALL WRITE_1820
MOV A,#0BEH ;发出读温度命令
ACALL WRITE_1820
ACALL READ_18200 ;将读出的温度数据保存到35H/36H
POP PSW
RET
; 这是DS18B20复位初始化子程序
INIT_1820:
SETB P3.4
CLR P3.4
;主机发出延时537微秒的复位低脉冲
MOV R1,#3
TSR1: MOV R0,#50
DJNZ R0,$
DJNZ R1,TSR1
SETB P3.4 ;然后拉高数据线
NOP
NOP
MOV R0,#12H
TSR2: JNB P3.4,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2
AJMP TSR4 ;延时
TSR3: SETB FLAG1 ;置标志位,表示DS1820存在
AJMP TSR5
TSR4: CLR FLAG1 ;清标志位,表示DS1820不存在
AJMP TSR7
TSR5: MOV R0,#58
TSR6: DJNZ R0,TSR6 ;时序要求延时一段时间
TSR7: SETB P3.4
RET
;写DS18B20的子程序(有具体的时序要求)
WRITE_1820:
MOV R2,#8;一共8位数据
CLR C
WR1: CLR P3.4
MOV R3,#3
DJNZ R3,$
RRC A
MOV P3.4,C
MOV R3,#11
DJNZ R3,$
SETB P3.4
NOP
DJNZ R2,WR1
SETB P3.4
RET
; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_18200:
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#29H ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00: MOV R2,#8 ;数据一共有8位
RE01: CLR C
SETB P3.4
NOP
NOP
CLR P3.4
NOP
NOP
NOP
SETB P3.4
MOV R3,#4
RE10: DJNZ R3,RE10
MOV C,P3.4
MOV R3,#23
RE20: DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
;1MS延时程序,LED显示程序用
DELAY: PUSH PSW ;延时500毫秒
DL1MS: MOV R6,#18H
DL1: MOV R7,#18H
DL2: DJNZ R7,DL2
DJNZ R6,DL1
POP PSW
RET
DL20MS: PUSH PSW
MOV R3,#25H ;8毫秒*32=0.196秒
DL20MS1:ACALL DISP
DJNZ R3,DL20MS1
POP PSW
RET
DL05S: PUSH PSW
MOV R3,#20H ;8毫秒*32=0.196秒
DL05S1: ACALL DISP
DJNZ R3,DL05S1
POP PSW
RET
DL1S: ACALL DL05S
ACALL DL05S
RET
Send_Byte:
CLR RST
NOP
CLR SCLK
NOP
SETB RST
NOP
MOV A,Command
MOV BitCnt,#08h
S_Byte0:
RRC A
MOV IO_DATA,C
NOP
SETB SCLK
NOP
CLR SCLK
DJNZ BitCnt,S_Byte0
NOP
S_Byte1:
MOV A,@R0
MOV BitCnt,#08h
S_Byte2:
RRC A
MOV IO_DATA,C
NOP
SETB SCLK
NOP
CLR SCLK
DJNZ BitCnt,S_Byte2
INC R0
DJNZ ByteCnt,S_Byte1
NOP
CLR RST
RET
;********************************************************************
;接收数据程序;
;名称:Receive_Byte
;描述:从被控器HT1380 接收ByteCnt 个字节数据
;命令字节地址在Command 中
;所接收数据的字节数在ByteCnt 中接收的数据在RcvDat 缓冲区中
;********************************************************************
Receive_Byte:
CLR RST
NOP
CLR SCLK
NOP
SETB RST
MOV A,Command
MOV BitCnt,#08h
R_Byte0:
RRC A
MOV IO_DATA,C
NOP
SETB SCLK
NOP
CLR SCLK
DJNZ BitCnt,R_Byte0
NOP
R_Byte1:
MOV BitCnt,#08h
R_Byte2:
NOP
SETB IO_DATA
NOP
MOV C,IO_DATA
RRC A
SETB SCLK
NOP
CLR SCLK
NOP
DJNZ BitCnt,R_Byte2
MOV @R1,A
INC R1
DJNZ ByteCnt,R_Byte1
NOP
CLR RST
RET
Write_Enable:
MOV Command,#8Eh
MOV ByteCnt,#1
MOV R0,#XmtDat
MOV XmtDat,#00h
ACALL Send_Byte
RET
Write_Disable:
MOV Command,#8Eh
MOV ByteCnt,#1
MOV R0,#XmtDat
MOV XmtDat,#80h
ACALL Send_Byte
RET
Osc_Enable:
MOV Command,#80h
MOV ByteCnt,#1
MOV R0,#XmtDat
MOV XmtDat,#00h
ACALL Send_Byte
RET
Osc_Disable:
MOV Command,#80h
MOV ByteCnt,#1
MOV R0,#XmtDat
MOV XmtDat,#80h
ACALL Send_Byte
RET
Read_Multiplebyte:
MOV Command,#0BFh
MOV ByteCnt,#8
MOV R1,#RcvDat
ACALL Receive_Byte
RET
Write_Singlebyte:
MOV ByteCnt,#1
MOV R0,#XmtDat
ACALL Send_Byte
RET
Write_Singlebyte1:
MOV Command,#82h
MOV ByteCnt,#1
MOV R0,#XmtDat
MOV XmtDat,#88h
ACALL Send_Byte
RET
Read_Singlebyte:
MOV ByteCnt,#1
MOV R1,#RcvDat
ACALL Receive_Byte
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -