$MOD51          

ORG 0000H             ;程序起始地址
LJMP MAIN 
ORG	000BH		      ;T0中断入口
LJMP INT_T0

;------------------------------------------------------------------------
ORG 1000H
MAIN:	 
	MOV TMOD,#21H     ;设置定时/计数器T1位方式2,8位自动重装模式。定时/计数器T0位方式1,16位定时/计数器模式
	MOV PCON,#00H	  ;SMOD=0  
	MOV TH1,#0FDH	  ;设定波特率为9600
	MOV TL1,#0FDH
	MOV SCON,#50H	  ;设置串口为8位模式,无校验
	MOV IE,#82H	      ;允许全局中断、T0中断
	MOV IP,#00H		  ;所有中断优先级为0
	SETB TR1		  ;使能T1
	SETB F0			  ;F0作为定时/计数器T0中断退出标志位(0表示退出中断)
	SETB P3.7		  ;使总线高电平
MLOOP:
	LCALL INIT
	LCALL SKIP_ROM
	LCALL CONVERT_T
	LCALL DELAY_750ms

	LCALL INIT
	LCALL SKIP_ROM
	LCALL READ_PAD

	LCALL READ_BYTE
	MOV SBUF,A
	LCALL READ_BYTE
	MOV SBUF,A
	LCALL DELAY_750ms

	JMP MLOOP

	RET
;------------------------------------------------------------------------

;#DS18B20的复位函数
;------------------------------------------------------------------------
RESET:
	CLR P3.7		  ;使总线低电平
	MOV B,#48
	LCALL DELAY
	SETB P3.7		  ;释放总线电平,接收应答信号

	RET
;------------------------------------------------------------------------

;#DS18B20的初始化函数
;------------------------------------------------------------------------
INIT:
	LCALL RESET
ILOOP1:
	JB P3.7,ILOOP1    ;等待总线被从机拉低
ILOOP2:
	JNB P3.7,ILOOP2	  ;等待总线被从机拉高
	MOV B,#48
	LCALL DELAY

	RET
;------------------------------------------------------------------------

;#写1时序
;------------------------------------------------------------------------
WRITE1:
	CLR P3.7		  ;使总线低电平
	NOP
	NOP
	SETB P3.7		  ;使总线高电平
	MOV B,#6
	LCALL DELAY

	RET
;------------------------------------------------------------------------

;#写0时序
;------------------------------------------------------------------------
WRITE0:
	CLR P3.7		  ;使总线低电平	
	MOV B,#6
	LCALL DELAY
	SETB P3.7		  ;释放总线

	RET
;------------------------------------------------------------------------

;#写1字节
;------------------------------------------------------------------------
WRITE_BYTE:
	MOV R2,#8
LAB:
	RRC A
	JC CALL_WRITE1
	LCALL WRITE0
	JMP LAB1
CALL_WRITE1:
	LCALL WRITE1
LAB1:
	DJNZ R2,LAB

	RET
;------------------------------------------------------------------------

;#读1位时序
;------------------------------------------------------------------------
READ_BIT:
	CLR P3.7		  ;拉低总线
	NOP				  ;延时2us
	NOP
	SETB P3.7		  ;释放总线
	NOP
	NOP
	MOV C,P3.7		  ;读取总线数据,存放在C中
	MOV B,#6
	LCALL DELAY

	RET
;------------------------------------------------------------------------

;#读取1字节信息
;------------------------------------------------------------------------
READ_BYTE:
	LCALL READ_BIT
	RRC A 
	LCALL READ_BIT
	RRC A 
	LCALL READ_BIT
	RRC A 
	LCALL READ_BIT
	RRC A 
	LCALL READ_BIT
	RRC A 
	LCALL READ_BIT
	RRC A 
	LCALL READ_BIT
	RRC A 
	LCALL READ_BIT
	RRC A 

	RET
;------------------------------------------------------------------------

;#Read Rom命令:33H(0011 0011B)
;------------------------------------------------------------------------
READ_ROM:
	LCALL WRITE1
	LCALL WRITE1
	LCALL WRITE0
	LCALL WRITE0
	LCALL WRITE1
	LCALL WRITE1
	LCALL WRITE0
	LCALL WRITE0

	RET
;------------------------------------------------------------------------

;#Skip Rom命令:CCH(1100 1100B)
;------------------------------------------------------------------------
SKIP_ROM:
	LCALL WRITE0
	LCALL WRITE0
	LCALL WRITE1
	LCALL WRITE1
	LCALL WRITE0
	LCALL WRITE0
	LCALL WRITE1
	LCALL WRITE1
	RET
;------------------------------------------------------------------------

;#Read SCratchpad命令:BEH(1011 1110B)
;------------------------------------------------------------------------
READ_PAD:
	LCALL WRITE0
	LCALL WRITE1
	LCALL WRITE1
	LCALL WRITE1
	LCALL WRITE1
	LCALL WRITE1
	LCALL WRITE0
	LCALL WRITE1
	RET
;------------------------------------------------------------------------

;#CONVERT命令:44H(0100 0100B)
;------------------------------------------------------------------------
CONVERT_T:
	LCALL WRITE0
	LCALL WRITE0
	LCALL WRITE1
	LCALL WRITE0
	LCALL WRITE0
	LCALL WRITE0
	LCALL WRITE1
	LCALL WRITE0
	RET
;------------------------------------------------------------------------	

;延时函数X10us
;------------------------------------------------------------------------
DELAY:
	MOV R1,B
LP:
	MOV R0,#10
LP1:
	DJNZ R0,LP1
	DJNZ R1,LP

	RET
;------------------------------------------------------------------------

;延时函数750ms
;------------------------------------------------------------------------
DELAY_750ms:
	MOV R0,#75
DLOOP2:
	MOV TH0,#0D8H	  ;计时10ms
	MOV TL0,#0F0H
	SETB TR0		  ;使能T0
DLOOP3:
	JB F0,DLOOP3	  ;F0为1则一直循环
	SETB F0 
	DJNZ R0,DLOOP2

	RET
;------------------------------------------------------------------------		

;#T0中断处理函数,主要功能清除中断标志、停止计数、
;------------------------------------------------------------------------
INT_T0:	
	CLR TR0           ;停止定时/计数器T0的计数
	CLR TF0           ;清除定时/计数器T0的溢出标志
	CLR F0
	RETI
;------------------------------------------------------------------------
			
END

原理图:
在这里插入图片描述

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