hdd961140543 发表于 2012-5-20 10:56:57

发一个刚在STC12C5608AD上调通的ds18b20的程序,晶振22.1184M

首先声明程序是照搬论坛上的,但是就是调不通,我用逻辑分析仪看了波形后,原来的延时函数时间差得非常远。重新改了延时函数,才可以复位成功。
然后读操作,写操作都用逻辑分析仪看了没有问题了,还是不能成功读出温度值来。
最后仔细看了时序,才发现就是因为复位后马上紧跟的写操作太早了,导致写的前几个位没有成功写入。加了延时后读出成功!
下面是代码
//*******晶振为22.1184M***************************************************************************
static
void delay_2us(void)
{
   char i;
   for(i=10;i>0;i--);
}

static
void delay_15us(char times )
{
   char i;
   for(;times>0;times--)
           for(i=70;i>0;i--);
}



//**********************************************************************************
//初始化DS18B20
//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动
//static
bit DS18B20_reset(void)      
{
        bit x;
        DQ = 1;                                         //DQ复位
       delay_15us (3);                         //稍做延时
       DQ = 0;                                         //单片机将DQ拉低
       delay_15us(33);                         //精确延时 大于 480us
       DQ = 1;                                         //拉高总线
       delay_15us(5);                      //等待大于60us
       x = DQ;                                         //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
       return x;       
}


//读一个字节
//static
unsigned char DS18B20_read(void)
{
    unsigned char i=0;
    unsigned char dat = 0;
   
    for (i=0;i<8;i++)
    {         
      DQ = 0;               //低电平 开始时间片
                delay_2us();
                DQ = 1;                        //高电平
                delay_15us(1);
                delay_2us();
                delay_2us();
      dat>>=1;
      DQ = 1;               //高电平 DS18B20开始输出
      if(DQ)                        
      {
              dat |= 0x80;      //如果是高电平就在最高位写入1,低电平则保留原来的0
      }
      delay_15us(1);      //延时30us
    }
   
    return(dat);
}



//写一个字节
//static
void DS18B20_write(unsigned char dat)
{
    unsigned char i=0;
   
    for (i=8; i>0; i--)
    {
      DQ = 0;
      delay_15us(1);
      DQ = dat&0x01;
      delay_15us(4);
      DQ = 1;
      dat>>=1;
                _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
                _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
    }
}

//static
void DS18B20_convert( void )
{
      DS18B20_reset();
        delay_15us(20);         //*********这里一定要加延时**************
      DS18B20_write(0xCC); // 跳过读序号列号的操作
      DS18B20_write(0x44); // 启动温度转换
}

//读取温度
unsigned int get_temperature(void)
{
      unsigned char tempL=0;
      unsigned char tempH=0;
      unsigned int t=0;

      DS18B20_convert();
      DS18B20_reset();
        delay_15us(20);         //*********这里一定要加延时**************
      DS18B20_write(0xCC); //跳过读序号列号的操作
      DS18B20_write(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
      tempL=DS18B20_read();
      tempH=DS18B20_read();

      t = (tempH*256 + tempL)*0.625+0.5;

      return(t);
}
页: [1]
查看完整版本: 发一个刚在STC12C5608AD上调通的ds18b20的程序,晶振22.1184M