#include "regx52.h"
#include "lcd.h"							//调液晶头文件
#define uint unsigned int
#define uchar unsigned char

uchar code temp[]="  temperature  ";		//1602第一行显示数据
uchar disbuf[]="now:000.0C      " ;
uint zhi=0;
sbit QD=P2^4;

/*********************微秒级延时********************/
void delayus(uint us)					 //一次6US   微秒级延时
{
	while(us--);
}

/*********************DS18B20复位********************/	
void ds18b20init()
{
	QD=1;
	delayus(4);		//30us
    QD=0;
	delayus(60);	//720US
	QD=1;
	delayus(14);	//48US			 
	//P3_1=QD;	    //是否存在，拉低为存在
	//P3_0=QD;
	QD=1;
	delayus(20);
}	

/*********************读一个字节*******************/		   
readchar()
{
	uchar dat;
	uchar i;
	QD=1;
	for(i=8;i>0;i--)
	{
		QD=0;				  //总线拉低
		QD=1;				  //总线拉高
		dat=dat>>1;		  	  //右移读下一位
		if(QD)				  //当此刻QD等与1
		dat=dat|0x80;		  //此位为1，不然就位0了
		delayus(4);			  //延时等待下一次
	}
	return(dat);
}

/*********************写一个字节*******************/
void writechar(uchar dat)
{
	  uchar i;
	  QD=1;
	  for(i=8;i>0;i--)
	  {	   
	   QD=0;						//总线拉低
	   QD=dat&0x01;					//取最低位写给QD  若0 则保持低 若1为此时拉高
	   delayus(3);						//延时45US
	   QD=1;						//总线拉高  
	   dat=dat>>1;	  				//高向低移位
	   delayus(4);			  //延时等待下一次
	  }
}

/*********************读取DS18B20温度*******************/
read18b20()
{
	uchar x=0;
	uchar y=0;
	uint  t=0;
	ds18b20init();
	writechar(0xcc);	//跳过ROM匹配
	writechar(0x44);	//开始转换
	delayus(80);		//等待转换完成
	ds18b20init();
	writechar(0xcc);	//跳过ROM匹配
	writechar(0xbe);	//发读命令
	delayus(20);   		//!!!关键 延时一点
	x=readchar();		//读低字节
 	y=readchar();		//读高字节
 	t=(y*256+x);		//高低字节合并
	t=t*25/10;			//*2.5
	t=t>>2;				//右移两位（2.5/4=0.625）和上面一步等效位 *0.625, 
						//比实际放大了10倍等于把小数点后一位提到个位，分离个位就得到小数位的值
	return(t);			//返回温度值
/* t = (y*256+x)*25/10;		   跟上面步骤一样
	return( t >> 2  );*/
}						  

/*********************分离温度值*******************/ 
void ds18b20display()
{
   	uint zhi=0;
   	zhi=read18b20();
	disbuf[5]=zhi/100+0x30;
 	disbuf[6]=zhi%100/10+0x30;						
 	disbuf[8]=zhi%100%10+0x30;						//个位  因为放大了10倍，此位实为小数位
 	write_charchuan(0x80+0x40,disbuf);				//显示
}

/*********************主函数*******************/
main()
{
 	lcdinitial();										 //液晶显示初始化
// write_charchuan(0x80,temp);
	write_charchuan(0x80+0x40,disbuf);					 //写第二行字
 	while(1)
 	{
 		write_charchuan(0x80,temp);				   //写第一行字  为稳定性考虑 把它写到循环里面
 		ds18b20display();							   //调18B20显示函数
 	}
}







