📄 test.asm
字号:
TEMP EQU 40H ;缓存1820读出的数据
TEML EQU 44H ;1820读出温度的低8位原始数据
TEMH EQU 45H ;1820读出温度的高8位原始数据
TEMPSJ EQU 46H ;实际温度地址
SETTH EQU 33H ;设定温度报警高位
SETTL EQU 34H ;设定温度报警低位
REST_N EQU 42H ;1820复位标志位
ORG 0000H
LJMP MAIN ;主程序首地址为0000H
ORG 0030H ;程序从0030H开始执行
MAIN:
MOV SETTH,#1CH ;设定温度报警的高位是28摄氏度
MOV SETTL,#16H ;设定温度报警的低位是22摄氏度
LCALL GET_TEMP ;调用读温度子程序
CLR C ;清状态位
MOV A, TEMP ;将35H地址单元的温度值放到A中
CJNE A,34H,LOOP1
SJMP SS
LOOP1: JC SS
MOV A,TEMP
CLR C
CJNE A,33H,LOOP2
SJMP FMQ
LOOP2: JNC FMQ
SJMP KEEP
SS: SETB P1.1
LCALL DELAY
CLR P1.1
LCALL DELAY
LJMP SS
DELAY: MOV R7,#250
D1: MOV R6,#250
D2: DJNZ R6,D2
DJNZ R7,D1
KEEP: SJMP MAIN
FMQ: SETB P1.2
LCALL DELAY
CLR P1.2
LCALL DELAY
LJMP FMQ
DELAY2: MOV R2,#250
D3: MOV R1,#250
D4: DJNZ R1,D4
DJNZ R2,D3
GET_TEMP: ;温度读取程序
LCALL INI ;调用初始化程序
JNB REST_N,INIBEG
SJMP GET_TEMP
INIBEG:
MOV A ,#0CCH ;发跳过ROM命令
LCALL WRITE ;写命令字
MOV A,#44 ;发开始温度转换命令
LCALL WRITE ;写命令字,启动18B20进行转换
NOP
TEL2: CLR P1.0
NOP
SETB P1.0
MOV R4,#6
TEL3: DJNZ R4,TEL3
MOV C,P1.0
MOV R5,#30
TEL4: DJNZ R5,TEL4 ;判断转换是否结束
JC TEL2
TEL5: LCALL INI ;再调用初始化程序
MOV A,#0CCH ;发跳过ROM命令
LCALL WRITE ;写命令字
MOV A,#0BEH ;发读存储器命令
LCALL WRITE ;写命令字
LCALL READ ;读出18B20的温度值低位
MOV TEML,A ;将18B20的温度值低位放到 44H中
LCALL READ ;读出18B20的温度值高位
MOV TEMH,A ;将18B20的温度值低位放到 45H中
TEL6: LCALL INI
JB REST_N,TEL6
;****************************************************************************
;通过移位合并两个字节中的温度值为一个字节的温度值
;****************************************************************************
MOV A,TEMH
CLR C
RLC A
ljmp tt4 ;温度是正值
tt4: RLC A
RLC A
RLC A
RLC A
MOV TEMH,A
MOV A,TEML
CLR C
RRC A
CLR C
RRC A
CLR C
RRC A
MOV TEML,A
MOV A,TEMH
ORL A,TEML
MOV TEMPSJ,A
RET
;DS18B20的初始化子程序
INI: CLR REST_N ;初始化子程序程序名
L0: CLR P1.0 ;使P1.0输出低电平
MOV R2,#200 ;将立即数200放在寄存器R2中
L1: CLR P1.0 ;使P1.0输出低电平
DJNZ R2,L1 ;主机发置位脉冲,持续时间在600微秒左右
SETB P1.0 ;主机释放总线,P1.0口改为输入口
MOV R2,#32 ;将立即数32放在寄存器R2中
L4: DJNZ R2,L4 ;DS18B20等待64微秒
CLR C ;将命令字清零
JB P1.0,L0 ;DS18B20数据线应变低,如果没有变低,说明还没有准备好,需重来,即再从L0开始重新执行
MOV R6,#80 ;将立即数80放在寄存器R6中
L5: JB P1.0,L3 ;DS18B20数据线变高,收到响应脉冲,初始化成功
DJNZ R6,L5 ;DS18B20数据线低电平状态可持续240微秒
SJMP L0 ;初始化失败,重来
L3: MOV R2,#240 ;将立即数240放在寄存器R2中
L2: DJNZ R2,L2 ;DS18B20应答过程最少480微秒
RET
;DS18B20的写子程序
WRITE: MOV R3,#8 ;将立即数 8放在寄存器R3中
WR1: SETB P1.0 ;将P1.0口设成高位,即主机释放总线,P1.0口改为输入口
MOV R4,#8 ;将立即数 8放在寄存器R4中
RRC A ;写入位从A中移到CY
CLR P1.0 ;将P1.0口设成低位
WR2: DJNZ R4,WR2 ;DS18B20在数据线变低16微秒后开始采样数据
MOV P1.0,C ;将命令字按位依次送给DS18B20
MOV R4,#30 ;将立即数30放在寄存器R4中
WR3: DJNZ R4,WR3 ;保证整个写过程持续60微秒
DJNZ R3,WR1 ;是否送完整个命令字
SETB P1.0 ;将P1.0口设成高位,即主机释放总线,P1.0口改为输入口
RET
;DS18B20的读子程序
READ: MOV R6,#8 ;将立即数8放在寄存器R6中
RE1: CLR P1.0 ;将总线设成低位
MOV R4,#4 ;将立即数4放在寄存器R4中
NOP ;空指令,即低电平持续2微秒
SETB P1.0 ;将P1.0口设成高位,即主机释放总线,P1.0口改为输入口
RE2: DJNZ R4,RE2 ;等待大约8微秒
MOV C,P1.0 ;主机按位读入DS18B20的数据
RRC A ;数据送入A
MOV R5,#30 ;将立即数30放在寄存器R5中
RE3: DJNZ R5,RE3 ;保证读数据过程持续60微秒
DJNZ R6,RE1 ;读完一个字节的数据,存入A中
MOV TEMP,A
SETB P1.0 ;将P1.0口设成高位,即主机释放总线,P1.0口改为输入口
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -