搜索
bottom↓
回复: 46

DS18B20温度读取有时会读出85度

[复制链接]

出0入0汤圆

发表于 2007-12-3 12:04:08 | 显示全部楼层 |阅读模式
DS18B20温度读取有时会读出85度,但是实际温度并不是这样。对于读出的数据是经过冗余校验的,这的确是18B20发出的数据,这是怎么回事呢?请各位高人指教了。

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2007-12-3 12:45:42 | 显示全部楼层
转换没有完成,或初次读取就是这样的,根据转换精度调整一下你的读取间隔时间,数据手册上好像有,发送转换命令后延时多少时间再读取

出0入0汤圆

发表于 2007-12-3 12:48:35 | 显示全部楼层
一般只有上电的时候才会这样的~我的做法是上电后2~3秒后才开始采集温度~

出0入0汤圆

发表于 2007-12-3 13:09:56 | 显示全部楼层
12位的时候需要750ms转换才完成,多做点事情再去读取吧

出0入4汤圆

发表于 2007-12-3 15:53:16 | 显示全部楼层
2楼的和我的遭遇一样,我也是这么处理的

出0入0汤圆

 楼主| 发表于 2007-12-4 13:23:20 | 显示全部楼层
我的温度采集是先转换,等主程序循环完一次(程序比较大)后再读取温度值,看完各位的回复。我想虽然程序比较大,但也有很多子程序不执行的时候,这时候转换时间可能就不够用了。我先加些延时看看,谢谢各位。

出0入0汤圆

发表于 2007-12-4 16:37:56 | 显示全部楼层
/*********************************************************************************************************
**定义引脚,用M16 PORTC.3 连接 DS18B20 2脚,模拟 1总线获取温度值   
********************************************************************************************************/     
#define  DQ_18B20       (1<<3)                // PC3,指定引脚
#define  DQ_TO_0()      (DDRC |=  DQ_18B20)   // PC3='0'
#define  DQ_TO_1()      (DDRC &= ~DQ_18B20)   // PC3='float'
#define  DQ_status()    (PINC & DQ_18B20)     // read PC3 pin


/*********************************************************************************************************
** 函数名称:ds18b20_config
** 功能描述:配置(使能)AVR与DS18B20的接口      
** 输 入:  无
** 输 出:  无
** 范  例: ds18b20_config(void);
********************************************************************************************************/
void ds18b20_config(void)
{  
    DDRC  &= ~DQ_18B20;   // 输入模式(上电时为高电平)
    PORTC &= ~DQ_18B20;   // 输出锁存器写0,以后不再更改
}  


/*********************************************************************************************************
** 函数名称:ds18b20_reset
** 功能描述:复位1-wire总线,并探测是否有温度芯片DS18B20(TO-92)
*  有返回1,没有返回0   
** 输 入:  无
** 输 出:  1或0
** 范  例: ds18b20_reset(void);
********************************************************************************************************/
unsigned char ds18b20_reset(void)
{   
    bit bus_flag;   //定义标记变量
    DQ_TO_0();      // 设置1-wire总线为低电平(占领总线)...
    delay_us(480);  // 延迟490us~960us, 与硬件密切相关,但应尽可能选小值(480us),把抖动留给系统(比如在延迟期间发生中断导致延迟变长)。
    #asm ("cli")    // 下面这段时间要求比较严格,为保险起见,关中断
    DQ_TO_1();      // 设置1-wire总线为高电平(释放总线)
    delay_us(67);  // 15至60US,最佳时间: 60us+7.5us!(忙延时,只是一种策略)
    if (DQ_status() )   // 探测总线上是否有器件     
    {
        bus_flag=0;   // 复位单总线但没有发现有器件在线
    }
    else
    {
        bus_flag=1;   // 复位单总线并发现有器件在线
    }
    #asm ("sei")         // 退出临界代码区(开中断)
   
    /* 保证Master(主机)释放总线的时间(不是说总线处于高电平的时间)不小于
       480us即可,这一时间从读总线状态之前就开始了,所以这里把这个
       时间计算在内。在Master释放总线的前半段,也是被动器件声明它
       们在线之时。
     */
    delay_us(490-67);   // 490-67.5us
    return(bus_flag);
}  
         

