打印

请教一个关于DS18B20如何正确读数的问题?

[复制链接]
8212|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
bmfw|  楼主 | 2009-11-19 22:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
bmfw|  楼主 | 2009-11-19 22:53 | 只看该作者
从零下40多突然到16,变化也太大了

使用特权

评论回复
板凳
smileagain| | 2009-11-19 23:42 | 只看该作者
我估计是你读出的数据没有正确解码。符号位你是怎么处理的?再看一下datasheet里的那张表吧

使用特权

评论回复
地板
xwj| | 2009-11-20 00:27 | 只看该作者
呵呵,
LZ对自己的程序太有自信了,这么相信你的读数啊?

使用特权

评论回复
5
bmfw|  楼主 | 2009-11-20 19:36 | 只看该作者
本帖最后由 bmfw 于 2009-11-25 21:35 编辑

附上有关程序,帮我看一下!
//////无符号整数转换为BCD码//////////////////////
uchar IntToBcd(unsigned char Int)
{
  uchar i,j;
  j=100;
  i=0;
  while((Int >= j) && (j>9))
    {
      Int-=j;
      i++;
    }
  j/=10;
  i=0;
  while((Int >= j) && (j>9))
    {
      Int-= j;
      i++;
    }
  return((i<<4)|(Int));
}
/////////////////////////////////////////////////
void  GetTemperature(void)
{
  uchar TempH = 0;
  uchar TempL = 0;
  uchar TempSigned  = 0;
  uchar TempHigh  = 0;
  uchar TempLow = 0;
  DS18B20_IO = 1;
  if  (DS18B20_Init())      //接收到应答脉冲
    {
      DS18B20_WriteByte(SkipRom);//0xcc发出SKIP ROM命令
      DS18B20_WriteByte(ConvertTemperature);//0x0x44发送温度转换命令
      Delay15us(50);        //等待AD转换结束
      DS18B20_Init();
      DS18B20_WriteByte(SkipRom);       //0xcc发出SKIP ROM命令
      DS18B20_WriteByte(ReadScratchpad);//0xbe发送读命令
      TempL = DS18B20_ReadByte();       //读取温度值低位字节(其中低4 位为二进制的"小数"部分)
      TempH = DS18B20_ReadByte();       //读取温度值高位字节(其中高5位为符号位)
      if (TempH^3==0) { TempSigned = 0;}//温度的符号位,0为正温度,1为负温度
      else                              //负温度
        {
          TempSigned = 1;               //温度的符号位,0为正温度,1为负温度
          TempL=256-TempL;              //负温度用补码表示,即反码加1
          TempH=255-TempH;              //也就是255-Temp+1
        }
    }
  //TempH的低四位和TempL的高四位是整数部分,TempL的低四位是小数部分
  TempHigh  = IntToBcd((TempH<<4)|(TempL>>4));
  TempLow   = IntToBcd((TempL&0x0f)*625/100);//小数部分*625/100转换成整数
}

使用特权

评论回复
6
ningling_21| | 2009-11-21 09:42 | 只看该作者
温度正负判断好像错了.

使用特权

评论回复
7
bmfw|  楼主 | 2009-11-21 20:46 | 只看该作者
昨晚测试了一下,读出的十六进制是正确的,可能是IntToBcd出了问题

使用特权

评论回复
8
bmfw|  楼主 | 2009-11-25 21:28 | 只看该作者
本帖最后由 bmfw 于 2009-11-25 21:33 编辑

再次请问一下,为什么我的程序在16度以下不能正确解码16度以上却没有问题?有关程序如下
uchar TAB_IntToBcd[]={
  0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
  0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
  0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,
  0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
  0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
  0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
  0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
  0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
  0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
  0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,};
TempL = DS18B20_ReadByte();//读取温度值低位字节(其中低4 位为二进制的"小数"部分)
TempH = DS18B20_ReadByte();//读取温度值高位字节(其中高5位为符号位)
if (TempH^3==0)   //正温度
  {
    TemSigned = 0x00; //温度的符号位,0为正温度,1为负温度
  }
else              //负温度
  {
    TemSigned = 0x01;
    TempL=256-TempL;              //负温度用补码表示,即反码加1
    TempH=255-TempH;              //也就是255-Temp+1
  }
//TempH的低四位和TempL的高四位是整数部分,TempL的低四位是小数部分
TemHigh  = TAB_IntToBcd[(TempH<<4)|(TempL>>4)];
TemLow   = TAB_IntToBcd[(TempL&0x0f)*625/100];//小数部分*625/100转换成整数

使用特权

评论回复
9
zlh6630| | 2009-12-1 17:26 | 只看该作者
我写了个在0到16度能正常测温,16度以上就跳到0了,我知道是高温数据没读到,但程序还没找到问题

使用特权

评论回复
10
bmfw|  楼主 | 2009-12-9 16:09 | 只看该作者
能把有关程序附上吗?

使用特权

评论回复
11
不亦心| | 2009-12-9 20:18 | 只看该作者
汇编的源程序要嘛

使用特权

