mengfc 发表于 2013-3-9 20:30:05

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

曾经编写的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;
}

HadesHe 发表于 2013-3-9 20:39:18

单总线需要校验,不然容易出错。

电子爱好者_MCU 发表于 2013-3-9 21:38:15

这个与交验应该没关系吧

cc224 发表于 2013-3-9 21:42:59

我都是记录以前读过的数据,如果跟当次差异太大就重新读下检验

mengfc 发表于 2013-3-10 07:27:19

cc224 发表于 2013-3-9 21:42 static/image/common/back.gif
我都是记录以前读过的数据,如果跟当次差异太大就重新读下检验

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

mengfc 发表于 2013-3-10 09:13:02

自己找到问题所在了,测量DS18B20要关闭中断,否则影响正常时序,导致测量结果不正确

zhamo 发表于 2013-3-10 19:56:19

如果有8个通道接8个18B20驱动里面的 接口要怎么定义呢?
比如说你DQ定义的是P3^0,然后我P3^1,P3^2,P3^3……都有接18B20,这样 驱动程序要怎么修改呢?要通用,可以选择需要读取温度的18B20.

中二525 发表于 2013-3-10 20:29:17

在读取ds18b20的时候必须要关闭总中断,否则会影响他的时序!

mengfc 发表于 2013-3-10 21:52:58

zhamo 发表于 2013-3-10 19:56 static/image/common/back.gif
如果有8个通道接8个18B20驱动里面的 接口要怎么定义呢?
比如说你DQ定义的是P3^0,然后我P3^1,P3^2,P3^ ...

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

Sullivan 发表于 2013-3-11 07:45:22

18b20常温时速度还凑合,高温时速度好慢,延时少了就错误。而且对时序要求太高了,用在系统里其他代码得给它让路,挺麻烦的。

mengfc 发表于 2013-3-11 08:33:06

Sullivan 发表于 2013-3-11 07:45 static/image/common/back.gif
18b20常温时速度还凑合,高温时速度好慢,延时少了就错误。而且对时序要求太高了,用在系统里其他代码得给 ...

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

Sullivan 发表于 2013-3-11 15:54:30

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

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

amxx 发表于 2014-8-22 17:37:35

有没有遇到过DS18B20读出的温度数据不对但CRC能通过的情况?

hantnt 发表于 2014-11-2 09:50:28

基本都是说是中断和crc

weimas 发表于 2014-11-17 15:04:21

时序要求是挺高的,好像上了80度就容易出现问题,应该是时序都不正常了

成就与价值 发表于 2015-2-5 15:55:09

学习楼主的经验!

dadatou 发表于 2015-2-5 16:20:19

楼上说读18B20时不能开中断的,肯定是程序架构有问题,在中断中做了太多的事,导致中断时间过长,或者中断太过频繁,我程序中同时读8路18B20,两个定时器中断(1个1mS,一个10mS),两个串口中断,完全无压力。
页: [1]
查看完整版本: DS18B20读温度时偶尔出现错误值