#include<reg51.h> 
#include<intrins.h> 
#define uint unsigned int 
#define uchar unsigned char         
sbit DQ=P1^3; 
sbit dula=P2^2; 
sbit wela=P2^3; 
uchar DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; 
uchar WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};  
uint ReadTempFlag; 
uchar TempData[8]; 
/******************************************* 
          uS延时函数,大致延时 
          长度 T=uS  
*******************************************/ 
void Delay800us()                //@11.0592MHz 
{ 
        unsigned char i, j; 
 
        _nop_(); 
        _nop_(); 
        _nop_(); 
        i = 9; 
        j = 151; 
        do 
        { 
                while (--j); 
        } while (--i); 
} 
 
void Delay100us()                //@11.0592MHz 
{ 
        unsigned char i, j; 
 
        _nop_(); 
        _nop_(); 
        i = 2; 
        j = 15; 
        do 
        { 
                while (--j); 
        } while (--i); 
} 
 
void Delay10us()                //@11.0592MHz 
{ 
        unsigned char i; 
 
        _nop_(); 
        i = 25; 
        while (--i); 
} 
void Delay10ms()                //@11.0592MHz 
{ 
        unsigned char i, j; 
 
        i = 108; 
        j = 145; 
        do 
        { 
                while (--j); 
        } while (--i); 
} 
 
/******************************************* 
函数名称:Init_18B20 
功    能:对DS18B20进行复位操作 
参    数:无 
返回值  :初始化状态标志:1--失败,0--成功 
********************************************/ 
bit Init_DS18B20() 
{ 
        bit Error; 
        DQ=1; 
        Delay10us(); 
        DQ=0; 
        Delay800us();  
        DQ=1; 
        Delay100us(); 
        Error=DQ; 
        Delay10us(); 
        Delay10us(); 
        Delay10us(); 
        Delay10us(); 
        Delay10us(); 
        return Error; 
} 
 
/******************************************* 
函数名称:Write_18B20 
功    能:向DS18B20写入一个字节的数据 
参    数:wdata--写入的数据 
返回值  :无 
********************************************/ 
void Write_DS18B20(uchar Wdat) 
{ 
        uint i; 
        for(i=0;i<8;i++) 
        { 
                DQ=0;  
                DQ=Wdat&0x01; 
                Delay10us(); 
                Delay10us(); 
                //Delay10us();                                //        ???? 
                //Delay10us();  
                //Delay10us(); 
                DQ=1; 
                Wdat>>=1;         
        }   
} 
 
/******************************************* 
函数名称:Read_18B20 
功    能:从DS18B20读取一个字节的数据 
参    数:无 
返回值  :读出的一个字节数据 
********************************************/ 
uchar Read_DS18B20() 
{ 
        uint i; 
        uchar Rdat=0; 
        for(i=0;i<8;i++) 
        {         
                DQ=0;                 
                Rdat>>=1; 
                DQ=1; 
                if(DQ) Rdat|=0x80; 
                Delay10us(); 
                Delay10us(); 
                Delay10us(); 
                Delay10us(); 
                Delay10us(); 
        } 
        return Rdat; 
} 
/******************************************* 
函数名称:Skip 
功    能:发送跳过读取产品ID号命令 
参    数:无 
返回值  :无 
********************************************/ 
void Skip(void) 
{ 
    Write_DS18B20(0xcc); 
} 
/******************************************* 
函数名称:Convert 
功    能:发送温度转换命令 
参    数:无 
返回值  :无 
********************************************/ 
void Convert(void) 
{ 
    Write_DS18B20(0x44); 
} 
/******************************************* 
函数名称:Read_SP 
功    能:发送读ScratchPad命令 
参    数:无 
返回值  :无 
********************************************/ 
void Read_SP(void) 
{ 
    Write_DS18B20(0xbe); 
} 
/******************************************* 
 
                功能:控制DS18B20完成一次温度转换 
                返回测量的温度数 
 
********************************************/ 
uint DS18B20_Convert() 
{ 
        uint TempL,TempH,Temp; 
        Init_DS18B20(); 
        Skip(); 
        Convert();         
        Delay10ms();         
        Init_DS18B20(); 
        Skip(); 
        Read_SP(); 
        TempL=Read_DS18B20(); 
        TempH=Read_DS18B20(); 
        TempH<<=8; 
        Temp=TempH+TempL; 
        return Temp; 
} 
void main() 
{ 
        uint Tt; 
        float f_Tt; 
        TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                      
        TH0=(65536-2000)/256;              //给定初值 
        TL0=(65536-2000)%256; 
        EA=1;            //总中断打开 
        ET0=1;           //定时器中断打开 
        TR0=1;           //定时器开关打开 
        while(1) 
        { 
                if(ReadTempFlag==1) 
                { 
                    ReadTempFlag=0; 
                        Tt=DS18B20_Convert(); 
                        if(Tt&0x8000)                           //为负数时 
                        { 
                                TempData[0]=0x40; 
                                Tt=~Tt; 
                                Tt+=1;         
                        } 
                        else 
                                TempData[0]=0; 
                 
                        /*TtH=Tt>>4; 
                        TtL=Tt&0x0f; 
                        //TtL=TtL*6/10; 
                 
                        if(TtH/100==0) 
                            TempData[1]=0; 
                    else 
                                TempData[1]=DuanMa[TtH/100]; 
 
                        TempData[2]=DuanMa[(TtH%100)/10];           //十位 
                        TempData[3]=DuanMa[(TtH%100)%10]|0x80;   //个位 
                 
                        TempData[4]=DuanMa[TtL/10]; 
                        TempData[5]=DuanMa[TtL%10]; 
                        TempData[6]=0x3f;;                                */ 
                         
                        f_Tt=Tt*0.0625; 
                        f_Tt=f_Tt*100+0.5; 
                        Tt=f_Tt; 
 
                        TempData[1]=DuanMa[Tt/10000];                   //百位 
 
                        TempData[2]=DuanMa[(Tt%10000)/1000];           //十位 
                        TempData[3]=DuanMa[(Tt%1000)/100]|0x80;   //个位 
                 
                        TempData[4]=DuanMa[(Tt%100)/10];                   //十分位 
                        TempData[5]=DuanMa[Tt%10];                                   //百分位 
                        TempData[6]=0x3f;;                 
                                           
                 
                        TempData[7]=0x39;         //显示C符号 
            } 
                 
        } 
} 
 
void Display(uchar Num) 
{ 
      static uchar i=0;                                  //???           改成uchar i;也行 
           
      wela=1; 
          P0=WeiMa; 
          wela=0; 
 
      dula=1; 
          P0=TempData; 
          dula=0; 
        
          i++; 
      if(i==Num) i=0; 
} 
void Timer0_isr(void) interrupt 1  
{ 
        uint  num; 
        TH0=(65536-2000)/256;                  //重新赋值 2ms 
        TL0=(65536-2000)%256; 
         Display(8);       // 调用数码管扫描 
        num++; 
    if(num==300)         
    { 
            num=0; 
            ReadTempFlag=1; //读标志位置1 
        } 
}
 |