/*********************************************************************************************************
** 函数名称:ds18b20_write
** 功能描述:写命令或数据到温度芯片DS18B20(发送一个字节)
** 输 入:  dat
** 输 出:  无
** 范  例: ds18b20_write(dat);
********************************************************************************************************/
void ds18b20_write(unsigned char dat)
{
    unsigned char count;
    for (count=0;count<8;count++) // 每个字节共8位,一次发一位
    {
        #asm ("cli")              // 保证绝对不会发生中断!
        DQ_TO_0();                // 设置1-wire总线为低电平
        delay_us(2);              // 延迟 2us   
        if (dat & 0x01)           // 并串转换,先低位后高位
        {
            DQ_TO_1();            // 如该位是1,释放总线,由上拉电阻输出高电平
        }  
        else
        {
            DQ_TO_0();            //否则,输出第电平
        }
        dat >>= 1;                // 右移,下一位做好准备
        delay_us(62);              // 延迟62us,(60us~120us实际不能到120us, 因为其它语句也用时间了!)
        DQ_TO_1();                // 释放总线,由上拉电阻输出高电平
        delay_us(2);               // 2us
        #asm ("sei")              // 恢复系统中断
    }
}  

  
/*********************************************************************************************************
** 函数名称:ds18b20_read
** 功能描述:从温度芯片DS18B20读配置或数据(接收一个字节)
** 输 入:  无
** 输 出:  dat
** 范  例: ds18b20_read();
********************************************************************************************************/
unsigned char ds18b20_read(void)
{
    unsigned char count,dat;
    dat = 0x00;        // 数据接收准备
    for(count=0; count<8; count++)  // 每个字节共8位,一次收一位
    {      
        #asm ("cli")     // 保证绝对不会发生中断!
        DQ_TO_0();     // 设置1-wire总线为低电平(拉低总线以同步),从总线拉低到读总线状态,不能大于15us!
        delay_us(2);   // 2us
        DQ_TO_1();     // 设置1-wire总线为高电平(释放总线)
        delay_us(4);   // 4us         
        dat >>= 1;     // 右移一位
        if (DQ_status()) dat|=0x80;   // 读取总线电平,先收低位再收高位
        #asm("sei")      // 恢复系统中断
        delay_us(62);   // 必须大于60us
    }
    return(dat);
}  


/*********************************************************************************************************
** 函数名称:convert_T
** 功能描述:向DS18B20发出启动温度转换指令 (发送一个字节0x44)。
**     本电路中只有一个器件DS18B20,所以不需要多个器件的ID识别,
**     跳过之后,启动温度转换,但在启动后,用户应等待几百个
**     毫秒(>750ms),才能读到这次的转换值,
** 输 入:  无
** 输 出:  无
** 范  例: convert_T();
********************************************************************************************************/
void convert_T(void)
{
    if (ds18b20_reset())
    {                            // 如果复位成功
        ds18b20_write(0xcc);     // 发送跳过多器件识别指令
        ds18b20_write(0x44);     // 发送启动温度转换指令
    }
}  

