#include<reg51.h>
sbit DQ=P1^4;
char code Tab [] ={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}
;
void delay(unsigned char i) //延时 2*i+5us
{
while(--i);
}
unsigned char Init_DS18B20()
//初始化DS18B20
{
unsigned char flag;
//存在标志位
DQ=1;
delay(1);
//短延时
DQ=0;
//总线产生下降沿 初始化开始
delay(250);
//总线保持低电平
480~960us
DQ=1;
//总线拉高 准备接收DS18B20应答脉冲
delay(30);
//读应答等待
flag=DQ;
return(flag);
}
void Write (unsigned char dat)
//向DS18B20写一个字节
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ=0; //总线拉低 启动写时间片
delay(6);
//大于1US
DQ=dat&0x01; //低字节开始逐位写
delay(30);
//延时60us 使写入有效
DQ=1;
//准备启动下一个写时间片
dat>>=1;
}
delay(5);
}
unsigned char Read(void)
//从DS18B20读一字节
{
unsigned char i=0,dat=0;
for(i=0;i<8;i++)
//8位
{
DQ=0;
// 总线拉低 启动读时间片
delay(1);
//大于1US
DQ=1;
//总线拉高 准备读取
dat>>=1;
if(DQ)
dat=dat|0x80;
//从总线拉起时算起 约15us内读取数据
delay(30);
//延时至少60us
}
return (dat);
}
unsigned char Get(void)
{
float temp;
unsigned char TH,TL;
while( Init_DS18B20()) ;
//验证初始化
Write(0xcc);
//跳过序列号检测
Write(0x44);
//启动温度转换
Init_DS18B20();
//初始化
Write(0xcc);
//跳过序列号检测
Write(0xbe);
//读取温度数据 读暂存器
TL=Read();
//低8位
TH=Read();
//高8位
temp=((TH*256)+TL)*0.0625*10+0.5; //实际温度 放大10倍 加四舍五入处理
return (temp);
}
void Display()
{
unsigned int t;
t=Get();
//小数位
P0=Tab[t%10];
P2=0xfd;
delay(200);
//个位
P0=Tab[(t/10)%10];
P2=0xf7;
delay(200);
//十位
P0=Tab[(t/100)%10];
P2=0xef;
delay(200);
//百位
P0=Tab[t/1000];
P2=0xdf;
delay(200);
//小数点
P0=0x7f;
P2=0xfb;
delay(200);
//C温度符号
P0=0xc6;
P2=0xfe;
delay(200);
}
void main()
{
Init_DS18B20();
while(1)
{
Display();
delay(20);
}
} |