📄 ds18a.asm
字号:
ORG 0100H
;单片机内存分配申明!
TEMPER_L DATA 51H;用于保存读出温度的低8位
TEMPER_H DATA 50H;用于保存读出温度的高8位
FLAG1 bit 38H;是否检测到DS18B20标志位
dq bit p3.7
MAIN:
LCALL GET_TEMPER;调用读温度子程序
LCALL DISPLAY;调用数码管显示子程序
lJMP MAIN
; ==========这是DS18B20复位初始化子程序====================
INIT_1820:
MOV P1,#0ffh
SETB dq
NOP
NOP
CLR dq
;主机发出延时537微秒的复位低脉冲
MOV R1,#3
TSR1:MOV R0,#90
DJNZ R0,$
DJNZ R1,TSR1
SETB dq;然后拉高数据线
MOV R0,#25H
TSR2:
JNB dq,TSR3;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ; 延时
TSR3:
SETB FLAG1 ; 置标志位,表示DS1820存在
;CLR P1.0;检查到DS18B20就蜂鳴器響起
LJMP TSR5
TSR4:
CLR FLAG1 ; 清标志位,表示DS1820不存在
;CLR P1.3;点亮P1。3脚LED表示温度传感器通信失败
LJMP TSR7
TSR5:
MOV R0,#117
TSR6:
DJNZ R0,TSR6 ; 时序要求延时一段时间
TSR7:
SETB dq
RET
;-----------------------------------------------------
; ===================读出转换后的温度值===============
GET_TEMPER:
SETB dq
LCALL INIT_1820;先复位DS18B20
JB FLAG1,TSS2
CLR P1.3;ds1820不存在则蜂鸣器响起
RET ; 判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
;------------------------DS18B20已经被检测到!!!!!!!!!!!!!!!!!!
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV R6,#34H
DJNZ R6,$
MOV A,#44H ; 发出温度转换命令
LCALL WRITE_1820
MOV R6,#34H
DJNZ R6,$
;-----------------------------------------
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
LCALL display
LCALL INIT_1820;准备读温度前先复位
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV R6,#34H
DJNZ R6,$
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
MOV R6,#34H
DJNZ R6,$
;lcall read_1820
LCALL READ_18200; 将读出的温度数据保存到50H/51H
RET
;=====================读温度================
;------------------读DS18B20的程序,从DS18B20中读出一个字节的数据
/*READ_1820:
MOV R2,#8
RE1:
CLR C
SETB DQ
NOP
NOP
CLR DQ
NOP
NOP
NOP
SETB DQ
MOV R3,#7
DJNZ R3,$
MOV C,DQ
MOV R3,#23
DJNZ R3,$
RRC A
DJNZ R2,RE1
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
;MOV P1,50H;蜂鸣器响起
RET
; ===================读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_18200:
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#51H ; 低位存入51H(TEMPER_L),高位存入50H(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
DEC R1
DJNZ R4,RE00
RET
;=======================显示子程序==================================
display:
mov 40h,50h
mov 41h,51h
mov 29h,41h
MOV R5,#50H
mov p2,#00
;===处理数据=================
mov a,40h
rlc a
jc fushu;是负数跳到负数执行显示
mov a,40h
swap a
anl a,#0f0h
mov 40h,a
mov a,41h
swap a
anl a,#0fh
mov 41h,a
mov a,40h
orl a,41h
mov 43h,a
mov a,29h
anl a,#0fh
mov 44h,a
loop:
mov a,43h
mov b,#100
div ab
mov 30h,a
mov 31h,b
mov a,31h
mov b,#10
div ab
mov 31h,a
mov 32h,b
mov a,44h;小数点
mov b,#5
mul ab
mov b,#8
div ab
mov 33h,a
mov a,30h
jz no
mov dptr,#tab
movc a,@a+dptr
setb p2.3
mov p0,a
lcall delay
clr p2.3
no:
mov a,31h
mov dptr,#tab
movc a,@a+dptr
setb p2.2
mov p0,a
lcall delay
clr p2.2
mov a,32h
mov dptr,#tab1
movc a,@a+dptr
setb p2.1
mov p0,a
lcall delay
clr p2.1
mov a,33h
mov dptr,#tab
movc a,@a+dptr
setb p2.0
mov p0,a
lcall delay
clr p2.0
DJNZ R5,LOOP
ret
;================负数===============
fushu:
mov a,40h
swap a
anl a,#0f0h
mov 40h,a
mov a,41h
swap a
anl a,#0fh
mov 41h,a
mov a,40h
orl a,41h
cpl a
mov 43h,a
mov a,29h
anl a,#0fh
mov 44h,a
loop1:
mov a,43h
mov b,#10
div ab
mov 30h,a
mov 31h,b
;=====负数符号“-”
setb p2.3
mov p0,#40h
lcall delay
clr p2.3
;==========十位=========
mov a,30h
mov dptr,#tab
movc a,@a+dptr
setb p2.2
mov p0,a
lcall delay
clr p2.2
;个位
mov a,31h
mov dptr,#tab1
movc a,@a+dptr
setb p2.1
mov p0,a
lcall delay
clr p2.1
mov a,44h;小数点
dec a
mov b,#5
mul ab
mov b,#8
div ab
mov 33h,a
mov a,#10
subb a,33h
mov dptr,#tab
movc a,@a+dptr
setb p2.0
mov p0,a
lcall delay
clr p2.0
ljmp loop1
ret
delay:
MOV R7,#010H;延时子程序 200us
DEL1:MOV R6,#50;
DJNZ R6,$;
DJNZ R7,del1;
ret
tab:db 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
tab1:db 0bFH,86H,0dBH,0cFH,0e6H,0eDH,0fDH,087H,0fFH,0eFH
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -