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

📄 digthermo.c

📁 此程序实现了ds18b20温度传感器的单线数据采集
💻 C
字号:
/*此程序实现了ds18b20温度传感器的单线数据采集,并且通过LED显示小数和整数部分*/
#include "DigThermo.h"

/* 延时t*11us */
void delay(uint t)
{
  for(;t>0;t--);
} 

/* 产生复位脉冲初始化DS18B20 */
void TxReset(void)
{  char presence=1;
   while(presence)
   {
      while(presence)
     {
        DQ=1;_nop_();_nop_();//从高拉倒低
	    DQ=0;                                       
	    delay(50);           //550 us
	    DQ=1;                                        
	    delay(6);            //66 us
	     presence=DQ;         //presence=0 复位成功,继续下一步
     } 
     delay(45);            //延时500 us
     presence=~DQ;         
   }
   DQ=1;                   //拉高电平
}

/* 读取数据的一个字节 */
uchar RdByte(void)
{
	uchar i;
    uchar value=0;
    for(i=8;i>0;i--)
    {
      DQ=1;_nop_();_nop_();
      value>>=1;
      DQ=0;_nop_();_nop_();_nop_();_nop_();         //4 us
      DQ=1;_nop_();_nop_();_nop_();_nop_();         //4 us
      if(DQ)value|=0x80;
      delay(6);                                     //66 us
    }
   DQ=1;
   return(value);
}

/* 写数据的一个字节 */
void WrByte(uchar val)
{
   uchar i;
    for(i=8;i>0;i--)
     {
        DQ=1;_nop_();_nop_();                  //从高拉倒低
        DQ=0;_nop_();_nop_();_nop_();_nop_();  //5 us
        DQ=val&0x01;                           //最低位移出
        delay(6);                              //66 us
        val=val/2;                             //右移1位
     }
      DQ=1;
     delay(1);
}
/*功能匹配*/
bit match_rom(uchar *rom)
{
	uchar i;
	TxReset();
	WrByte(0x55);
	for(i=8;i>0;i--)
	{
		WrByte(*(rom+i-1));
	}
	return 1;
}	

/* 读取温度值 */
void RdTemp(uchar *serial)
{
	TxReset();			// 产生复位脉冲,初始化DS18B20 
	delay(200);			// 延时
	WrByte(0xcc);		// skip rom 命令
	WrByte(0x44);		// read scratchpad 命令
	delay(1);			// 延时
	match_rom(serial);	  //匹配
	WrByte(0xbe);		// convert T 命令
	tplsb = RdByte();	// 温度值低位字节(其中低4位为二进制的“小数”部分)
	tpmsb = RdByte();	// 高位值高位字节(其中高5位为符号位)		
}

 /*对采集到的数据进行处理*/
 void DataChange()
 {
   uint tem;
   uchar temp,flag;	
   uchar low,j;
   if(tpmsb>7)
   {
      flag=1;
      tem=tpmsb;
      tem<<=8;                                               
      tem=tem|tplsb;      // 两字节合成一个整型变量。
      tem=(tem^0xffff);//异或
	  tem=tem+1;	 //取反加1
	  tplsb=tem&0xff;
	  tpmsb=tem>>8;
   }
   temp=tpmsb<<4&0x70;
   temp=temp|(tplsb>>4);
   display[6]=temp/100;     // 取百位数据暂存
   display[5]=temp%100/10;     // 取十位数据暂存
   display[4]=temp%100%10;;      // 取个位数据暂存
   low=tplsb&0x0f;
   switch(low)			//处理小数部分,对于12位的分辨率,以0.625和对应的数据相乘可以得出16种情况0000~1111
   {
    
      		case 0:					
			      display[3]=0;
				  break;
			case 1:					
			       display[3]=0;
				   display[2]=6;
				   display[1]=2;
				   display[0]=5;
				  break;
			case 2:					
			      display[3]=1;
				  display[2]=2;
				  display[1]=5;
				  break;
			case 3:					
			      display[3]=1;
				  display[2]=8;
				  display[1]=7;
				  display[0]=5;
				  break;
			case 4:					
			      display[3]=2;
				  display[2]=5;
				  break;
			case 5:					
			      display[3]=3;
				  display[2]=1;
				  display[1]=2;
				  display[0]=5;
				  break;
			case 6:					
			      display[3]=3;
				  display[2]=7;
				  display[1]=5;
				  break;
			case 7:					
			      display[3]=4;
				  display[2]=3;
				  display[1]=7;
				  display[0]=5;
				  break;
			case 8:					
			      display[3]=5;
				  break;
			case 9:					
			      display[3]=5;
				  display[2]=6;
				  display[1]=2;
				  display[0]=5;
				  break;
			case 10:					
			      display[3]=6;
				  display[2]=2;
				  display[1]=5;
				  break;
			case 11:					
			      display[3]=6;
				  display[2]=8;
				  display[1]=7;
				  display[0]=5;
				  break;
			case 12:					
			      display[3]=7;
				  display[2]=5;
				  break;
			case 13:					
			      display[3]=8;
				  display[2]=1;
				  display[1]=2;
				  display[0]=5;
				  break;
			case 14:					
			      display[3]=8;
				  display[2]=7;
				  display[1]=5;
				  break;
			case 15:					
			      display[3]=9;
				  display[2]=3;
				  display[1]=7;
				  display[0]=5;
				  break;
			default:break;
	}

  if(flag) 	//把负号标志放在整数最高位不是0的前一位
  {
	if(display[6]==0&display[5]!=0) display[6]=16;
	if(display[6]==0&display[5]==0&display[4]!=0) display[5]=16;
	if(display[6]==0&display[5]==0&display[4]==0) display[5]=16;
	flag=0;
  }
  	for(j=6;j>3;j--)
	{
	  if(display[j]!=0) 
	  break;
	  if(j==4) break;	//当第一个整数位为0时,此位的0显示;
	  display[j]=17;   // 使为0的数据不显示
	}
  
 } 
/*uchar * read_rom(void)
{
	uchar rom[8],i;
	TxReset();
	WrByte(0x33);
	for(i=7;i>=0;i--)
	{
		rom[i]=RdByte();
	}
	return &rom[0];
}  */

/*定时中断,显示采集的温度*/
  void t0(void) interrupt 1 using 0 
 {
    uchar i,tr;
    P2=0xff;
	if(i==4)//使第四位带有小数点
	tr=0x80;
	else 	//其他位小数点不显示
	tr=0x00;
    P0=(tr|dispcode[display[i]]);
    P2=dispbitcode[7-i];
   i++;
   if(i==8) i=0;
   TH0=(65536-2200)/256; 
   TL0=(65536-2200)%256; 
 
 }

/*主函数*/
void main(void)
{
  uchar i;	 
  TMOD=0x01; 
  TH0=(65536-2200)/256; 
  TL0=(65536-2200)%256;
  TR0=1; 
  ET0=1; 
  EA=1;
   while(1)
	{ 
	  delay(130);
	  RdTemp(get_serial+i*8);	 // 读取温度 
	  display[7]=i+10;	  //显示当前传感器的编号
	  DataChange();	//数据处理 
	  i++ ;
	  if(i==3) i=0;
	}
	
}

⌨️ 快捷键说明

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