📄 ds18b20.asm
字号:
;****************************************************
;变量定义
;****************************************************
DQ BIT P2.4 ;DS18B20数据位
FLAG1 BIT 00H
SIGN BIT 01H ;符号位
MSB EQU 30H ;转换数据高位字节
LSB EQU 31H ;转换数据低位字节
INTEG EQU 32H ;转换数据整数部分
DECIM EQU 33H ;转换数据小数部分
SEG_S EQU 34H ;符号位段码
SEG_I3 EQU 35H
SEG_I2 EQU 36H
SEG_I1 EQU 37H ;3位整数段码
SEG_D1 EQU 38H ;1位小数段码
SEG_C EQU 39H ;符号"C"段码
;******************************************************
;主程序
;******************************************************
ORG 0000H
MAIN: LCALL INIT_1820 ;DS18B20初始化
LCALL GET_TEMPER ;读取转换数据
LCALL DATA_PROC ;数据处理
LCALL SEG_GEN ;生成显示码
LCALL DISPLAY ;数码显示
SJMP MAIN
;****************************************************************
;DS18B20复位初始化子程序
;****************************************************************
INIT_1820: SETB DQ
NOP
CLR DQ ;主机发出延时537微秒的复位低脉冲
MOV R1,#3
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 TSR6
TSR5: MOV R0,#117
DJNZ R0,$ ;时序要求延时一段时间
TSR6: SETB DQ
RET
;*****************************************************************
;读出转换后的温度值
;*****************************************************************
GET_TEMPER: SETB DQ
LCALL INIT_1820 ;先复位DS18B20
JB FLAG1,TSS2
RET ;判断DS1820是否存在
TSS2: MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H ;发出温度转换命令
LCALL WRITE_1820
LCALL DELAY ;等待AD转换结束,12位转换需750微秒
LCALL INIT_1820 ;准备读温度前先复位
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ;发出读温度命令
LCALL WRITE_1820
LCALL READ_18200 ;将读出的温度数据保存到35H/36H
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,#2 ;将温度高位和低位从DS18B20中读出
MOV R1,#31H ;低位存入31H,高位存入30H
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
DJNZ R3,$
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
;***********************************************************
;数据处理子程序,判断正负,并分离转换值的整数和小数部分
;符号位为SIGN,0为正,1为负
;整数部分存放在INTEG(32H)中,小数部分存放在DECIM(33H)中
;***********************************************************
DATA_PROC: CLR C
CLR SIGN
MOV A,MSB
RLC A
JC NEG ;判断符号位
LJMP PROC
NEG: CLR C ;对负数取补码
SETB SIGN
MOV A,LSB
CPL A
ADD A,#1
MOV LSB,A
MOV A,MSB
CPL A
ADDC A,#0
MOV MSB,A
PROC: MOV A,LSB ;分离转换值的整数和小数部分
ANL A,#0FH
MOV DECIM,A ;存储小数部分
MOV A,MSB
SWAP A
ANL A,#0F0H
MOV INTEG,A
MOV A,LSB
SWAP A
ANL A,#0FH
MOV R0,INTEG
ORL A,R0
MOV INTEG,A ;存储整数部分
RET
;***************************************************************
;生成显示码子程序
;符号位段码存放在SEG_S中,整数段码存放在SEG_I3到SEG_I1中
;小数部分段码存放在SEG_D1到SEG_D4中
;***************************************************************
SEG_GEN: MOV DPTR,#TABLE
JB SIGN,S_NEG
MOV SEG_S,#00H
SJMP S_INT
S_NEG: MOV SEG_S,#40H
S_INT: MOV A,INTEG
MOV B,#100
DIV AB
MOVC A,@A+DPTR
MOV SEG_I3,A ;百位数段码
MOV A,B
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV SEG_I2,A ;十位数段码
MOV A,B
MOVC A,@A+DPTR
ORL A,#80H ;加小数点
MOV SEG_I1,A ;个位数段码
MOV DPTR,#SWITCH
MOV A,DECIM
MOV B,DECIM
ADD A,B
JMP @A+DPTR ;根据小数值查表,求段码
SWITCH: AJMP K0
AJMP K1
AJMP K2
AJMP K3
AJMP K4
AJMP K5
AJMP K6
AJMP K7
AJMP K8
AJMP K9
AJMP K10
AJMP K11
AJMP K12
AJMP K13
AJMP K14
AJMP K15
K0: MOV SEG_D1,#3FH
AJMP RETURN
K1: MOV SEG_D1,#06H
AJMP RETURN
K2: MOV SEG_D1,#06H
AJMP RETURN
K3: MOV SEG_D1,#5BH
AJMP RETURN
K4: MOV SEG_D1,#4FH
AJMP RETURN
K5: MOV SEG_D1,#4FH
AJMP RETURN
K6: MOV SEG_D1,#66H
AJMP RETURN
K7: MOV SEG_D1,#66H
AJMP RETURN
K8: MOV SEG_D1,#6DH
AJMP RETURN
K9: MOV SEG_D1,#7DH
AJMP RETURN
K10: MOV SEG_D1,#7DH
AJMP RETURN
K11: MOV SEG_D1,#07H
AJMP RETURN
K12: MOV SEG_D1,#7FH
AJMP RETURN
K13: MOV SEG_D1,#7FH
AJMP RETURN
K14: MOV SEG_D1,#6FH
AJMP RETURN
K15: MOV SEG_D1,#6FH
AJMP RETURN
RETURN: MOV SEG_C,#39H ;符号"C"的段码
RET
;*************************************************************
;显示子程序,首位为符号位,三位整数,1位小数
;最后一位"C"为摄氏度标志
;*************************************************************
DISPLAY: MOV P3,#0FFH
CLR P3.0
MOV P0,SEG_S
LCALL DELAY
SETB P3.0
CLR P3.1
MOV P0,SEG_I3
LCALL DELAY
SETB P3.1
CLR P3.2
MOV P0,SEG_I2
LCALL DELAY
SETB P3.2
CLR P3.3
MOV P0,SEG_I1
LCALL DELAY
SETB P3.3
CLR P3.4
MOV P0,SEG_D1
LCALL DELAY
SETB P3.4
CLR P3.5
MOV P0,SEG_C
LCALL DELAY
SETB P3.5
RET
;**********************************************************
;延时子程序,延时5ms
;**********************************************************
DELAY: MOV R5,#5 ;延时5ms
D1: MOV R6,#248
DJNZ R6,$
DJNZ R5,D1
RET
;**********************************************************
TABLE: DB 3FH,06H,5BH,4FH,66H ;段码表
DB 6DH,7DH,07H,7FH,6FH
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -