📄 ds1820.asm
字号:
TEMPER_L EQU 28H ;用于保存读出温度的低8位
TEMPER_H EQU 29H ;用于保存读出温度的高8位
TEMPER EQU 50H ;用于存放读出温度的整数有效部分
TEMP_BREAK EQU 34H ;用于存放拆散后温度的百位,十位,个,小数位,34H为首地址
FLAG1 EQU 20H.5 ;是否检测到DS18B20标志位
DQ EQU P0.3 ;数据线
;-----------------------------------------------lcd-----------------------------
RS EQU P3.5
RW EQU P3.4
E EQU P3.6
XPOS EQU 22H ;行方向
YPOS EQU 21H ;列方向
;----------------------------------------------------------------------------------
ORG 0000H
LJMP START
ORG 0030H
START:
LCALL LCDRESET
LCALL DISPLAY1
MAIN: LCALL GET_TEMPER
nop
LCALL CONT_TEMPER
LCALL TEMP_BREAKS
LCALL DISPLAY
LJMP MAIN
;-----------------------------------------DISPLAY----------------------------
DISPLAY:
JB 20H.0,SS
XX: LCALL ADD_ASCII
LCALL DISBUF
RET
SS:
MOV TEMP_BREAK,#'-'-48
CLR 20H.0
LJMP XX
ADD_ASCII: MOV R0,#TEMP_BREAK
LCALL ADDS
INC R0
LCALL ADDS
INC R0
LCALL ADDS
INC R0
LCALL ADDS
RET
DISBUF: MOV R0,#TEMP_BREAK
MOV A,@R0
MOV XPOS,#4
MOV YPOS,#1
LCALL LCDWRITE
INC R0
INC XPOS
MOV A,@R0
LCALL LCDWRITE
INC R0
INC XPOS
MOV A,@R0
LCALL LCDWRITE
INC XPOS
INC XPOS
INC R0
MOV A,@R0
LCALL LCDWRITE
RET
ADDS: MOV A,@R0
ADD A,#48
MOV @R0,A
RET
DISPLAY1: MOV XPOS,#0
MOV YPOS,#0
MOV DPTR,#TAB
MOV R0,#0
DS_LP: MOV A,R0
MOVC A,@A+DPTR
LCALL LCDFILL
INC R0
CJNE R0,#32, DS_LP
RET
;-----------------------------------RESET_1820------------------------------------;
RESET_1820:
SETB DQ
NOP
CLR DQ
MOV R1,#3 ;主机发出延时537微秒的复位低脉冲
TSR1: MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB DQ ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#25H
TSR2:
JNB DQ,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ; 延时
TSR3:
SETB FLAG1 ; 置标志位,表示DS1820存在
LJMP TSR5
TSR4:
CLR FLAG1 ; 清标志位,表示DS1820不存在
LJMP TSR7
TSR5:
MOV R0,#117
TSR6:
DJNZ R0,TSR6 ; 时序要求延时一段时间
TSR7:
SETB DQ
RET
;------------------------读出转换后的温度值--------------------------
GET_TEMPER:
SETB DQ
LCALL RESET_1820 ;先复位DS18B20
JB FLAG1,TSS2
RET ; 判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H ; 发出温度转换命令
LCALL WRITE_1820
;LCALL DISPLAY ;这里等待AD转换结束,12位的话750ms
LCALL DELAY400MS
LCALL DELAY400MS
LCALL RESET_1820 ;准备读温度前先复位
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_18200 ; 将读出的温度数据保存到29H/28H
RET
;-----------------------------;写DS18B20的子程序----------------------------
WRITE_1820:
MOV R2,#8 ;一共8位数据
CLR C
WR1:
CLR DQ
MOV R3,#6
DJNZ R3,$
RRC A
MOV DQ,C
MOV R3,#23
DJNZ R3,$
SETB DQ
NOP
DJNZ R2,WR1
SETB DQ
RET
;-------------------------------读DS18B20的程序,从DS18B20中读出两个字节的温度数据-------------------------
READ_18200:
MOV R4,#4 ; 将温度高位和低位从DS18B20中读出
MOV R1,#TEMPER_L ;低位存入28H(TEMPER_L),高位存入29H(TEMPER_H)
RE00:
MOV R2,#8 ;数据一共有8位
RE01:
CLR C
SETB DQ
NOP
NOP
CLR DQ
NOP
NOP
NOP
SETB DQ
MOV R3,#9
RE10:
DJNZ R3,RE10
MOV C,DQ
MOV R3,#23
RE20:
DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
INC R1
DJNZ R4,RE00
RET
;-------------------------------CONT_TEMP----------------------
CONT_TEMPER:
JNB FLAG1,TEMP_RET1
JNB 29H.7,PLUS ;29H中的最高位是否为1(温度<0),20H.0=1
SETB 20H.0 ;负数取补
MOV A,TEMPER_L
CPL A
ADD A,#01H
MOV TEMPER_L,A
MOV A,TEMPER_H
CPL A
ADDC A,#00H
MOV TEMPER_H,A
PLUS: MOV A,TEMPER_L ;将28H中的低4位移入 TEMPER_L中
ANL A,#0F0H
SWAP A
MOV TEMPER,A
MOV A,TEMPER_H
ANL A,#0FH
SWAP A
ORL A,TEMPER
ERW: MOV TEMPER,A
TEMP_RET1: RET
TEMP_BREAKS:
MOV R0,#TEMP_BREAK ;将TEMPER的十六进制数转换成10进制
MOV A,TEMPER
MOV B,#100
DIV AB
MOV @R0,A
INC R0
MOV A,B
MOV B,#10
DIV AB
MOV @R0,A
INC R0
MOV @R0,B
INC R0
ANL TEMPER_L,#0FH ;小数点后一位进制转换
MOV A,TEMPER_L
MOV B,#6H
MUL AB
MOV B,#10
DIV AB
MOV @R0,A
RET
;-------------------------LCD---------------------DISPLAY------------------MODLE----------------------------------------
;-------------------------------LCD 写满屏幕地址和字符数据指令--------------------------------
LCDFILL:
LCALL LCDWRITE
INC XPOS
MOV A,XPOS
CJNE A,#16,RETURN
INC YPOS
MOV A,YPOS
CJNE A,#2,RETURN
RETURN:RET
;-----------------------------------LCD 写一个地址和字符数据指令-----------------------------------
LCDWRITE:
LCALL LCDPOS ;lcd 写地址指令
LCALL LCDWD ;LCD 写字符指令
RET
;------------------------------LCD 写地址指令--------------------------------------------------------
LCDPOS:PUSH ACC
ANL XPOS,#0FH
ANL YPOS,#01H
MOV A,YPOS
CJNE A,#00,LPS_LAY
MOV A,XPOS
LJMP LPS_LAX
LPS_LAY:MOV A,XPOS
ADD A,#40H
LPS_LAX:ORL A,#80H
LCALL LCDWC
POP ACC
RET
;------------------------------------LCD RESET--------------------------------------------------------------------
LCDRESET:
LCALL DELAY5MS
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
;----------------------------------LCD write not check,写指令------------------------
LCDWCN:CLR RS
CLR RW
MOV P1,A
SETB E
NOP
CLR E
RET
;--------------------------LCD busy check,wait till not busy(读状态,判断是否忙)-----------------------------------
WAITIDLE:
PUSH ACC
MOV P1,#0FFH
CLR RS
SETB RW
SETB E
WTD_PA:NOP
JB P1.7,WTD_PA
CLR E
POP ACC
RET
;--------------------------LCD WRITE TATA(写数据)----------------------------------------
LCDWD:LCALL WAITIDLE
MOV P1,A
CLR RW
SETB RS
SETB E
NOP
CLR E
RET
;----------------------------DELAY---------------------------------
DELAY5MS:MOV R5,#5
DL2: MOV R6,#250
DL1: NOP
NOP
DJNZ R6,DL1
DJNZ R5,DL2
RET
DELAY400MS:
MOV R5,#20 ;延时子程序(400MS)
DL4_PA: MOV R6,#100
DL4_PB: MOV R7,#100
DJNZ R7,$
DJNZ R6,DL4_PB
DJNZ R5,DL4_PA
RET
TAB: DB '*','*','T','e','m','p','e','r','a','t','u','r','e','*','*','*'
DB '*','*','*','*','*','*','*','.','*','^','C','*','*','*','*','*'
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -