⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 18b20.c

📁 基于c51单片机的18b20实时温度检测
💻 C
字号:
 #include<regx51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit  rs=P2^1	;
sbit  rw= P2^2	;
sbit  e=P2^3 ;
sbit   DO=P1^0;

uchar temp_l = 0;  //温度值存储低位字节
uchar temp_h = 0;  //温度值存储高位字节

uchar tempsign = 0;  //温度值符号位
uchar temp_integer[4]; //温度整数存储数组
uchar temp_dicimal[5]; //温度小数存储数组

void delay(uint ms)
{
 uint i;
 uchar j;
 for(i=0;i<ms;i++)
   for(j=0;j<250;j++)
   {
    _nop_();
   	_nop_();
	_nop_();
    _nop_();
   }



}
void  write_com(uchar com)
{
	 rs=0;
	 P3=com;
	 delay(1);
	 e=1;
	 delay(1);
	 e=0;

}

void  write_data(uchar date)
{
	 rs=1;
	 P3=date;
	 delay(1);
	 e=1;
	 delay(1);
	 e=0;

}
void gotoxy(uchar x,uchar y)	//光标指针移动到x行y列
{
	if(x==0)
	{
		write_com(0x80+y);
    }
	else
	{
		write_com(0x80+0x40+y);
	}
}	
/* ##########################################################################
初始化:设置显示模式       ----  0x38  --设置16x2 显示,5x7点阵,8位数据接口
        显示开/关及光标设置 --   0x08  --关显示
		                    --   0x0b  --开显示
								 0x0e  --显示光标,不闪烁
								 0x0c  --不显示光标,不闪烁
								 0x0d  --光标闪烁,不显示
								 0x0f  --光标显示+闪烁
						  ------ 0x06  --读或写一个字符后地址指针加一,且光标加一,整屏不移动
						  ------ 0x01  --显示清屏:数据指针清零,所有显示清零
					    	     0x02  --显示回车:数据指针清零    
 ######################################################################### */ 
void init()
{
	  rw=0;	   //开写状态
	 // write_com(0x01);
	  write_com(0x38);
	  write_com(0x0f);
	  write_com(0x06);
	  write_com(0x0c);	
}
void print(uchar *p) //显示字符串	 //void display_string(uchar *str,uchar len)
{									//	{
    while(*p)						//	 	uchar i;
	{								//	 	for(i=0;i<len;i++)
		write_data(*p);				//		 {
		p++;						//		   write_data(str【i】);
	}								//		  }
}									//
void display_number(uchar number)	//	 }
{
	write_data(0x30+number);  //转化为ASCII码
} 

/*us级延时,延时时间约4+2*i*/
void Delayus(uchar i)
 {
  while(--i);
 }

/*产生复位脉冲,等待应答信号*/
bit Resetpaulse()
{

 DO = 0; //拉低约600us
 Delayus(150);
 Delayus(150);

 DO = 1;//产生上升沿,延时约15~60us
 Delayus(30);

 return(~DO); //等待应答信号

} 

/*读取数据一位*/
bit Readbit()
{
 uint i = 0;
 bit b = 0;

 DO = 0; //产生读时隙  
 i++;	 //维持低电平至少1us

 DO = 1; //1us以上后拉高
 Delayus(2); //延时8us,DO下降沿15内ds18b20输出的数据才有效


 b = DO; //读取数据
 Delayus(40);	 //每个读时隙至少持续60us

 return(b);
} 

/*读取一个字节*/
uchar Readbyte()
{
 uchar byte_read = 0;
 uchar i, j;

 for(i=0; i<8; i++)
  {
   j = Readbit();
   byte_read = (j<<i) | byte_read; //低位读起
  }

 return(byte_read);
} 

/*写一个字节*/
void Writebyte(uchar byte_to_write)
{
 uchar i = 0;
 uchar j = 0;
 bit write_bit = 0;

 for(j=0; j<8; j++)
  {
   write_bit = 	(byte_to_write & 0x01);
    if(write_bit == 1) //写1
	 {
	  DO = 0;  //产生写时隙
	  Delayus(3);	   //延时15us
	  
	  DO = 1;  //写1
	  Delayus(40);   //延时,写时隙不得低于60us
	 }
	else
	 {
	  DO = 0;  //产生写时隙
	  Delayus(50);   //延时,保持低约60us~120us 
	  DO = 1;  
	  i++;
	 }
   byte_to_write = byte_to_write >> 1;
  }
}


/*启动温度转换*/
void StartConvert()
{
 Resetpaulse();	  // 发出复位脉冲,每次操作都从复位开始
 delay(1);
 Writebyte(0xcc); //skip room命令,跳过序列号命令字
 Writebyte(0x44); //启动温度转换命令
}

/*读取温度值*/
void ReadTempreture()
{
 Resetpaulse();	  // 发出复位脉冲,每次操作都从复位开始
 delay(1);
 Writebyte(0xcc); //skip room命令
 Writebyte(0xbe); //读取暂存器命令
 temp_l = Readbyte(); //存储温度低字节值 (整数部分低四位和小数部分)
 temp_h	= Readbyte(); //存储温度高字节值 (其中高五位为符号位)
}

/*数据处理程序*/
void Digital_process()
{
	 uchar total = 0;
	 uchar low = 0;
	 uint  dicimal = 0;
	
	 tempsign = (temp_h >> 7) & 0x01; //得出符号位
	 total = ((temp_h << 4)&0xf0) | ((temp_l >> 4)&0x0f); //取整数位
	 low =  temp_l & 0x0f; //取小数位
	
	 if(tempsign == 0)
	  {
		   temp_integer[0] = total / 100 + '0'; //计算百、十、个位	 	  
		   temp_integer[1] = (total%100)/10 + '0';
		   temp_integer[2] = (total%100)%10 + '0'; 
		   temp_integer[3] = '\0';
		/*   if(temp_integer[0] == '0')
			 {
				   if(temp_integer[1] != '0')
					{
				     	temp_integer[0] = '\0'; //百位零消隐
				     
				     }
				   else if(temp_integer[1] == '0')
				    {
					 	temp_integer[0] = '\0';  //百位,十位零都消隐
					 	temp_integer[1] = '\0';
					}
		     }	*/ 
		   dicimal = low * 625;	         //计算小数
		   temp_dicimal[0] = dicimal / 1000 + '0';	//十分位
		   temp_dicimal[1] = dicimal % 1000 /100 + '0';	 //百分位
		   temp_dicimal[2] = dicimal % 100 / 10 + '0';	 //千分位
		   temp_dicimal[3] = dicimal % 10 + '0';		//万分位
		   temp_dicimal[4] = '\0'; 	  //数组加一个空字符(好像系统也会自动加上的)
	  }
	
	 else if(tempsign == 1)	  //负数处理
	  {
		   if(low == 0x00)		//负数要取反加一再乘以0.0625就是实际温度值了,我这里没有设那么多int型变量,
		     {
				  total = ~total + 1;  //所以就用了这么一个计算方法
				  low &= 0x0f;
			  }				   /*具体一点讲,小数低四位为全零时取反加一要有进位,此时只要整数位取反加一即可,
		                         小数位不用理会,其余情况整数位取反,小数位取反加一*/
		   else
		     {
				  total = ~total ;
				  low = (~low) + 1;
				  low &= 0x0f;	  //注意高四位要变成零
			  }	 	  
		   temp_integer[1] = (total%100)/10 + '0'; //计算十、个位
		   temp_integer[2] = (total%100)%10 + '0'; 
		   temp_integer[3] = '\0';
		
		
		 //  if(temp_integer[1] == '0')
		 //   {
		//	 temp_integer[1] = '\0';
		 //   }
		   dicimal = low * 625;
		   temp_dicimal[0] = dicimal / 1000 + '0';
		   temp_dicimal[1] = dicimal % 1000 /100 + '0';
		   temp_dicimal[2] = dicimal % 100 / 10 + '0';
		   temp_dicimal[3] = dicimal % 10 + '0';
		   temp_dicimal[4] = '\0';
	  }
	 

}

void main()
{
	 bit palse = 0;
	 init();
	
	 gotoxy(0,2);
	 print("CHECKING...");
	 delay(300);
	 
	
	 palse = Resetpaulse();	  //检测DS18B20是否响应
	 if(palse)
	  {
		   init();
		   gotoxy(0,3);
		   print("DS18B20 OK");
	   }
	 else
	   {
		    init();
		    gotoxy(0,3);
		    print("DS18B20 ERROR");
		    while(1);
	
	   } 
	 
	  while(1)
	  {
		   delay(1);
		   StartConvert();
		   delay(200);
		   ReadTempreture();
		   Digital_process();
		
		   if(tempsign == 0)     //显示正值温度
		   {
			     gotoxy(1,0);
				 print("TEMP:");
		         print("+");
			     print(temp_integer);
		         print(".");
		         print(temp_dicimal);
			}
		   else				     //显示负值温度
		    {
				 gotoxy(1,0);
				 print("TEMP:");
	             print("-");
		         print(temp_integer + 1);
			     print(".");
                 print(temp_dicimal);
			}
	   }
	 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -