介绍
通过DS18B20采集温度在LCD1602上显示
第一行显示温度第二行显示精度
Proteus运行仿真图

源程序
主函数
#include<reg51.h>
#include "mine.h"
uchar code WenDu[]={"Tempture:"};
uchar code JingDu[]={"Accuracy:0.0625"};
uchar code Sz[]={"0123456789"};
int Tempture;
void main()
{ LCD_Init();
ds18b20Init();
ds18b20Start();
delayxms(1000);
while(1)
{
TemptureDisplay();
}
}
void TemptureDisplay()
{
uint i,Bai,Ge,Shi;
Tempture=ds18b20ReadTemperture()*10;
if(Tempture<0)
{
Tempture=-Tempture;
DisplayChar(1,9,'-');
}
else DisplayChar(1,9,'+');
Bai=Tempture/100;
Ge=Tempture%10;
Shi=(Tempture%100)/10;
for(i=0;i<9;i++)
DisplayChar(1,i,WenDu[i]);
for(i=0;i<15;i++)
DisplayChar(2,i,JingDu[i]);
DisplayChar(1,12,'.');
DisplayChar(1,14,0xdf);
DisplayChar(1,15,'C');
DisplayChar(1,10,Sz[Bai]);
DisplayChar(1,11,Sz[Shi]);
DisplayChar(1,13,Sz[Ge]);
}
自定义头文件
#ifndef _MINE_H
#define _MINE_H
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
void ds18b20Rest();
uchar ds18b20Check();
uchar ds18b20ReadBit();
uchar ds18b20ReadByte();
void ds18b20WriteByte(uchar dat);
void ds18b20Start();
uchar ds18b20Init();
float ds18b20ReadTemperture();
void TemptureDisplay();
sbit DQ=P3^3;
void Busy();
void W_Data(uchar dat);
void W_Cmd(uchar cmd);
void LCD_Init();
void DisplayChar(uchar y , uchar x , uchar dat );
sbit rs=P2^0;
sbit rw=P2^1;
sbit e=P2^2;
void delay10us(uint us);
void delayxms(uint x);
#endif
LCD1602函数
#include<reg51.h>
#include "mine.h"
void Busy()
{do
{
e=0;
rs=0;
rw=1;
P0=0Xff;
e=1;
} while (P0^7==1);
}
void W_Cmd(uchar cmd)
{
P0=cmd;
rs=0;
rw=0;
e=0;
delayxms(2);
e=1;
delayxms(2);
e=0;
}
void W_Data(uchar dat )
{
P0=dat;
rs=1;
rw=0;
e=0;
delayxms(2);
e=1;
delayxms(2);
e=0;
}
void LCD_Init()
{
W_Cmd(0x38);
W_Cmd(0x0c);
W_Cmd(0x06);
W_Cmd(0x01);
}
void DisplayChar(uchar y , uchar x , uchar dat )
{
uchar address;
if (y==1)
address=0x80+x;
else
address=0xc0+x;
W_Cmd(address);
W_Data(dat);
}
DS18B20
#include<intrins.h>
#include "mine.h"
void ds18b20Reset()
{
DQ=0;
delay10us(75);
DQ=1;
delay10us(2);
}
uchar ds18b20Check()
{
uchar time_temp=0;
while(DQ&&time_temp<20)
{
time_temp++;
delay10us(1);
}
if(time_temp>=20)return 1;
else time_temp=0;
while((!DQ)&&time_temp<20)
{
time_temp++;
delay10us(1);
}
if(time_temp>=20)return 1;
return 0;
}
uchar ds18b20ReadBit()
{
uchar dat=0;
DQ=0;
_nop_();_nop_();
DQ=1;
_nop_();_nop_();
if(DQ)dat=1;
else dat=0;
delay10us(6);
return dat;
}
uchar ds18b20ReadByte()
{
uchar i=0;
uchar dat=0;
uchar temp=0;
for(i=0;i<8;i++)
{
temp=ds18b20ReadBit();
dat=(temp<<7)|(dat>>1);
}
return dat;
}
void ds18b20WriteByte(uchar dat)
{
uchar i=0;
uchar temp=0;
for(i=0;i<8;i++)
{
temp=dat&0x01;
dat>>=1;
if(temp)
{
DQ=0;
_nop_();_nop_();
DQ=1;
delay10us(6);
}
else
{
DQ=0;
delay10us(6);
DQ=1;
_nop_();_nop_();
}
}
}
void ds18b20Start()
{
ds18b20Reset();
ds18b20Check();
ds18b20WriteByte(0xcc);
ds18b20WriteByte(0x44);
}
uchar ds18b20Init()
{
ds18b20Reset();
return ds18b20Check();
}
float ds18b20ReadTemperture()
{
float temp;
uchar datH=0;
uchar datL=0;
uint value=0;
ds18b20Start();
ds18b20Reset();
ds18b20Check();
ds18b20WriteByte(0xcc);
ds18b20WriteByte(0xbe);
datL=ds18b20ReadByte();
datH=ds18b20ReadByte();
value=(datH<<8)+datL;
if((value&0xf800)==0xf800)
{
value=(~value)+1;
temp=value*(-0.0625);
}
else
{
temp=value*0.0625;
}
return temp;
}
共用函数
#include<reg51.h>
#include "mine.h"
void T0_init()
{
TMOD=0x01;
TH0=0x3c;
TL0=0xb0;
EA=1;
ET0=1;
TR0=1;
}
void delay10us(uint us)
{
while(us--);
}
void delayxms(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<110;j++);
}
显示负数的时候小数位会有偏差但不知道原因