/*********************************************************************************************************
** 函数名称:read_T
** 功能描述:读取并计算转换后的温度值。向DS18B20发出读取温度值指令(发送一个字节0xbe)。
**     假定DS18B20一定是正确的,所以没有返回有关状态。当你故意把DS18B20从电路
**     中拔下而能让程序告诉你出错时,你可以自己修改这段代码!  
** 输 入:  无
** 输 出:  无
** 范  例: read_T();
********************************************************************************************************/
void read_T(void)
{   
    //unsigned int  value=0;     //定义初值
    unsigned char MSB;           //温度高字节
    unsigned char LSB;           //温度低字节
    unsigned long int t1=0;      //温度整数部分数值
    unsigned short int t2=0;     //温度小数部分数值
    //bit   wendu_flag;          //负温度标志
     
    if (ds18b20_reset())
    {                            // 如果复位成功
        ds18b20_write(0xcc);     // 跳过多器件识别
        ds18b20_write(0xbe);     // 读暂存器
        LSB=ds18b20_read();      // 低字节         
        MSB=ds18b20_read();      // 高字节
        //value  = (int)ds18b20_read();       // 低字节
        //value += (int)(ds18b20_read())<<8;  // 高字节
        //高字节的前5位是符号,温度大于0,这5位为0,值乘0.0625即得实际温度.温度小于0,这5位为1,数值取反加1再乘0.0625即得实际温度  
        if ( (MSB & 0xF0)>0 )   //判断是否为负温度(高字节前四位是否为1)
        {                     
            wendu_flag=1;       //置位,是负数
        }
        else
        {
            wendu_flag=0;       //清标记,是正数
        }
        if (wendu_flag)               //如果为负温度取反加1
        {                       
            MSB=~MSB;           //高位取反
            LSB=~LSB+1;         //低位取反
        }
        t1 = MSB<<4;            //得到温度整数部分
        t1 |= (LSB>>4);
        t2 = (LSB & 0x0F)*0.0625*10000; //得到温度小数部分并扩大10000倍
        //计算各位数码管要显示的数值
        //if(wendu_flag) //温度百位
        //{
        //    Bit[1]=10; //如果为负温度则显示"-"
        //}
        //else
        //{
        //    Bit[1]=t1/100;  //温度百位
        //}
        //Bit[2]=t1%100/10;   //温度十位
        //Bit[3]=t1%10;       //温度个位
        time[0]=(t1%100);     //温度整数(2位)
        //Bit[4]=t2/1000;     //第一位小数
        //Bit[5]=t2%1000/100; //第二位小数
        //time[0]=(t2/1000)+(t2%1000/100);      //温度小数(2位)
        //Bit[6]=t2%100/10;   //第三位小数
        //Bit[7]=t2%10;       //第四位小数
    }
}  
-------------------------------
这是论坛里的,我以在M16调试通过。主要是在主函数里调用。

