📄 temper.asm
字号:
ORG 0000H
DOT EQU 30H ;小数部?
ZHENGSHU EQU 31H ;整数部分
FLAG1 EQU 38H ;表示是否检测到18B20的标志位
DIS_1 EQU 32H ;温度符号位显示
DIS_2 EQU 33H ;温度百位显示
DIS_3 EQU 34H ;温度十位数显?
DIS_4 EQU 35H ;温度个位数显?
WDDATA BIT P3.0 ;数据总线
MAIN: LCALL INIT_1820 ;调用18B20复位初始化子程序
MAIN1: LCALL GET_TEMPER ;调用读温度子程序
LCALL FORMULA ;公式计算,显示小数点后两位
LCALL DISPLAY ;显示测试出的温度
AJMP MAIN1
;复位初始化子程序
INIT_1820:
SETB WDDATA ;按照时序拉高P3.0
NOP ;延时一个机器周期1微秒
CLR WDDATA ;拉低数据线
MOV R0,#36
LCALL DELAY ;调用延时子程序,发出一个540微秒的低脉冲
SETB WDDATA ;再次拉高数据线
NOP
NOP
MOV R0,#36
TZ2: JNB WDDATA,TZ3 ;运行36次跳转指令,等待72微秒,其间收到低脉冲,证明18B20存在,否则不存在
DJNZ R0,TZ2
LJMP TZ4
TZ3: SETB FLAG1 ;收到低脉冲,标志位置高,证明18B20存在
LJMP TZ5
TZ4: CLR FLAG1 ;没有低脉冲反馈,证明18B20没有连接上,标志位置低
LJMP TZ7 ;TZ7将P3.0拉高
TZ5: MOV R0,#06EH ;复位成功,按照时序延时240微秒
TZ6: DJNZ R0,TZ6
TZ7: SETB WDDATA
RET
;读出转化后温度值的子程序
GET_TEMPER: SETB WDDATA ;定时入口
LCALL INIT_1820 ;运行前先复位
JB FLAG1,ZH2 ;如果检测到18B20存在,跳到ZH2
RET ;没有18B20,跳出
ZH2: MOV A,#0CCH ;调用SKIP ROM命令
LCALL WRITE_1820
MOV A,#044H ;调用CONVERT命令,一定要先执行ROM命令再执行RAM命令
LCALL WRITE_1820 ;调用写温度子程序
MOV R0,#50 ;根据时序要求延时750微秒等待A/D转换结束
LCALL DELAY
LCALL INIT_1820 ;在读温度值前先复位
MOV A,#0CCH
LCALL WRITE_1820 ;每下一个命令都要调用写程序写入
MOV A,#0BEH
LCALL WRITE_1820
LCALL READ_1820
RET
;写温度子程序
WRITE_1820: MOV R2,#8 ;一个字节共8位
CLR C ;清空进位位
WR1: CLR WDDATA ;拉低总线
MOV R3,#8
DJNZ R3,$ ;18B20开始工作,对数据进行采样,等待1
RRC A ;
MOV WDDATA,C ;命令字按位依次送给18B20
MOV R3,#32
WR2: DJNZ R3,WR2 ;保证写过程持续在60微秒?
SETB WDDATA
NOP
DJNZ R2,WR1 ;未写完一个字节的话继续进行
SETB WDDATA
RET
;读温度子程序,可以读出9个8位数据,分别存入以60H开始的9个地址内
READ_1820: MOV R4,#9 ;写9个数据
MOV R1,#60H ;温度值低位在60H,高位在61H
RE0: MOV R2,#8 ;数据共有8位
RE1: CLR C
SETB WDDATA
NOP
NOP ;
CLR WDDATA
NOP
NOP
NOP ;保持低电平2微秒
SETB WDDATA ;
MOV R3,#09
RE2: DJNZ R3,RE2 ;等待9微秒,让字节传来
MOV C,WDDATA ;主机按位依次读入18B20数据
MOV R3,#24
RE3: DJNZ R3,RE3
RRC A ;读取数据移入A
DJNZ R2,RE1
MOV @R1,A ;从60H开始存
INC R1 ;地址加1
DJNZ R4,RE0 ;循环
SETB WDDATA
RET
;温度计算子程序
;整数部分则把61H低四位变为60H高四位,60H原来的高四位变做低四位。如果温度为负则取反即可
FORMULA: MOV A,60H
ANL A,#0F0H ;取60H高四位
swap a
MOV R5,A
MOV A,61H
ANL A,#0FH ;取61H低四位
swap a
ORL A,R5 ;或得到一个新字节
MOV ZHENGSHU,A ;存入整数部分地?
MOV A,61H
ANL A,#80H ;取温度高位上最高位,因为61H前5位如果是1,温度为负,?
jnb acc.7,ZHENG ;如果是0,温度为正,跳转
MOV A,ZHENGSHU ;如果是1,温度为负
CPL A ;温度值取反
INC A
MOV DIS_1,#40H ;给符号位赋值"-"
MOV ZHENGSHU,A
RET
ZHENG:MOV DIS_1,#00H ;给符号位赋值"0"
RET
DISPLAY: MOV A,ZHENGSHU ;把整数值赋给A
MOV B,#10 ;十进制/十进制
DIV AB
MOV DIS_4,b;DIS_3是个位数
MOV B,#10
DIV AB
MOV DIS_3,B
MOV DIS_2,A
MOV DPTR,#NUMTAB
MOV R0,#4
DP1: MOV R1,#140 ;循环显示1000次
DPLOP: MOV A,DIS_4 ;取个位
MOVC A,@A+DPTR ;
MOV P0,A
clr p2.0
ACALL DELAY100
setb p2.0
MOV A,DIS_3 ;取十位
MOVC A,@A+DPTR ;选址
MOV P0,A
clr p2.1
ACALL DELAY100
setb p2.1
MOV A,DIS_2 ;取十位
MOVC A,@A+DPTR ;选址
MOV P0,A
clr p2.2
ACALL DELAY100
setb p2.2
MOV A,DIS_1 ;取符号位
MOV P0,A ;送给P0腖E
clr p2.3
ACALL DELAY100 ;持续1毫秒
setb p2.3
DJNZ R1,DPLOP
DJNZ R0,DP1
RET
;1毫秒延时
DELAY100: MOV R7,#180
DJNZ R7,$
RET
;15微秒延时
DELAY:
LOOP:MOV R1,#06H
LOOP1:DJNZ R1,LOOP1
DJNZ R0,LOOP
RET
;540毫秒延时
DELAY500: MOV R4,#248
DA1: MOV R5,#248
DA2: DJNZ R5,DA2
DJNZ R4,DA1
RET
;共阴极代码
NUMTAB: DB 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -