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

📄 ds18b20.c

📁 温度芯片DS1820的驱动程序
💻 C
字号:
//korfi 2007/09/22

extern int iIOPort00;
extern int *IOPort00;
extern unsigned char SNCode[8];	// DS18B20中唯一的序列号
extern short jTemperture;
extern float fTemperture;


void SetDS18B20High()
{
	iIOPort00 |= 0x10;
	*IOPort00 = iIOPort00;
}

void SetDS18B20Low()
{
	iIOPort00 &= 0xEF;
	*IOPort00 = iIOPort00;
}

//=======================================================================
void Delay3uS()
{
    unsigned short j;
// op   	for(j=0;j<70;j++);
   	for(j=0;j<41;j++);
}

void Delay10uS()
{
    unsigned short j;
//op   	for(j=0;j<260;j++);
   	for(j=0;j<140;j++);
}

void Delay15uS()
{
    unsigned short j;
//op   	for(j=0;j<390;j++);
   	for(j=0;j<211;j++);
}

void Delay45uS()
{
    unsigned short j;
//op   	for(j=0;j<1200;j++);
   	for(j=0;j<640;j++);
}

void Delay580uS()
{
    unsigned int j;
//op   	for(j=0;j<10000;j++);
   	for(j=0;j<19640;j++);
}

// 耗时:508 + 508 + 10 = 1026uS
int    InitDS18B20()  //Reset Tx
{
	unsigned int i, j;

    SetDS18B20Low();			//低电平 Tx产生 "reset pulse"
    Delay580uS(); 		//延时580us  "480us(min)--960us(max)"
    SetDS18B20High();			//高电平上拉
    i=0;

    while(1)  			//等待DS18B20产生 "presence pulse"
    {         			//60us(min)--240us(max)
      j = *IOPort00;
      if ((j&0x40)==0) break;
      Delay10uS();
      if (i++>=30) return 0;      //300us内没有出现低电平,则未挂接或DS18B20故障
    }
    Delay580uS();		//延时580us 等待DS18B20就绪
    return 1;
}

// 耗时:63*8 = 504uS
void    WriteCommandToDS18B20(unsigned char Cmd ) 	//命令字放在Byte中
{
	int i, Mask;

	Mask = 1;
	for(i=0;i<8;i++)
	{
		if(Cmd & Mask)
		{
			SetDS18B20Low();		//DS18B20=0;
			Delay15uS();
			SetDS18B20High();		//DS18B20=1;
			Delay45uS();
		}
		else
		{
			SetDS18B20Low();		//DS18B20=0;
			Delay15uS();
			Delay45uS();
			SetDS18B20High();		//DS18B20=1;
		}
		Mask <<= 1;
		Delay3uS();
	}
}

// 耗时:63*8 = 504uS
unsigned char   ReadByteFromDS18B20()	/*从DS18B20中读一个字节*/
{
	int i, j;
	unsigned char c;
	
	c=0;
	for(i=0;i<8;i++)
	{
		SetDS18B20Low();		//DS18B20=0;
        Delay3uS();
		SetDS18B20High();		//DS18B20=1;
		Delay15uS();
		c >>= 1;
		j = *IOPort00;
		if ( j&0x40 ) c |= 0x80;
		Delay45uS();
	}
	return c;
}

unsigned int cal_crc(unsigned char *ptr, unsigned char len) 
{
	unsigned char i;
	unsigned int crc=0;

	while(len--!=0) 
	{
		for(i=0x80; i!=0; i/=2) 
		{
			if ((crc&0x80)!=0) 
			{
				crc *= 2; 
				crc ^= 0x131;		/* CRC = X^8 + X^5 + X^4 + 1*/
			}   /* 余式CRC乘以2再求CRC  */
			else 
				crc *= 2;
			if ( (*ptr&i)!=0 ) crc ^= 0x131;                /* 再加上本位的CRC */
		}
		ptr++;
	}
	return(crc);
}

/*输入InputData,输出CRC*/
unsigned char  CreatCrcValue(unsigned char * p) 
{                     
    unsigned char i, j, InputData, CRC;
    
    CRC = 0;
    /*对9个字节的数据进行CRC校验,余数应为0*/
    for(j=0;j<9;j++)	
	{
        InputData = *(p+j);
	    for(i=0;i<8;i++)
	    {
		    if (((InputData ^ CRC) & 0x01) != 0)
		    {  
			/*若输入的BIT数据与CRC的低0位异或为1,则CRC与0x18异或
		      然后CRC左移。CRC的高8位置1(此位为BIT数据与CRC的低0位异或的1)*/
		         CRC ^= 0x18; 
		         CRC >>= 1;
		         CRC |= 0x80;
		     }   
		     else  
		     	CRC >>= 1;
  	      	 InputData >>= 1;
	    }
    }
    return CRC;
}

void ReadSerialNumber()		// 读取DS18B20中唯一的序列号
{
     int i;

	if (!InitDS18B20())	/* No DS18B20 present */
	{
		jTemperture = -32768;	// 0x8000
		return;
	}
	
	WriteCommandToDS18B20(0x33);	/* Read Rom command */
	Delay580uS();
	
	for (i=0; i<8; i++)
	{
		 SNCode[i] = ReadByteFromDS18B20();
		 Delay580uS();
	}
	SNCode[6] ^= 'H';
	SNCode[5] ^= 'J';
	SNCode[4] ^= 'Z';
//	SNCode[3] ^= 0xFF;
//	SNCode[2] ^= 0xFF;
//	SNCode[1] ^= 0xFF;
     
}

void ReadTemperature()	/*读温度精度为0.1℃,存放在FTemperature中*/
{
     int i;
     unsigned char c, CRC, uData1[10];  
     
     if (!InitDS18B20())	/* No DS18B20 present */
	 {
		jTemperture = -32768;	// 0x8000
		return;
	 }

     WriteCommandToDS18B20(0xCC);	/* Skip Rom command */

     WriteCommandToDS18B20(0x4E);	/*write Scratchpad */

     WriteCommandToDS18B20(0x4B);	/*write TH */
     WriteCommandToDS18B20(0x46);	/*write TL */
     WriteCommandToDS18B20(0x7F);	/*write Configuration register */


     //InitDS18B20();					/* Reset*/
     if (!InitDS18B20()) 
	 {
		jTemperture = -32768;	// 0x8000
		return;
	 }
     WriteCommandToDS18B20(0xCC);	/* Skip Rom command */
     WriteCommandToDS18B20(0x44);	/* Convert T command  启动温度变换 */

     for (i=0; i<100; i++) Delay580uS();	/*等待温度变换完成*/
     
     c = ReadByteFromDS18B20();
     i=0;
     while (c!=0xFF)
     {
         c = ReadByteFromDS18B20();
         Delay580uS();
         if(i++>=5000) //失败
 		 {
			jTemperture = -32768;	// 0x8000
			return;
		 } 
     }

     InitDS18B20();					/* Reset */
     WriteCommandToDS18B20(0xCC);	/* Skip Rom command */
     WriteCommandToDS18B20(0xBE);	/* Read Scratchpad command 读内存命令 */

     /*读取读内存值 9个字节 低位在前, 存放在XmtDat*/
     for(i=0;i<9;i++)
         uData1[i] = ReadByteFromDS18B20();
     
     uData1[9] = cal_crc(uData1, 8);
     
/*     i = uData1[1];
     i <<= 8;
     i += uData1[0];
     t = i * 0.0625;
*/     
     CRC = CreatCrcValue(uData1);
     
	if(CRC != 0) //失败
		jTemperture = -32768;	// 0x8000
	else
	{
		jTemperture = (uData1[1]<<8) + uData1[0];
		fTemperture =   (float)jTemperture *0.0625;
		if(fTemperture > 50.0)
		{
			//SetAdj3High();
			//ReadK2();
			ReadK1();
		}	
		else
		{
			//SetAdj3Low();	
			ReadK1();
		}	
	}	
		
}

⌨️ 快捷键说明

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