#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit ds=P2^4;
bit flag;
uint temp,num;
void writecod(uchar);
void writedata(uchar);
void delay();
sbit RS=P2^5; //LCD1602數據/命令選擇端
sbit RW=P2^6; //LCD1602讀/寫選擇端
sbit EN=P2^7; //LCD1602使能端
uchar code table[]={'0','1','2','3','4','5','6','7','8','9'};
void delayus(uint t)//us級的延時程序
{
while(t--);
}
void ds_reset()//DS18B20復位初始化
{
ds=1;//初始總線
delayus(5);//11.0592M大約66us
ds=0;//拉低總線
delayus(80);//大約延時700多us
ds=1;//釋放總線
delayus(14);//11.0592M延時時間差不多在150us
if(ds==0)
flag=1;
else
flag=0;
delayus(20);//大約200多us
}
bit ds_read_bit()//一個位的讀取函數
{
bit dat;
ds=0;
_nop_();//一個機器周期的延時函數大約1us;
_nop_();
ds=1;//釋放總線
_nop_();
dat=ds;
delayus(10);
return dat;
}
//DS18b20在傳輸數據的時候都是低位在前
uchar ds_read_byte()//讀一個字節
{
uchar i,j,k;
for(i=0;i<8;i++)
{
j=ds_read_bit();
k=(j<<7)|(k>>1);
}
return k;
}
void ds_write_byte(uchar dat)//寫一個字節
{
uchar i;
for(i=0;i<8;i++)
{
ds=0;
_nop_();
ds=dat;
ds=dat&0x01;//只保留dat的最低位,因為DS18B20在傳輸數據的過程中都是低位在前
delayus(6);
ds=1;
dat=dat>>1;
}
delayus(6);
}
uint read_temperature()//讀溫度
{
uchar a,b;//DS18B20的溫度分別分2個字節存放的,分別低8位LSB和高8位MSB,所以這里a用來存低8位b用來存高8位
ds_reset();//初始化
ds_write_byte(0xcc);//發送跳過ROM
ds_write_byte(0xbe);//發送讀取溫度指令
a=ds_read_byte();
b=ds_read_byte();
//接下來用一個16位的變量來存儲溫度值
temp=b;
temp=temp<<8;
temp=temp|a;
temp=temp*0.0625*10+0.5;//為了方便顯示將數放10倍,+0.5四舍五入;
return temp;
}
void writecod(uchar x)
{
RS=0;
RW=0;
EN=0;
P0=x;
delay();
EN=1;
delay();
EN=0;
}
void writedata(uchar y)
{
RS=1;
RW=0;
EN=0;
P0=y;
delay();
EN=1;
delay();
EN=0;
}
void delay()
{
uchar a,b;
for(a=100;a>0;a--)
for(b=100;b>0;b--);
}
void main()
{
writecod(0x01);
writecod(0x38);
writecod(0x0e);
writecod(0x06);
writecod(0x80);
while(1)
{
ds_reset();//初始化
ds_write_byte(0xcc);//跳過ROM
ds_write_byte(0x44);//啟動溫度轉換
num=read_temperature();
writecod(0x80);
writedata(table[num/100]);
writecod(0x80+1);
writedata(table[num%100/10]);
writecod(0x80+2);
writedata('.');
writedata(table[num%10]);
writedata(0xdf);
writedata('C');
delay();
delay();
delay();
}
}
|