评论回复
12
wi2c| | 2009-12-9 22:33 | 只看该作者
回去仔细读手册
DS1820很成熟
绝对没有问题
你自己完全可以搞定,你行的

使用特权

评论回复
13
znmcu| | 2009-12-18 15:33 | 只看该作者
DS18b20.c

#include "DS18b20.h"
#include "myfun.h"

/*******************************************************

        +-------------------------------------+
        |  振南电子 驱动程序模块 DS18B20 部分 |
        +-------------------------------------+

  此源码版权属 振南 全权享有,如欲引用,敬请署名并告知
        严禁随意用于商业目的,违者必究,后果自负
         振南电子
             ->产品网站 http://www.znmcu.cn/
             ->产品网店 http://shop.znmcu.cn/
             ->产品咨询 QQ:987582714
                                    MSN:yzn07@126.com
                            WW:yzn07       
                                                                          
********************************************************/

/******************************************************************
- 功能描述:DS18B20初始化
- 隶属模块:DS18B20模块
- 函数属性:外部,供用户使用
- 参数说明:无      
- 返回说明:返回值为0说明初始化成功,否则失败
- 注:初始化是正确操作DS18B20是重要一步,必须初始化成功
******************************************************************/

unsigned char DS18B20_Init()
{
unsigned char x=0;
DQ=1;       //DQ复位
delay(96);  //稍做延时
DQ=0;       //单片机将DQ拉低
delay(960); //精确延时 大于 480us
DQ=1;       //拉高总线
delay(168);
x=DQ;       //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(240);
return x;
}

/******************************************************************
- 功能描述:从DS18B20读取一个字节
- 隶属模块:DS18B20模块
- 函数属性:内部
- 参数说明:无      
- 返回说明:从DS18B20读到的字节
- 注:无
******************************************************************/

unsigned char DS18B20_ReadByte()
{
unsigned char i=0,dat=0;
for(i=0;i<8;i++)
{
  DQ=0;    //给脉冲信号
  dat>>=1;
  DQ = 1;  //给脉冲信号
  if(DQ) dat|=0x80;
  delay(48);
}
return(dat);
}

/******************************************************************
- 功能描述:向DS18B20写入一个字节
- 隶属模块:DS18B20模块
- 函数属性:内部
- 参数说明:dat:将要向DS18B20写入字节      
- 返回说明:无
- 注:无
******************************************************************/

void DS18B20_WriteByte(unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
  DQ=0;
  DQ=dat&0x01;
  delay(60);
  DQ=1;
  dat>>=1;
}
}

/******************************************************************
- 功能描述:从DS18B20中读取温度
- 隶属模块:DS18B20模块
- 函数属性:外部,供用户使用
- 参数说明:无      
- 返回说明:由于返回的温度是浮点数(即小数),为了方便返回的值将为原
             值的100倍,即精确到小数点后2位,用户需要对返回值除以100
                         得到实际的温度值
- 注:这里读取温度是以DS18B20的最高精度来读取的,即12位
******************************************************************/

unsigned int DS18B20_ReadTemperature()
{
unsigned int t=0;
DS18B20_Init();
DS18B20_WriteByte(0xcc); // 跳过读序号列号的操作
DS18B20_WriteByte(0x44); // 启动温度转换
DS18B20_Init();
DS18B20_WriteByte(0xcc); //跳过读序号列号的操作
DS18B20_WriteByte(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
((unsigned char *)&t)[1]=DS18B20_ReadByte();
((unsigned char *)&t)[0]=DS18B20_ReadByte();
return (t!=1360)?(t*6.25):0; //DS18B20有一个常见的问题,即所谓的85问题
                              //刚上电时可能读回的温度值是85,这是错误的值,应舍弃
}
DS18b20.h

#ifndef  _DS18B20_H_
#define  _DS18B20_H_

#include "reg51.h"

/*******************************************************

        +-------------------------------------+
        |  振南电子 驱动程序模块 DS18B20 部分 |
        +-------------------------------------+

  此源码版权属 振南 全权享有,如欲引用,敬请署名并告知
        严禁随意用于商业目的,违者必究,后果自负
         振南电子
             ->产品网站 http://www.znmcu.cn/
             ->产品网店 http://shop.znmcu.cn/
             ->产品咨询 QQ:987582714
                                    MSN:yzn07@126.com
                            WW:yzn07       
                                                                          
********************************************************/

sbit DQ=P1^4; //DS18B20的数据端

unsigned char DS18B20_Init();
unsigned char DS18B20_ReadByte();
void DS18B20_WriteByte(unsigned char dat);
unsigned int DS18B20_ReadTemperature();

#endif

使用特权

评论回复
14
传感时代| | 2019-9-27 22:48 | 只看该作者
可选用成品,我们专门研发了一线总线采集模块LCT2662M,还有仪表LCT2201C,可以采集常用的一线总线器件ds18b20,还有模拟量ds2438等。支持64个ds18b20同时采集。输出rs485总线,便于和电脑等终端通讯,常用于粮库粮仓测温,煤筒仓测温,水蓄冷测温等等。



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

24

主题

86

帖子

0

粉丝