搜索
bottom↓
回复: 16

DS18B20读温度时偶尔出现错误值

[复制链接]

出0入0汤圆

发表于 2013-3-9 20:30:05 | 显示全部楼层 |阅读模式
曾经编写的DS18B20程序原来一切正常,但是最近拿来用时发现偶尔会出现数据错误,例如正常室温20度,但是偶尔会出现负值或很高的温度,怀疑新购的DS18B20时序参数同上批有点差别,有遇到过这种情况的吗?大家在使用DS18B20时是读出全部9个自己并用CRC进行校验吗?请大家指教。

晶振频率11.0592MHz,AT89C52,我的代码如下:

unsigned char DS18B20_ReadByte()
{
  unsigned char i, dat=0;

  for(i=0; i<8; i++)
  {
    dat >>= 1;
    //开始另一个读周期前必须有1us以上的高电平恢复期
    DQ = 1;
    Delay2us();
    //产生读起始信号,数据线保持在低电平至少1μs,DS18B20在总线下降沿后输出15us的有效数据
    DQ = 0;
    Delay2us();
    DQ = 1;
    Delay8us();
    if(DQ) dat |= 0x80;
    //延时60us以上来满足DS18B20的时序
    Delay65us();
  }
  
  return dat;
}

/****************************************************************************************************************************************************
* 对总线上唯一的DS18B20进行温度转换及读取,返回带符号整形值。计算温度时需要乘以0.0625,如果出错返回值为200℃,超过其测温范围
*****************************************************************************************************************************************************/
int DS18B20_GetTemperature(void)
{
  unsigned char i, tempL, tempH;
  
  //温度转换  
  if(!DS18B20_Reset()) return 0x0C80;
  DS18B20_WriteByte(0xCC); //跳过ROM
  DS18B20_WriteByte(0x44); //进行温度转换
  //等待温度转换结束
  for(i=0; i<200; i++)
  {
    if(DS18B20_ReadByte() == 0xFF) break;
    Delay5ms();
  }

  //读取温度
  if(!DS18B20_Reset()) return 0x0C80;
  DS18B20_WriteByte(0xCC); //跳过ROM
  DS18B20_WriteByte(0xBE); //读寄存器
  tempL = DS18B20_ReadByte(); //先读低8位数据
  tempH = DS18B20_ReadByte(); //再读高8位数据
  DS18B20_Reset(); //通过再次复位中断读取  

  return (tempH<<8)|tempL;
}

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2013-3-9 20:39:18 | 显示全部楼层
单总线需要校验,不然容易出错。

出0入0汤圆

发表于 2013-3-9 21:38:15 | 显示全部楼层
这个与交验应该没关系吧

出0入0汤圆

发表于 2013-3-9 21:42:59 | 显示全部楼层
我都是记录以前读过的数据,如果跟当次差异太大就重新读下检验

出0入0汤圆

 楼主| 发表于 2013-3-10 07:27:19 | 显示全部楼层
cc224 发表于 2013-3-9 21:42
我都是记录以前读过的数据,如果跟当次差异太大就重新读下检验

这个也是一个好方法,谢谢!

出0入0汤圆

 楼主| 发表于 2013-3-10 09:13:02 | 显示全部楼层
自己找到问题所在了,测量DS18B20要关闭中断,否则影响正常时序,导致测量结果不正确

出0入0汤圆

发表于 2013-3-10 19:56:19 | 显示全部楼层
如果有8个通道接8个18B20  驱动里面的 接口要怎么定义呢?
比如说你DQ定义的是P3^0,然后我P3^1,P3^2,P3^3……都有接18B20,这样 驱动程序要怎么修改呢?要通用,可以选择需要读取温度的18B20.

出0入0汤圆

发表于 2013-3-10 20:29:17 | 显示全部楼层
在读取ds18b20的时候必须要关闭总中断,否则会影响他的时序!

出0入0汤圆

 楼主| 发表于 2013-3-10 21:52:58 | 显示全部楼层
zhamo 发表于 2013-3-10 19:56
如果有8个通道接8个18B20  驱动里面的 接口要怎么定义呢?
比如说你DQ定义的是P3^0,然后我P3^1,P3^2,P3^ ...

我也想问这个问题呢,不打算把所有DS18B20接到一个口线上,因为那样需要知道DS18B20的ROM。打算每一个DS18B20接一个口线,有好的办法吗?
我现在需要用两个,用的是最笨的办法,同样的函数写了两遍,有更好的办法吗?
sbit不可以做为函数参数传送的。

出0入0汤圆

发表于 2013-3-11 07:45:22 来自手机 | 显示全部楼层
18b20常温时速度还凑合,高温时速度好慢,延时少了就错误。而且对时序要求太高了,用在系统里其他代码得给它让路,挺麻烦的。

出0入0汤圆

 楼主| 发表于 2013-3-11 08:33:06 | 显示全部楼层
Sullivan 发表于 2013-3-11 07:45
18b20常温时速度还凑合,高温时速度好慢,延时少了就错误。而且对时序要求太高了,用在系统里其他代码得给 ...

你说的这个确实是一个问题,在做项目时一定要考虑。其他好用、便宜、货源充足容易购买的数字温度芯片还有哪些?

出0入0汤圆

发表于 2013-3-11 15:54:30 来自手机 | 显示全部楼层
mengfc 发表于 2013-3-11 08:33  你说的这个确实是一个问题,在做项目时一定要考虑。其他好用、便宜、货源充足容易购买的数字温度芯片还有 ...

我要求不高,而且单片机有空闲ADC,所以直接三极管+LM358搞定。

出0入0汤圆

发表于 2014-8-22 17:37:35 | 显示全部楼层
有没有遇到过DS18B20读出的温度数据不对但CRC能通过的情况?

出0入0汤圆

发表于 2014-11-2 09:50:28 | 显示全部楼层
基本都是说是中断和crc

出0入0汤圆

发表于 2014-11-17 15:04:21 | 显示全部楼层
时序要求是挺高的,好像上了80度就容易出现问题,应该是时序都不正常了

出0入0汤圆

发表于 2015-2-5 15:55:09 | 显示全部楼层
学习楼主的经验!

出0入0汤圆

发表于 2015-2-5 16:20:19 | 显示全部楼层
楼上说读18B20时不能开中断的,肯定是程序架构有问题,在中断中做了太多的事,导致中断时间过长,或者中断太过频繁,我程序中同时读8路18B20,两个定时器中断(1个1mS,一个10mS),两个串口中断,完全无压力。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-7-23 10:29

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

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