DS18B20温度计 *
采用4位LED共阳显示器显示测温值,显示精度0.1℃,测温范围-55~+125*
用AT89C2051单片机,12MHZ晶振 *
********************************************************************
***************常数定义********************
TIMEL EQU0E0H 20ms,定时器0时间常数
TIMEH EQU0B1H
TEMPHEAD EQU36H
********************工作内存定义**********************
BITST DATA 20H
TIME1S0K BIT BITST.1
TEMPONEOK BIT BITST.2
TEMPL DATA 26H
TEMPH DATA 27H
TEMPHC DATA 28H
TEMPLC DATA 29H
SCANLEDDATA 2AH
*****************引脚定义*****************************
TEMPDIN BIT P3.7
*****************中断向量区***************************
ORG0000H
LJMP START
ORG000BH
LJMP T01T
***************系统初始化****************************
ORG0030H
START: MOV SP,#60H
CLSMEM: MOV R0,#20H
MOV R1,#60H
CLSMEM1: MOV @R0,#00H
INC R0
DJNZ R1,CLSMEM1
MOV TMOD,#00100001B 定时器0工作方式1(16位)
MOV TH0,#HIGH(65536-5000)
MOV TL0,#LOW(65536-5000)5ms
SJMPINIT
ERROR: NOP
LJMPSTART
NOP
INIT: NOP
SETB ET0
SETB TR0
SETB EA
MOV PSW,#00H
CLR TEMPONEOK
MOV 50H,#10
MOV 51H,#10
MOV 52H,#10
MOV 53H,#10
LJMP MAIN
*******************************************************************
定时器0中断服务程序
*******************************************************************
T01T: CLR TR0
MOV TH0,#HIGH(65536-5000)
MOV TL0,#LOW(65536-5000)5ms
SETB TR0
LEDDIS:
MOV DPTR,#TAB
MOV R1,#50H
MOV A,SCANLED
ADD A,R1
MOV R1,A
MOV A,SCANLED
JNZ LEDDIS1
MOV P3,#08H
SJMP LEDDIS4
LEDDIS1:
DEC A
JNZ LEDDIS2
MOV P3,#04H
SJMP LEDDIS4
LEDDIS2:
DEC A
JNZ LEDDIS3
MOV P3,#02H
SJMP LEDDIS4
LEDDIS3:
MOV P3,#01H
LEDDIS4:
MOV A,@R1
MOVC A,@A+DPTR
MOV P1,A
INC SCANLED
MOV A,SCANLED
CJNE A,#4,T0CNT
MOV SCANLED,#0
T0CNT:
INC R7
CJNER7,#200,T0IT1
MOV R7,#00H
SETB TIME1S0K1s定时到标志
T0IT1: RETI
********************************************************************
主程序
********************************************************************
MAIN:
JNB TIME1S0K,MAIN
CLR TIME1S0K测温每1s一次
LCALL READTEMP读出温度值子程序
LCALL CONVTEMP温度BCD码计算处理子程序
LCALL DISPBCD 显示区BCD码温度值刷新子程序
LJMPMAIN
********************************************************************
子程序区
********************************************************************
***************复位DS18B20*****************************************
INITDS1820: SETB TEMPDIN
NOP
CLRTEMPDIN
MOVR6,#251延时>480μs
DJNZ R6,$
SETB TEMPDIN
MOV R6,#37
LOOP1820: MOVC,TEMPDIN
JC INITDS1820OUT
DJNZ R6,LOOP1820
SJMP INITDS1820
RET
INITDS1820OUT:
MOVR6,#06BH 延时200μs
DJNZ R6,$
SETB TEMPDIN
RET
*******读DS18B20的程序,从DS18B20中读出1字节的数据*****
READDS1820: MOV R7,#08H
READDS1820LOOP: CLR TEMPDIN
NOP
NOP
SETB TEMPDIN
MOV R6,#07延时15μs
DJNZ R6,$
MOV C,TEMPDIN
RRC A
MOV R6,#25
DJNZ R6,$
DJNZ R7,READDS1820LOOP
RET
******写DS18B20的程序,从DS18B20中写1字节数据*****
WRITEDS1820: MOV R7,#08H
WRITEDS1820LOP: CLR TEMPDIN
MOV R6,#07H 延时15μs
DJNZ R6,$
RRC A
MOV TEMPDIN,C
MOV R6,#30延时104μs
DJNZR6,$
SETB TEMPDIN
NOP
DJNZR7,WRITEDS1820LOP
SETB TEMPDIN
RET
******************读TEMP******************88
READTEMP: LCALL INITDS1820
MOV A,#0CCH
LCALLWRITEDS1820 Skip ROM
MOVA, #44H
LCALL WRITEDS1820 开始转换
MOV R6,#250 延时
DJNZ R6,$
READTEMP1: LCALL INITDS1820
MOV A,#0CCH
LCALL WRITEDS1820 SkipROM
MOV A,#0BEH
LCALLWRITEDS1820 中间结果寄存器
MOV R6,#34H 延时104μs
DJNZ R6,$
READTEMP2:LCALL READDS1820
MOVTEMPL,A
LCALL READDS1820
MOVTEMPH,A
READTEMPOUT: RET
**************处理温度BCD码子程序***********
CONVTEMP:MOV A,TEMPH
ANL A,#80H
JZTEMPC1
CLR C
MOV A,TEMPL
CPL A
ADD A,#01H
MOV TEMPL,A
MOVA,TEMPH "-"
CPL A
ADDC A,#00H
MOVTEMPH,A TEMPHC HI=符号位
MOVTEMPHC,#0BH
SJMP TEMPC11
TEMPC1:MOV TEMPHC,#0AH"+"
TEMPC11:
MOV R6,#4H
TEMPC12:
MOV A,TEMPH
RRC A
MOV TEMPH,A
MOV A,TEMPL
RRC A
MOV TEMPL,A
DJNZ R6,TEMPC12
RET
*****************小数部分码表*********
TEMPDOTTAB:DB 00H,01H,01H,02H,03H,03H,04H,04H,05H,06H
DB 06H,07H,08H,08H,09H,09H
************显示区BCD码温度值刷新子程序********
DISPBCD: MOV 53H,TEMPHC
MOV A,TEMPL
MOV B,#10
DIV AB
MOV 50H,B
MOV B,#10
DIV AB
MOV 51H,B
JZ DISPBCD2
MOV 52H,A
RET
DISPBCD2: MOV 52H,#10
RET
TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0BFH
共阳段码表 "0","1","2","3","4","5","6","7","8","9","不亮","-"
END
/*************** writer:shopping.w ******************/
#include <reg51.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DQ = P3^6
uchar code DSY_CODE[] =
{ 0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0X00}
uchar code df_Table[] = {0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9}
uchar CurrentT = 0
uchar Temp_Value[]={0x11,0x22}
uchar Display_Digit[]={0,0,0,0}
bit DS18B20_IS_OK = 1
void Delay(uint x)
{
while(--x)
}
uchar Init_DS18B20()
{
uchar status
DQ = 1
Delay(8)
DQ = 0
Delay(90)
DQ = 1
Delay(8)
DQ = 1
return status
}
uchar ReadOneByte()
{
uchar i,dat=0
DQ = 1
_nop_()
for(i=0i<8i++)
{
DQ = 0
dat >>= 1
DQ = 1
_nop_()
_nop_()
if(DQ)
dat |= 0X80
Delay(30)
DQ = 1
}
return dat
}
void WriteOneByte(uchar dat)
{
uchar i
for(i=0i<8i++)
{
DQ = 0
DQ = dat& 0x01
Delay(5)
DQ = 1
dat >>= 1
}
}
void Read_Temperature()
{
if(Init_DS18B20() ==1 )
DS18B20_IS_OK = 0
else
{
WriteOneByte(0xcc)
WriteOneByte(0x44)
Init_DS18B20()
WriteOneByte(0xcc)
WriteOneByte(0xbe)
Temp_Value[0] = ReadOneByte()
Temp_Value[1] = ReadOneByte()
DS18B20_IS_OK=1
}
}
void Display_Temperature()
{
uchar i
uchar t=150
uchar ng=0, np=0
if ( (Temp_Value[1] & 0xf8) == 0xf8)
{
Temp_Value[1] = ~Temp_Value[1]
Temp_Value[0] = ~Temp_Value[0]+1
if (Temp_Value[0] == 0x00) Temp_Value[1]++
ng=1np=0xfd
}
Display_Digit[0] = df_Table[ Temp_Value[0] & 0x0f ]
CurrentT = ((Temp_Value[0] & 0xf0)>>4) | ((Temp_Value[1] & 0x07)<<4)
Display_Digit[3] = CurrentT / 100
Display_Digit[2] = CurrentT % 100 / 10
Display_Digit[1] = CurrentT % 10
if (Display_Digit[3] == 0)
{
Display_Digit[3] = 10
np = 0xfb
if (Display_Digit[2] == 0)
{
Display_Digit[2] = 10
np = 0xf7
}
}
for (i=0i<30i++)
{
P0=0x39P2=0x7fDelay(t)P2=0xFF
P0=0x63P2=0xbfDelay(t)P2=0xff
P0=DSY_CODE[Display_Digit[0]]
P2=0xDFDelay(t)P2=0xff
P0=(DSY_CODE[Display_Digit[1]]) | 0x80
P2=0xefDelay(t)P2=0xff
P0=DSY_CODE[Display_Digit[2]]
P2=0xf7Delay(t)P2=0xff
P0=DSY_CODE[Display_Digit[3]]
P2=0xfb Delay(t) P2=0xff
if (ng)
{
P0 = 0x40 P2 = np Delay(t) P2=0xff
}
}
}
void main()
{
Read_Temperature()
Delay(50000)
Delay(50000)
while(1)
{
Read_Temperature()
if(DS18B20_IS_OK)
Display_Temperature()
}
}
驱动程序:#include"reg52.h"
sbit DQ=P1^4
unsigned char TempH,TempL
void delay(unsigned int i)//延时函数
{
while(i--)
}
void Init_DS18B20(void)
{
unsigned char x=0
EA=0
DQ = 1 //DQ复位
delay(8) //稍做延时
DQ = 0 //单片机将DQ拉低
delay(80)//精确延时 大于 480us
DQ = 1 //拉高总线
delay(10)
x=DQ //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(5)
EA=1
}
unsigned char ReadOneChar(void)
{
unsigned char i=0
unsigned char dat = 0
EA=0
for (i=8i>0i--)
{
DQ = 0// 给脉冲信号
dat>>=1
DQ = 1// 给脉冲信号
if(DQ)
dat|=0x80
delay(5)
}
return(dat)
EA=1
}
void WriteOneChar(unsigned char dat)
{
unsigned char i=0
EA=0
for (i=8i>0i--)
{
DQ = 0
DQ = dat&0x01
delay(5)
DQ = 1
dat>>=1
}
delay(5)
EA=1
}
void ReadTemperature(void)
{
unsigned char a=0
unsigned int b=0
unsigned int t=0
Init_DS18B20()
WriteOneChar(0xCC)// 跳过读序号列号的 *** 作
WriteOneChar(0x44)// 启动温度转换
delay(200)
Init_DS18B20()
WriteOneChar(0xCC)//跳过读序号列号的 *** 作
WriteOneChar(0xBE)//读取温度寄存器等(共可读9个寄存器) 前两个就是温度
TempL=ReadOneChar() //低位
TempH=ReadOneChar() //高位
Init_DS18B20()
WriteOneChar(0xCC)// 跳过读序号列号的 *** 作
WriteOneChar(0x44)// 启动温度转换
}
主程序;
main(){
unsigned char Temp,a
InitTimer0()
while(1){
ReadTemperature()
if(TempH>128)
{str[0]=dis_dm[11] //负号标志
TempH=~TempH // 取反加1
TempL=~TempL+1}
else
{str[0]=dis_dm[12]} //不亮
Temp=((TempL&0xf0)>>4)|((TempH&0x0f)<<4)
a=Temp/100
if(a==0) {a=12}
str[1]=dis_dm[a]//百位温度
str[2]=dis_dm[(Temp%100)/10]//十位温度
str[3]=dis_dm[(Temp%100)%10]&0x7f//个位温度,带小数点
str[4]=dis_dm[(TempL&0x0f)*6/10]//十分位
str[5]=dis_dm[10]//c
}
你主要是需要驱动程序,主程序你可以按照自己的需求写!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)