main
{
.....
    #asm("sei")
   
while (1)
{     
..........
//我用了马老师的状态机,不用在白等750ms...好多教程里都是delay_ms(),害人的!!!!!
5秒到,ds18b20_state=1,在中断里++time_750ms计时(ds18b20_state=2),到了750ms在执行read_T();

        if (ds18b20_state)          //5秒到,进入测温状态1
        {
            switch (ds18b20_state)          //状态0:待命,状态1:发转换命令,状态2:读取温度值
            {
                case 1:                     //5秒到
                     ds18b20_state=2;       //进入下个状态     
                     time_750ms=0;          //清750ms计时器
                     convert_T();           //向ds18b20发出转换温度命令
                     break;
                case 2:
                     if (time_750ms>=75)    //延时750ms,等待温度转换命令执行完毕
                     {                        
                         ds18b20_state=0;   //完成温度检测,返回状态0
                         time_750ms=0;      //清750ms计时器
                         read_T();          //获取温度值
                     }
                     break;
            }
        }

.....
}

出0入0汤圆

发表于 2008-5-4 23:15:44 | 显示全部楼层
我做两个的,但是一个正常测出,另一个却始终是85.0000

出0入8汤圆

发表于 2008-5-4 23:50:01 | 显示全部楼层
如果你的一直是85度 说明你的18b20 完完了   应该是你把正负接反了 不小心把他烧坏了

出0入46汤圆

发表于 2008-5-5 00:42:27 | 显示全部楼层
我也调试通过了,正在用呢!

/**************************************
*filename : ds18b20.h
*function :
*author   :
*date     :
***************************************/
#ifndef _DS18B20_H_
#define _DS18B20_H_

#include<avr/io.h>
#include<avr/delay.h>
#include<avr/interrupt.h>

#ifndef  CPU_CRYSTAL_18B20
#define  CPU_CRYSTAL_18B20    (4)
#endif

#define  INT8U  unsigned char
#define  INT16U unsigned int
#define  SUCC   1
#define  wait_us(us)  _delay_loop_2((INT16U)((us)*CPU_CRYSTAL_18B20/4))

#define  DQ_18B20_PORT  PORTD                                  // PORTD
#define  DQ_18B20_DDR   DDRD                                  // DDRD
#define  DQ_18B20       (1<<PD5)              // PD5
#define  DQ_TO_0()      (DDRD |=  DQ_18B20)   // PD5='0'
#define  DQ_TO_1()      (DDRD &= ~DQ_18B20)   // PD5='float'
#define  DQ_status()    (PIND & DQ_18B20)     // read PD5 pin

/*---------------- 函数原型声明 ------------------*/
// 1个初始化模块
void ds18b20_config(void);         // 配置端口

// 3个基本模块
unsigned char ds18b20_reset(void); // 复位DS18B20
void ds18b20_write(INT8U dat);     // 写字节到DS18B20
INT8U ds18b20_read(void);          // 读字节从DS18B20

// 2个应用模块
void   convert_T(void);            // 启动温度转换
INT16U read_T(void);               // 读取转换值

/*-------------------------------------------------------
*  配置(使能)AVR与DS18B20的接口
*/
void ds18b20_config(void)
{
    DQ_18B20_DDR  &= ~DQ_18B20;   // 输入模式(上电时为高电平)
    DQ_18B20_PORT &= ~DQ_18B20;   // 输出锁存器写0,以后不再更改
}

/*-------------------------------------------------------
*    复位1-wire总线,并探测是否有温度芯片DS18B20(TO-92
*  封装)挂在总线上,有返回SUCC,没有返回FAIL
*/
unsigned char ds18b20_reset(void)
{
    unsigned char bus_flag=0;

    DQ_TO_0();      // 设置1-wire总线为低电平(占领总线)...

    /* 现在延迟480us~960us, 与硬件密切相关,但应尽可能选小值(480us),
       把抖动留给系统(比如在延迟期间发生中断导致延迟变长)。
     */
    wait_us(490);   // 490us

    cli();          // 下面这段时间要求比较严格,为保险起见,关中断
    DQ_TO_1();      // 设置1-wire总线为高电平(释放总线)
   
    /* 这个浮点数是由编译器计算好的,而不是由你的MCU在运行时临时计算的,
       所以不会占用用户MCU的时间,不必担心(看看前面的宏你就可以确定了)
     */
    wait_us(67.5);  // 最佳时间: 60us+7.5us!(忙延时,只是一种策略)
   
    // 探测总线上是否有器件   
    if(DQ_status()) bus_flag=0;   // 复位单总线但没有发现有器件在线
    else bus_flag=1;              // 复位单总线并发现有器件在线
   
    sei();          // 退出临界代码区(开中断)

    /* 保证Master释放总线的时间(不是说总线处于高电平的时间)不小于
       480us即可,这一时间从读总线状态之前就开始了,所以这里把这个
       时间计算在内。在Master释放总线的前半段,也是被动器件声明它
       们在线之时。
     */
    wait_us(490-67.5);   // 490-67.5us

    return(bus_flag);
}

/*--------------------------------------------------------
*  写命令或数据到温度芯片DS18B20(发送一个字节)
*/
void ds18b20_write(INT8U dat)
{
    INT8U count;

    // 每个字节共8位,一次发一位
    for(count=0; count<8; count++) {
        cli();                   // 保证绝对不会发生中断!
        DQ_TO_0();               // 设置1-wire总线为低电平
        wait_us(2);              // about 2us
        
        if(dat&0x01) DQ_TO_1();  // 并串转换,先低位后高位
        else DQ_TO_0();
        dat >>= 1;               // 下一位做好准备
        
        // 60us~120us(实际不能到120us, 因为其它语句也用时间了!)
        wait_us(62);             // 62us
        
        DQ_TO_1();
        sei();                   // 恢复系统中断
        wait_us(2);              // 2us
    }
}

/*---------------------------------------------------------
*  从温度芯片DS18B20读配置或数据(接收一个字节)
*/
INT8U ds18b20_read(void)
{
    INT8U count,dat;

    dat = 0x00;       // 数据接收准备
   
    // 每个字节共8位,一次收一位
    for(count=0; count<8; count++) {
        cli();        // 保证绝对不会发生中断!
        
        // 从总线拉低到读总线状态,不能大于15us!
        DQ_TO_0();    // 设置1-wire总线为低电平(拉低总线以同步)
        wait_us(2);   // 2us
        DQ_TO_1();    // 设置1-wire总线为高电平(释放总线)
        wait_us(4);   // 4us        
        dat >>= 1;
        if(DQ_status()) dat|=0x80;   // 读取总线电平,先收低位再收高位
        
        sei();        // 恢复系统中断
        wait_us(62);  // 必须大于60us
    }
    return(dat);
}

/*-------------------------------------------------------
*     我的电路中只有一个器件DS18B20,所以不需要多个器件的ID
*  识别,跳过之后,启动温度转换,但在启动后,用户应等待几百个
*  毫秒,才能读到这次的转换值,这是DS18B20的数据手册规定的。
*  因为温度转换是需要时间的嘛!(^_^)
*/
void convert_T(void)
{
    if(ds18b20_reset()==SUCC) {  // 如果复位成功
        ds18b20_write(0xcc);     // 跳过多器件识别
        ds18b20_write(0x44);     // 启动温度转换
    }
}

/*-------------------------------------------------------
*  读取转换后的温度值
*  我假定DS18B20一定是正确的,所以没有返回有关状态。当你故意
*  把DS18B20从电路中拔下而能让程序告诉你出错时,你可以自己修
*  改这段代码!
*/
INT16U read_T(void)
{
    INT16U value=0;
   
        convert_T();//需要手动测量时可以单独写
       
    if(ds18b20_reset()==SUCC)
        {                             // 如果复位成功
        ds18b20_write(0xcc);     // 跳过多器件识别
        ds18b20_write(0xbe);     // 读暂存器
        value  = (INT16U)ds18b20_read();       // 低字节
        value += (INT16U)(ds18b20_read())<<8;  // 高字节
                return(value);
    }
        else
        {
            return(0xFFF);
        }
   
}

#endif

出0入0汤圆

发表于 2008-5-5 01:34:06 | 显示全部楼层
感觉18B20挺耐用的,我的接反过几次,都是它很烫才发现的,现在还又能够得好好的

出0入0汤圆

发表于 2008-5-5 08:05:30 | 显示全部楼层
我的不是显示85度,而是老显示25度,尽管室温才不到20度,为什么呢?

出0入0汤圆

发表于 2008-5-5 09:01:40 | 显示全部楼层
#include "msp430f1232.h"
#include "HardWare.h"
#include "main.h"


float         Temper=0.0;
unsigned char Error = 0;
//-----------------------------------
//功能:写18B20
//-----------------------------------
void Write_18B20(unsigned char n)
{
unsigned char i;
for(i=0;i<8;i++)
   {
    DATA_LO;
    delay(6);//总延时14us 左右
    if((n&0x01)==0x01)
      {
       DATA_HI;
      }
    else
      {
       DATA_LO;
      }
    n=n>>1;
    delay(33);//延时55us 以上
    DATA_HI;
    delay(1);
   }
_NOP();
}
//------------------------------------
//功能:读取18B20
//------------------------------------
unsigned char Read_18B20(void)
{
unsigned char i;
unsigned char temp;
i=0;
for(i=0;i<8;i++)
   {
    temp=temp>>1;
    DATA_LO;
    _NOP();_NOP();_NOP();_NOP();_NOP();//延时1us
    DATA_HI;
    DATA_IN;
    //_NOP();_NOP();_NOP();
    //_NOP();_NOP();_NOP();
    //_NOP();_NOP();_NOP();
    //_NOP();_NOP();_NOP();
    //_NOP();_NOP();_NOP();
    //_NOP();//延时5us
    delay(2);//延时8us
    if(DATA_STATE)
     {
      temp |= 0x80;
     }
    else
     {
      temp &= 0x7F;
     }
    delay(33); //延时55us
    DATA_OUT;
    DATA_HI;
    delay(1);
   }
return temp;
}
//-----------------------------------
void Init18b20 (void)
{
DATA_LO;
delay(340);//延时500us
DATA_IN;
delay(60);//延时90us
if(DATA_STATE)
  {
   Error =1;    //失败1
  }
else
  {
   Error = 0;//初始化成功
  }
delay(50);//等待DS18B20驱动总线低电平完成
DATA_HI;
DATA_OUT;
delay(5);//初始化完成后的空间隙
}
void ReadTemp (void)
{
unsigned char temp_low,temp_high; //温度值
signed int    temperature=0;
temp_low=Read_18B20(); //读低位
temp_high=Read_18B20(); //读高位
temperature=temp_high;
temperature<<=8;
temperature|=temp_low;
Temper=temperature*0.0625;
}
/*void Config18b20(void)  //重新配置报警限定值和分辨率
{
Init18b20();
Write_18B20(0xcc);  //skip rom
Write_18B20(0x4e);  //write scratchpad
Write_18B20(0x00);  //上限
Write_18B20(0x00);  //下限
Write_18B20(0x3f);  //set10bit(分辨率0.25)
Init18b20();
Write_18B20(0xcc);  //skip rom
Write_18B20(0x48);  //保存设定值
Init18b20();
Write_18B20(0xcc);  //skip rom
Write_18B20(0xb8);  //回调设定值
}*/

void GetTemp(void)
{
//Config18b20();
Init18b20();
Write_18B20(0xcc);//SKIP ROM
Write_18B20(0x44);//CONVERT
delay(0xffff);delay(0xffff);delay(6553);
delay(0xffff);delay(0xffff);delay(6553);
delay(0xffff);delay(0xffff);delay(6553);
delay(0xffff);delay(0xffff);delay(6553);
delay(0xffff);delay(0xffff);delay(6553);
//延时920ms以上,等待12BIT转换完成
Init18b20();
Write_18B20(0xcc);//SKIP ROM
Write_18B20(0xbe);//读取缓存命令
ReadTemp();
}

出0入0汤圆

发表于 2008-6-10 15:55:26 | 显示全部楼层
我用的也是本贴内的驱动程序,但18b20老显示显示85度,我已经在上电几十秒后才读的啊,芯片也没有发烫,没有接反.这到底是怎么回事啊?

出0入0汤圆

发表于 2008-6-10 16:08:42 | 显示全部楼层
我的开电85 偶尔还出现0 呢,不知道怎么回事情哦


(原文件名:photo0170.JPG)

出0入0汤圆

发表于 2008-6-10 16:59:56 | 显示全部楼层
不着急。。慢慢来额,要不换个18B20试试

出0入0汤圆

发表于 2008-6-10 17:36:50 | 显示全部楼层
我的成功了,不显示85度了,可以正常显示温度了。原因是我参考了网上程序太多了,大杂汇,多加了不该加的函数.

本贴内的程序还是挺好的,很不错

出0入0汤圆

发表于 2008-6-10 18:05:08 | 显示全部楼层
本公司的量产产品!
24路温度采集器:
上电,用上位机开始重复读(800ms一次,这时还没接12B20)
首先是0
然后是85
然后就是65535

..............

再把24个28B20接上
先是十几度
然后二十几
然后稳定为气温!

出0入0汤圆

发表于 2008-6-10 18:13:26 | 显示全部楼层
哈哈,我用的内部晶振, 开机出现一次85 后恢复正常,偶尔出现0

出0入0汤圆

发表于 2009-5-2 21:40:40 | 显示全部楼层
请问8楼

如果18B20因为电源接反烧坏了,仅仅会出现读出全为85度,其它读出都正常吗?
初始化是对的,读ROM也是对的,最后一字节是28h

出130入129汤圆

发表于 2009-5-2 21:44:09 | 显示全部楼层
85度原因是程序没写对,一些时序操作问题,不是坏的原因。

出0入0汤圆

发表于 2009-5-2 21:53:12 | 显示全部楼层
借贴问一下,好像改过参数(比如分辨率)后初始就不是85了,有95之类的?

出0入0汤圆

发表于 2009-5-2 22:17:58 | 显示全部楼层
我的改了分辨率后仍然是85度

出0入0汤圆

发表于 2009-5-2 22:24:31 | 显示全部楼层
P5.5为DQ口

uint Rd_Temp(void){
uchar a=0;
uchar b=0;
uint  t=0;
a=Init_DS18B20();
if(a!=0)
   str_disp(t_err,0x00,0x00,0x0B);
a=Init_DS18B20();
wr_char(0xCC); //skip Device ID
wr_char(0x44); //start T conversion
delay(253);
a=Init_DS18B20();
if(a==0){
  wr_char(0xCC); //skip Device ID
  wr_char(0xBE); //read T
  a=rd_char();
  b=rd_char();
  t=b;
  t<<=8;
  t=t|a;
  return(t);
}
else{
  str_disp(t_err,0,16,11);
  return(t=0);
}
}



uchar rd_char(void){
uchar t_i=0;
uchar t_dat=0;
for(t_i=8;t_i>0;t_i--){
    clr_DQ; //
    t_dat>>=1;
    set_DQ; //
    delay(35);
    if(P5&0x20)
      t_dat|=0x80;
    delay(243);
    delay(48);
    }
return(t_dat);
}

void wr_char(uchar t_data){
uchar t_i=0;
for (t_i=8;t_i>0;t_i--){
      clr_DQ;
      if(t_data&0x01)
          P5|=0x20;
        else
          P5&=0xDF;      
      delay(253);
      set_DQ;
      t_data>>=1;
}
}


uchar Init_DS18B20(void){
uchar x=0;
set_DQ;    //DQ reset
delay(50);
clr_DQ;   
delay(243); //delay 480us
delay(243);
delay(243);
delay(243);
delay(200);
set_DQ;   
delay(175);
x=P5&0x20;  //x=0,reset OK,else need reset
delay(243);
delay(243);
delay(243);
delay(243);
delay(57);
return(x);
}

这是我的部分程序,延时程序进入和退出耗时1.04微秒,延时函数内每减一耗时0.407微秒
都是按照器件的英文应用笔记上的程序改写的

哪位有时间麻烦看一下

出0入0汤圆

发表于 2009-5-7 11:09:50 | 显示全部楼层
感谢6楼的程序

出0入0汤圆

发表于 2009-5-18 18:14:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-19 08:30:32 | 显示全部楼层
上电后要过一段时间,再读,还有就是,上电的时候,如果是85,就不显示好了

出0入0汤圆

发表于 2009-6-23 13:26:03 | 显示全部楼层
如何修改分辨率啊?

出0入0汤圆

发表于 2009-6-24 16:48:14 | 显示全部楼层
我也碰到过类似的问题
【26楼】 sjh00213 宋宋
不错的方法

出0入0汤圆

发表于 2009-8-5 13:35:58 | 显示全部楼层
我的做法是上电后先读一次,但是不显示。

出0入0汤圆

发表于 2010-2-26 00:23:03 | 显示全部楼层
留个记号

出0入0汤圆

发表于 2010-6-18 21:53:27 | 显示全部楼层
我的也是吖上电会有85出现,但一下就回到正常了,如果把数据处理和显示函数都写成同一个函数的话就没有85出现,但我的加了报警和按键程序又有上电就有85出现一下,还算正常吧,偶尔会有个67出再的报警一下,我也不知道问题出在哪里啊!

出0入0汤圆

发表于 2010-10-24 15:18:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-11 21:27:32 | 显示全部楼层
收藏。

出0入0汤圆

发表于 2011-10-6 13:18:55 | 显示全部楼层
顶!

出0入0汤圆

发表于 2012-2-10 05:23:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-11 20:50:17 | 显示全部楼层
我刚做出来了,总显示85度的原因可分为两种情况:1、芯片坏了(我就是那样的,换了块,马上就出来了)。2、采集温度函数中的延时不够,我差不多是用了750ms左右。1s,2s我试了,都行。

出0入0汤圆

发表于 2013-4-15 00:05:48 | 显示全部楼层
今天太晚了,明天再细细看看程序,老是会跳到0 。。还在debug

出0入0汤圆

发表于 2013-5-29 11:59:11 | 显示全部楼层
mark 下                                 

出0入0汤圆

发表于 2013-7-17 09:05:43 | 显示全部楼层
要注意的是执行转换命令后,一定要等待750ms以上,才能读出正确的数据,
还有问题就有可能是上拉电阻的问题了。

出0入0汤圆

发表于 2014-6-13 13:44:35 | 显示全部楼层
18b20测温,参考!

出0入0汤圆

发表于 2014-6-13 15:40:14 | 显示全部楼层
我早调通了

出0入0汤圆

发表于 2014-8-3 17:11:43 | 显示全部楼层
为什么我用逻辑分析仪打出来发的0xcc、0xbe指令是对的,而0xcc就不对,首次转换的时间也大于750ms,怎么回事

出0入0汤圆

发表于 2014-10-17 11:06:32 | 显示全部楼层
参考下,注释比较清楚

出0入0汤圆

发表于 2014-11-18 16:29:46 | 显示全部楼层
mark............

出0入8汤圆

发表于 2014-11-18 16:34:00 | 显示全部楼层
DS18B20 mark

出0入0汤圆

发表于 2014-11-18 17:26:50 | 显示全部楼层
这么老的帖子都翻出来了,呵呵,相信电工们看到显示屏上的85℃都会 会心的一笑
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 04:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表