标题:
基于18B20温度检测程序精确0.25度
[打印本页]
作者:
daniu
时间:
2014-12-27 16:22
标题:
基于18B20温度检测程序精确0.25度
;=================================================================================
;Filename:DS18B20.asm ;
;Program function: temperature testing ;
; version: v1.0 ;
; date: 2009-9-03 11;49 ;
; Author: 兰建文 ;
; Company: YUANDIAN ;
;=================================================================================
;MCU type:AT89S52 ;
;FOSC: ERC,HF,XT,LF,TMR0 Mode ;
;WDTEN: DISABLE ;
;PROTECT:YES ;
;LVDTEN:ENABLE LVD=1.8V ;
;OSCD: 12 oscillator periods ;
;PMCD: No_Power saving ;
;SET freq:12MHz ;
;Fosc=XT 1MHz(2T)=0.50us ;
;Time:T=(65536-M)*Pre*Tm/Osc ;
;Tm:Oscillater periods=12,Pre(TCC=1:x) ;
;PAPH: Disable ;
;PBPH: Enable ;
;VDD: extv=5V ;
;CHECKSUM: CONFIG: ,CONFIG1: ;
;ROM size: RAM size: ;
;=================================================================================
; Register Definitions
;-----------Define system register---------------------------
;=================================================================================
;单片机内存分配申明!
;=================================================================================
TEMPER_L EQU 29H;用于保存读出温度的低8位
TEMPER_H EQU 28H;用于保存读出温度的高8位
FLAG1 EQU 22H.0H;是否检测到DS18B20标志位
a_bit EQU 20H;数码管个位数存放内存位置
b_bit EQU 21H;数码管十位数存放内存位置
c_bit EQU 23H;数码管小数点个分位
d_bit EQU 24H;数码管小数点十分位
ORG 0000H
JMP MAIN
ORG 0030H
MAIN:
LCALL GET_TEMPER;调用读温度子程序
;=================================================================================
;进行温度显示
;显示范围00到99度,显示精度为1度
;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位
;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度
;=================================================================================
MOV 27H,29H
MOV A,29H
MOV C,28H.0;将28H中的最低位移入C
RRC A
MOV C,28H.1
RRC A
MOV C,28H.2
RRC A
MOV C,28H.3
RRC A
MOV 29H,A
MOV A,27H
RR A
RR A
ANL A,#03H
CJNE A,#3,LAN1
MOV 27H,#75
AJMP XIANSHI
LAN1: CJNE A,#2,LAN2
MOV 27H,#50
AJMP XIANSHI
LAN2: CJNE A,#1,LAN3
MOV 27H,#25
AJMP XIANSHI
LAN3: CJNE A,#0,MAIN
MOV 27H,#00
XIANSHI:LCALL DISPLAY;调用数码管显示子程序
AJMP MAIN
;=================================================================================
; 这是DS18B20复位初始化子程序
;=================================================================================
INIT_1820:
SETB P3.5
NOP
CLR P3.5
;主机发出延时537微秒的复位低脉冲
MOV R1,#3
TSR1:
MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB P3.5;然后拉高数据线
NOP
NOP
NOP
MOV R0,#25H
TSR2:
JNB P3.5,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.5
RET
;=================================================================================
; 读出转换后的温度值
;=================================================================================
GET_TEMPER:
SETB P3.5
LCALL INIT_1820;先复位DS18B20
JNB FLAG1,OUT ; 判断DS1820是否存在?若DS18B20不存在则返回
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
OUT:
RET
;=================================================================================
;写DS18B20的子程序(有具体的时序要求)
;=================================================================================
WRITE_1820:
MOV R2,#8;一共8位数据
CLR C
WR1:
CLR P3.5
MOV R3,#6
DJNZ R3,$
RRC A
MOV P3.5,C
MOV R3,#23
DJNZ R3,$
SETB P3.5
NOP
DJNZ R2,WR1
SETB P3.5
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.5
NOP
NOP
CLR P3.5
NOP
NOP
NOP
SETB P3.5
MOV R3,#9
RE10:
DJNZ R3,RE10
MOV C,P3.5
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 A,27H
MOV B,#10
DIV AB
MOV c_bit,A
MOV d_bit,B
MOV R0,#4
Dpl1:
MOV R1,#250 ;显示1000次
DPLOP:
MOV DPTR,#TAB1 ;指定查表启始地址
MOV A,a_bit ;取个位数
MOVC A,@A+DPTR ;查个位数的7段代码
MOV P0,A ;送出个位的7段代码
CLR P2.2 ;开个位显示
ACALL D1MS ;显示1ms
SETB P2.2
MOV A,b_bit ;取十位数
MOV DPTR,#TAB
MOVC A,@A+DPTR ;查十位数的7段代码
MOV P0,A ;送出十位的7段代码
CLR P2.3 ;开十位显示
ACALL D1MS ;显示1ms
SETB P2.3
MOV DPTR,#TAB
MOV A,c_bit
MOVC A,@A+DPTR
MOV P0,A
CLR P2.1
ACALL D1MS
SETB P2.1
MOV A,d_bit
MOVC A,@A+DPTR
MOV P0,A
CLR P2.0
ACALL D1MS
SETB P2.0
DJNZ R1,DPLOP ;250次没完循环
DJNZ R0,Dpl1 ;4个250次没完循环
RET
;=================================================================================
;1MS延时(按12MHZ算)
;=================================================================================
D1MS:
MOV R7,#80
DJNZ R7,$
RET
;=================================================================================
;实验板上的7段数码管0~9数字的共阳显示代码
;=================================================================================
TAB:
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
TAB1:
DB 080H,079H,024H,030H,19H,12H,02H,078H,00H,10H
END
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1