这是关于DS18B20的读写程序,数据脚P3.4,晶振12MHZ ;温度传感器18B20汇编程序,采用器件默认的12位转化,最大转化时间750微秒 ;可以将检测到的温度直接显示到连接到AT89C2051的两个数码管上 ;显示温度00到99度,很准确哦~~无需校正!
ORG 0000H
;单片机内存分配申明! TEMPER_L EQU 29H ;用于保存读出温度的低8位 TEMPER_H EQU 28H ;用于保存读出温度的高8位 FLAG1 EQU 38H ;是否检测到DS18B20标志位 A_BIT EQU 20H ;数码管个位数存放内存位置 B_BIT EQU 21H ;数码管十位数存放内存位置
MAIN: LCALL GET_TEMPER ;调用读温度子程序
;显示范围00到99度,显示精度为1度 ;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位 ;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度 ;这个转化温度的方法非常简洁,无需乘于0.0625系数
MOV A,29H MOV C,40 ;将28H中的最低位移入C RRC A MOV C,41H RRC A MOV C,42H RRC A MOV C,43H RRC A MOV 29H,A
LCALL DISPLAY ;调用数码管显示子程序
AJMP MAIN
;这是DS18B20复位初始化子程序 INIT_1820: SETB P3.4 NOP CLR P3.4 ;主机发出延时537微秒的复位低脉冲 MOV R1,#3 TSR1: MOV R0,#107 DJNZ R0,$ DJNZ R1,TSR1 SETB P3.4 ;然后拉高数据线 NOP NOP NOP MOV R0,#25H TSR2: JNB P3.4,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 P3.4 RET
;读出转换后的温度值
GET_TEMPER: SETB P3.4 LCALL INIT_1820 ;先复位DS18B20 JB FLAG1,TSS2 RET ;判断DS1820是否存在?若DS18B20不存在则返回 TSS2: MOV A,#0CCH ;跳过ROM匹配 LCALL WRITE_1820 MOV A,#44H ;发出温度转换命令 LCALL WRITE_1820
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
LCALL DISPLAY
LCALL INIT_1820 ;准备读温度前先复位
MOV A,#0CCH ;跳过ROM匹配 LCALL WRITE_1820
MOV A,#0BEH ;发出读温度命令 LCALL WRITE_1820
LCALL READ_18200 ;将读出的温度数据保存到35H/36H
RET
;写DS18B20的子程序(有具体的时序要求) WRITE_1820: MOV R2,#8 ;一共8位数据 CLR C WR1: CLR P3.4 MOV R3,#6 DJNZ R3,$ RRC A MOV P3.4,C MOV R3,#23 DJNZ R3,$ SETB P3.4 NOP DJNZ R2,WR1 SETB P3.4 RET
;读DS18B20的程序,从DS18B20中读出两个字节的温度数据 READ_18200: MOV R4,#2 ;将温度高位和低位从DS18B20中读出 MOV R1,#29H ;低位存入29H(TEMPER_L),高位存入28H(TEMPER_H) RE00: MOV R2,#8 ;数据一共有8位 RE01: CLR C SETB P3.4 NOP NOP CLR P3.4 NOP NOP NOP SETB P3.4
MOV R3,#9 RE10: DJNZ R3,RE10
MOV C,P3.4
MOV R3,#23 RE20: DJNZ R3,RE20
RRC A DJNZ R2,RE01 MOV @R1,A DEC R1 DJNZ R4,RE00 RET
;显示子程序
DISPLAY: MOV A,29H ;将29H中的十六进制数转换成10进制 MOV B,#10 ;10进制/10=10进制 DIV AB MOV B_BIT,A ;十位在a MOV A_BIT,B ;个位在b MOV DPTR,#NUMTAB ;指定查表启始地址 MOV R0,#4 DPL1: MOV R1,#250 ;显示1000次 DPLOP: MOV A,A_BIT ;取个位数 MOVC A,@A+DPTR ;查个位数的7段代码 MOV P1,A ;送出个位的7段代码 CLR P3.7 ;开个位显示 ACALL D1MS ;显示1ms SETB P3.7 MOV A,B_BIT ;取十位数 MOVC A,@A+DPTR ;查十位数的7段代码 MOV P1,A ;送出十位的7段代码 CLR P3.5 ;开十位显示 ACALL D1MS ;显示1ms SETB P3.5 DJNZ R1,DPLOP ;250次没完循环 DJNZ R0,DPL1 ;4个250次没完循环 RET
;1MS延时(按12MHZ算)
D1MS: MOV R7,#80 DJNZ R7,$ RET
;7段数码管0~9数字的共阳显示代码
NUMTAB: DB 081H,0CFH,092H,086H,0CCH,0A4H,0A0H,08FH,080H,084H
END 这是关于DS18B20的读写程序,数据脚P3.4,晶振12MHZ ;温度传感器18B20汇编程序,采用器件默认的12位转化,最大转化时间750微秒 ;可以将检测到的温度直接显示到连接到AT89C2051的两个数码管上 ;显示温度00到99度,很准确哦~~无需校正!
ORG 0000H
;单片机内存分配申明! TEMPER_L EQU 29H ;用于保存读出温度的低8位 TEMPER_H EQU 28H ;用于保存读出温度的高8位 FLAG1 EQU 38H ;是否检测到DS18B20标志位 A_BIT EQU 20H ;数码管个位数存放内存位置 B_BIT EQU 21H ;数码管十位数存放内存位置
MAIN: LCALL GET_TEMPER ;调用读温度子程序
;显示范围00到99度,显示精度为1度 ;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位 ;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度 ;这个转化温度的方法非常简洁,无需乘于0.0625系数
MOV A,29H MOV C,40 ;将28H中的最低位移入C RRC A MOV C,41H RRC A MOV C,42H RRC A MOV C,43H RRC A MOV 29H,A
LCALL DISPLAY ;调用数码管显示子程序
AJMP MAIN
;这是DS18B20复位初始化子程序 INIT_1820: SETB P3.4 NOP CLR P3.4 ;主机发出延时537微秒的复位低脉冲 MOV R1,#3 TSR1: MOV R0,#107 DJNZ R0,$ DJNZ R1,TSR1 SETB P3.4 ;然后拉高数据线 NOP NOP NOP MOV R0,#25H TSR2: JNB P3.4,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 P3.4 RET
;读出转换后的温度值
GET_TEMPER: SETB P3.4 LCALL INIT_1820 ;先复位DS18B20 JB FLAG1,TSS2 RET ;判断DS1820是否存在?若DS18B20不存在则返回 TSS2: MOV A,#0CCH ;跳过ROM匹配 LCALL WRITE_1820 MOV A,#44H ;发出温度转换命令 LCALL WRITE_1820
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
LCALL DISPLAY
LCALL INIT_1820 ;准备读温度前先复位
MOV A,#0CCH ;跳过ROM匹配 LCALL WRITE_1820
MOV A,#0BEH ;发出读温度命令 LCALL WRITE_1820
LCALL READ_18200 ;将读出的温度数据保存到35H/36H
RET
;写DS18B20的子程序(有具体的时序要求) WRITE_1820: MOV R2,#8 ;一共8位数据 CLR C WR1: CLR P3.4 MOV R3,#6 DJNZ R3,$ RRC A MOV P3.4,C MOV R3,#23 DJNZ R3,$ SETB P3.4 NOP DJNZ R2,WR1 SETB P3.4 RET
;读DS18B20的程序,从DS18B20中读出两个字节的温度数据 READ_18200: MOV R4,#2 ;将温度高位和低位从DS18B20中读出 MOV R1,#29H ;低位存入29H(TEMPER_L),高位存入28H(TEMPER_H) RE00: MOV R2,#8 ;数据一共有8位 RE01: CLR C SETB P3.4 NOP NOP CLR P3.4 NOP NOP NOP SETB P3.4
MOV R3,#9 RE10: DJNZ R3,RE10
MOV C,P3.4
MOV R3,#23 RE20: DJNZ R3,RE20
RRC A DJNZ R2,RE01 MOV @R1,A DEC R1 DJNZ R4,RE00 RET
;显示子程序
DISPLAY: MOV A,29H ;将29H中的十六进制数转换成10进制 MOV B,#10 ;10进制/10=10进制 DIV AB MOV B_BIT,A ;十位在a MOV A_BIT,B ;个位在b MOV DPTR,#NUMTAB ;指定查表启始地址 MOV R0,#4 DPL1: MOV R1,#250 ;显示1000次 DPLOP: MOV A,A_BIT ;取个位数 MOVC A,@A+DPTR ;查个位数的7段代码 MOV P1,A ;送出个位的7段代码 CLR P3.7 ;开个位显示 ACALL D1MS ;显示1ms SETB P3.7 MOV A,B_BIT ;取十位数 MOVC A,@A+DPTR ;查十位数的7段代码 MOV P1,A ;送出十位的7段代码 CLR P3.5 ;开十位显示 ACALL D1MS ;显示1ms SETB P3.5 DJNZ R1,DPLOP ;250次没完循环 DJNZ R0,DPL1 ;4个250次没完循环 RET
;1MS延时(按12MHZ算)
D1MS: MOV R7,#80 DJNZ R7,$ RET
;7段数码管0~9数字的共阳显示代码
NUMTAB: DB 081H,0CFH,092H,086H,0CCH,0A4H,0A0H,08FH,080H,084H
END 这是关于DS18B20的读写程序,数据脚P3.4,晶振12MHZ ;温度传感器18B20汇编程序,采用器件默认的12位转化,最大转化时间750微秒 ;可以将检测到的温度直接显示到连接到AT89C2051的两个数码管上 ;显示温度00到99度,很准确哦~~无需校正!
ORG 0000H
;单片机内存分配申明! TEMPER_L EQU 29H ;用于保存读出温度的低8位 TEMPER_H EQU 28H ;用于保存读出温度的高8位 FLAG1 EQU 38H ;是否检测到DS18B20标志位 A_BIT EQU 20H ;数码管个位数存放内存位置 B_BIT EQU 21H ;数码管十位数存放内存位置
MAIN: LCALL GET_TEMPER ;调用读温度子程序
;显示范围00到99度,显示精度为1度 ;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位 ;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度 ;这个转化温度的方法非常简洁,无需乘于0.0625系数
MOV A,29H MOV C,40 ;将28H中的最低位移入C RRC A MOV C,41H RRC A MOV C,42H RRC A MOV C,43H RRC A MOV 29H,A
LCALL DISPLAY ;调用数码管显示子程序
AJMP MAIN
;这是DS18B20复位初始化子程序 INIT_1820: SETB P3.4 NOP CLR P3.4 ;主机发出延时537微秒的复位低脉冲 MOV R1,#3 TSR1: MOV R0,#107 DJNZ R0,$ DJNZ R1,TSR1 SETB P3.4 ;然后拉高数据线 NOP NOP NOP MOV R0,#25H TSR2: JNB P3.4,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 P3.4 RET
;读出转换后的温度值
GET_TEMPER: SETB P3.4 LCALL INIT_1820 ;先复位DS18B20 JB FLAG1,TSS2 RET ;判断DS1820是否存在?若DS18B20不存在则返回 TSS2: MOV A,#0CCH ;跳过ROM匹配 LCALL WRITE_1820 MOV A,#44H ;发出温度转换命令 LCALL WRITE_1820
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
LCALL DISPLAY
LCALL INIT_1820 ;准备读温度前先复位
MOV A,#0CCH ;跳过ROM匹配 LCALL WRITE_1820
MOV A,#0BEH ;发出读温度命令 LCALL WRITE_1820
LCALL READ_18200 ;将读出的温度数据保存到35H/36H
RET
;写DS18B20的子程序(有具体的时序要求) WRITE_1820: MOV R2,#8 ;一共8位数据 CLR C WR1: CLR P3.4 MOV R3,#6 DJNZ R3,$ RRC A MOV P3.4,C MOV R3,#23 DJNZ R3,$ SETB P3.4 NOP DJNZ R2,WR1 SETB P3.4 RET
;读DS18B20的程序,从DS18B20中读出两个字节的温度数据 READ_18200: MOV R4,#2 ;将温度高位和低位从DS18B20中读出 MOV R1,#29H ;低位存入29H(TEMPER_L),高位存入28H(TEMPER_H) RE00: MOV R2,#8 ;数据一共有8位 RE01: CLR C SETB P3.4 NOP NOP CLR P3.4 NOP NOP NOP SETB P3.4
MOV R3,#9 RE10: DJNZ R3,RE10
MOV C,P3.4
MOV R3,#23 RE20: DJNZ R3,RE20
RRC A DJNZ R2,RE01 MOV @R1,A DEC R1 DJNZ R4,RE00 RET
;显示子程序
DISPLAY: MOV A,29H ;将29H中的十六进制数转换成10进制 MOV B,#10 ;10进制/10=10进制 DIV AB MOV B_BIT,A ;十位在a MOV A_BIT,B ;个位在b MOV DPTR,#NUMTAB ;指定查表启始地址 MOV R0,#4 DPL1: MOV R1,#250 ;显示1000次 DPLOP: MOV A,A_BIT ;取个位数 MOVC A,@A+DPTR ;查个位数的7段代码 MOV P1,A ;送出个位的7段代码 CLR P3.7 ;开个位显示 ACALL D1MS ;显示1ms SETB P3.7 MOV A,B_BIT ;取十位数 MOVC A,@A+DPTR ;查十位数的7段代码 MOV P1,A ;送出十位的7段代码 CLR P3.5 ;开十位显示 ACALL D1MS ;显示1ms SETB P3.5 DJNZ R1,DPLOP ;250次没完循环 DJNZ R0,DPL1 ;4个250次没完循环 RET
;1MS延时(按12MHZ算)
D1MS: MOV R7,#80 DJNZ R7,$ RET
;7段数码管0~9数字的共阳显示代码
NUMTAB: DB 081H,0CFH,092H,086H,0CCH,0A4H,0A0H,08FH,080H,084H
END
|