📄 18-0 ds18b20.asm
字号:
;//**************浙江天煌科技实验有限公司**************
;//*文件名:DS18B20温度控制程序
;//*创建人:巫升辉
;//*2006.2.23
;//* 功能:进行温度显示,这里我们考虑用I2C 7279串行调用显示两位数码管来显示温度
;显示范围00到99度,显示精度为1度 温度控制在50度,超过温度时则风扇模拟降温,
;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位
;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度
;这个转化温度的方法非常简洁无需乘于0.0625系数
;//****************************************************
TEMPER_L EQU 20H ;用于保存读出温度的低8位
TEMPER_H EQU 21H ;用于保存读出温度的高8位
FLAG1 EQU 22H ;是否检测到DS18B20标志位
DATA_IN DATA 025H
DATA_OUT DATA 026H
TIMER DATA 030H
BIT_COUNT DATA 031H
DBUF DATA 032H
CLK BIT P1.6
DAT BIT P1.7
ORG 0000H
LJMP START
ORG 0100H
START:SETB P1.4
clr p1.5
MAIN: LCALL GET_TEMPER;调用读温度子程序
MOV A,29H
MOV C,40H ;将28H中的最低位移入C
RRC A
MOV C,41H
RRC A
MOV C,42H
RRC A
MOV C,43H
RRC A
MOV 29H,A
LCALL TOBCD
LCALL DISPLAY ;调用数码管显示子程序
LCALL DELAY
AJMP MAIN
INIT_1820: ; 这是DS18B20复位初始化子程序
SETB P1.0
NOP
CLR P1.0
MOV R1,#3 ;主机发出延时537微秒的复位低脉冲
TSR1:MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB P1.0 ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#25H
TSR2:JNB P1.0,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 P1.0
RET
GET_TEMPER: ; 读出转换后的温度值
SETB P1.0
LCALL INIT_1820 ;先复位DS18B20
JB FLAG1,TSS2
RET ; 判断DS1820是否存在?若DS18B20不存在则返回
TSS2:MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H ; 发出温度转换命令
LCALL WRITE_1820
LCALL DELAY1 ;这里通过调用显示子程序实现延时一段时间,等待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
WRITE_1820: ;写DS18B20的子程序(有具体的时序要求)
MOV R2,#8 ;一共8位数据
CLR C
WR1: CLR P1.0
MOV R3,#6
DJNZ R3,$
RRC A
MOV P1.0,C
MOV R3,#23
DJNZ R3,$
SETB P1.0
NOP
DJNZ R2,WR1
SETB P1.0
RET
READ_18200: ; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#29H ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:MOV R2,#8 ; 数据一共有8位
RE01:CLR C
SETB P1.0
NOP
NOP
CLR P1.0
NOP
NOP
NOP
SETB P1.0
MOV R3,#9
RE10:DJNZ R3,RE10
MOV C,P1.0
MOV R3,#23
RE20:DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
TOBCD:
MOV A,29H ;将29H中的十六进制数转换成10进制
MOV B, #10
DIV AB
MOV DBUF+1, A
MOV A, B
MOV DBUF,A
MOV A,DBUF+1
CJNE A,#5,$+3
JNC WW
SETB P1.4
CLR P1.5
RET
WW: CLR P1.4
SETB P1.5
DISPLAY:
ANL P2,#00H ; CS7279有效
MOV DATA_OUT,#10100100B ; A4H,复位命令
CALL SEND
MOV DATA_OUT,#10000000B ; 在第一个数码管上显示
CALL SEND
MOV DATA_OUT,DBUF
CALL SEND
MOV DATA_OUT,#10000001B ; 译码方式0,2位显示在第一个数码管上显示
CALL SEND
MOV DATA_OUT,DBUF+1
CALL SEND
RET
SEND: MOV BIT_COUNT,#8 ; 发送字符子程序
ANL P2,#00H
CALL LONG_DELAY
SEND_LOOP:MOV C,DATA_OUT.7
MOV DAT,C
SETB CLK
MOV A,DATA_OUT
RL A
MOV DATA_OUT,A
CALL SHORT_DELAY
CLR CLK
CALL SHORT_DELAY
DJNZ BIT_COUNT,SEND_LOOP
CLR DAT
RET
LONG_DELAY: MOV TIMER,#80 ;延时约200US
DELAY_LOOP: DJNZ TIMER,DELAY_LOOP
RET
SHORT_DELAY: MOV TIMER,#6 ;延时约20US
SHORT_LP: DJNZ TIMER,SHORT_LP
RET
DELAY: LCALL DELAY1
LCALL DELAY1
LCALL DELAY1
LCALL DELAY1
LCALL DELAY1
RET
DELAY1:MOV R1, #0
DLOOP: DJNZ R1, DLOOP
DJNZ R0, DELAY1
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -