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

📄 18b20shu.c

📁 用18B20数字温度传感器芯片 实现温度采集 并在数码管(用7290)显示
💻 C
字号:
#include "reg51.H"
#include "intrins.h"
#define  DELAY5US _nop_();

sbit 	SDA=P1^0;
sbit 	SCL=P1^1;
sbit 	P1_7=P1^7;
#define WSLA1 0x70
#define RSLA1 0x71



sbit DQ=P3^3;  
//***************   函数声明   *********************
void STA(void);
void STOP(void);
void CACK(void);
void WRBYT(unsigned char  *p);
void WRNBYT(unsigned char  *R3,unsigned char  *R2,unsigned char  *R0,unsigned char  n);
unsigned b[20]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe4,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e,0xfa,0x1e,0x12,0x00};

unsigned char GET_TEMPER();
unsigned char temp[2],temp_num;
void INIT_1820();                     //初始化函数
void TEMP_COV();                      //温度转换函数
void WRITE_1820(unsigned char datax); //写DS18B20函数
void READ_1820();                     //读DS18B20函数
void DELAY60US(); 
void DELAY80US();
void DELAY300US();
void DELAY();
unsigned char FLAG1;
//***************   主函数   *********************
main()
{
//unsigned char datay;

unsigned char a[8]={0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc};
unsigned char shu,n,*c,*y,*x,wai=0x10,WSLA=WSLA1,f4,ffh,ffl,xiaoh,xiaol;//f4是小数的二进制数
unsigned long int h=0,f,ff;
//P1=0xff; 
while(1)
	{  
		GET_TEMPER();   //采集温度函数(数据在temp[0]、temp[1]中)
		TEMP_COV();	    //将12位精度的数值转换成8位温度值在temp_num中
		h=(unsigned long int)temp_num;
		f4=temp[0]&0x0f;
		f=(unsigned long int)f4;
		ff=f*10000/16;
		xiaoh=ff/100;
		xiaol=ff%100;

		shu=(unsigned char)h;
		a[4]=shu%10;//a[0]为个位
		a[4]=b[a[4]]+1;//将a【0】变为字符码
		a[5]=shu%100;
		a[5]=a[5]/10;
		a[5]=b[a[5]];
		a[6]=shu/100;
		a[6]=b[a[6]];

		ffh=(unsigned char)xiaoh;
		a[2]=ffh%10;
		a[2]=b[a[2]];
		a[3]=ffh/10;
		a[3]=b[a[3]];

		ffl=(unsigned char)xiaol;
		a[0]=ffl%10;
		a[0]=b[a[0]];
		a[1]=ffl/10;
		a[1]=b[a[1]];

		x=&WSLA;
		c=&wai;
		y=a;
		n=8;
		WRNBYT(x,c,y,n);
		DELAY();

		//datay=temp_num;  //缓冲
		//P1=~datay;	    //数据取反后送P1口输出
	} 
}



unsigned char GET_TEMPER()
{   unsigned char i;
	DQ=1;
BCD:INIT_1820();	//对DS18B20初始化
	if(FLAG1!=1)
	  goto BCD;	    //如果18B20不存在返回继续
	DELAY80US();    //存在时延时
	i=0xcc;		    //写ROM命令(跳过序列号)
	WRITE_1820(i);
	i=0x44;		    //发送温度转换命令
	WRITE_1820(i);
	DELAY();		//延时等待转换
CBA:INIT_1820();	//对DS18B20初始化
	if(FLAG1!=1)
	   goto CBA;	//如果18B20不存在返回继续
	DELAY80US();    //存在时延时
	i=0xcc;		    //写ROM命令(跳过序列号)
	WRITE_1820(i);   
	i=0xbe;		    //发出读温度命令
	WRITE_1820(i);   
	READ_1820();	//READ_1820 

} 

void INIT_1820() 
{   DQ=1;
	_nop_();
	DQ=0;
	DELAY300US();	
	DQ=1;
	DELAY80US(); 
	if(DQ!=0x01) FLAG1=0x01;	//建立标志
	  else FLAG1=0x00;
	DELAY300US();
	DQ=1;						//释放总线
}

void WRITE_1820(unsigned char datax)
{   unsigned char i;
	for(i=0;i<8;i++)
	{		//DQ=0后15US之内就应当把数据发送到DQ上
	DQ=0;	 		
	_nop_(); 		
	_nop_(); 		
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();  	
	if(datax & 0x01)DQ=1;  //根据datax 组装发送位DQ
       	else  DQ=0;   	   //或者使用 DQ=datax&0x01;
	datax=datax>>1;
	DELAY60US();		   //DS18B20在DQ=0的15-60us内采样DQ			 	
	DQ=1;
	_nop_();
	 } 	
}
  
void READ_1820()  		//从DS18B20中连续读出两个字节温度值
{  unsigned char i,j;   //数据送temp[2]中,其中temp[0]为低8位,temp[1]为高四位
   for(i=0;i<2;i++)
	  { temp[i]=0xff;
	    for(j=0;j<8;j++)
		{
		  DQ=1;
		  _nop_();
		  DQ=0;   	//拉低DQ
		  _nop_();	//维持1US	
		  DQ=1; 	//释放	
		  _nop_();   //DQ=0后15US内主控器必须完成采样DQ
		  temp[i]=temp[i]>>1;
 		  if(DQ==1) temp[i]=temp[i]|0x80;
		  	else temp[i]=temp[i]&0x7f;
		  DELAY60US(); 			//>60US 后释放DQ 		  
		 } 	  
	  }
}

void TEMP_COV() 		//将temp[0]、temp[1]中的12位数职去掉低4位(小数)
{unsigned char i,j;     //合并到 temp_num中
 i=temp[0]&0xf0;
 i=i>>4;
 j=temp[1]<<4;
 temp_num=i|j;
 }

void DELAY60US()
{ unsigned char i;
	for(i=0;i<6;i++); 
}

void DELAY80US()
{ unsigned char i,j;
	for(i=0;i<8;i++)
		for(j=0;j<1;j++);
}

void DELAY300US()
{  unsigned char i,j;
	for(i=0;i<33;i++)
		for(j=0;j<1;j++);
}

void DELAY()
{ unsigned char i,j;
	for(i=0;i<255;i++)
		for(j=0;j<250;j++);  
}
//【附录二】由C语言编制的I2C通讯子函数
// 以上的内容如果在主函数的前面已经包含、声明时,可以省略。
//#################################################################################
void STA(void) 						//启动信号子函数
{	 SDA=1;
     SCL=1;
     DELAY5US 	 
	 SDA=0;
	 DELAY5US 
     SCL=0;
}
//#################################################################################
void STOP(void) 					//停止信号子函数
{   SDA=0;
    SCL=1; 	
	DELAY5US 
	SDA=1;
	DELAY5US  	
}
//#################################################################################
void MACK(void) 					//应答信号子函数
{    SDA=0;
     SCL=1;
	 DELAY5US 	
	 SCL=0;
	 SDA=1;
}
//#################################################################################
void NMACK(void) 					//非应答信号子函数

{    SDA=1;
     SCL=1;
	 DELAY5US   	 
	 SCL=0;
	 SDA=0;
}
//#################################################################################
void CACK(void)         			//应答检测子程序
{   
     SDA=1;
     SCL=1;
	 DELAY5US    	 
	 F0=0;
	 if(SDA==1)
	 F0=1;
	 SCL=0;
}
//#################################################################################
//                             发送一字节子数据程序     WRBYT
//#################################################################################
void WRBYT(unsigned char  *p)
{    unsigned char  i=8,temp;
     temp=*p;
	 while(i--)
	 {   if((temp&0x80)==0x80)
	         {  SDA=1; 
			    SCL=1; 			
				DELAY5US 				
				SCL=0; 			 
			 }
			 else
			 {  SDA=0;
			    SCL=1; 				
				DELAY5US 				
				SCL=0;
			 }
			 temp=temp<<1;
	 }
}
//#################################################################################
//                            接收一字节子数据程序     RDBYT
//#################################################################################
void RDBYT(unsigned char  *p)
{    unsigned char i=8,temp=0;
     while(i--)
	 {    SDA=1;
	      SCL=1;
		  DELAY5US   		  
		  temp=temp<<1;
		  if(SDA==1)
		  	temp=temp|0x01;
		  else
		    temp=temp&0xfe;
          SCL=0;
	 }
     *p=temp;
}
//#################################################################################
//                           发送N个字节子数据程序     WRNBYT
//#################################################################################
void WRNBYT(unsigned char  *R3,unsigned char  *R2,unsigned char  *R0,unsigned char  n)
{                
 loop:    STA();
	      WRBYT(R3);
	      CACK();
	      if(F0)
	      goto loop;
		  WRBYT(R2);
		  CACK();
		  if(F0)
		  goto loop;
		  while(n--)
		  {  WRBYT(R0);
		     CACK();
			 if(F0)
			  goto loop;
			  R0++;
		  } 
          STOP();
}
//#################################################################################
//                            接收N个字节子数据程序     RDNBYT
//#################################################################################
//【子函数入口参数说明】:
//R3是外部器件地址写,R4是外部器件地址读,R2是从器件内部子地址,R0是目标数据块首地址,//n是要读的字节数
void RDNBYT(unsigned char  *R3,unsigned char  *R4,unsigned char  *R2,unsigned char  *R0,unsigned char  n)
{   
     loop1:  STA();
			 WRBYT(R3);
			 CACK();
			 if(F0)
			 goto loop1;
			 WRBYT(R2);
			 CACK();
			 if(F0)
			 goto loop1;
			 STA();
			 WRBYT(R4);
			 CACK();
			 if(F0)
			 goto loop1;
			 while(n--)
			 {    RDBYT(R0);
			    if(n>0)
  				    {
					  MACK();
				      R0++;
			        }
				 else  NMACK();
				 } 			  
			 STOP();
}
//#################################################################################

⌨️ 快捷键说明

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