打印
[AVR单片机]

DS18B20多个并在一起,线长了就读不出来怎么办?[已解决]

[复制链接]
6081|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
SUNKE9|  楼主 | 2010-4-1 21:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 SUNKE9 于 2010-4-2 10:28 编辑

DS18B20多个并在一起,用的rom搜索功能搜出id然后分别读取温度,连线(30cm)短就能读出来,线长(80cm)了就读不出来怎么办?外接4.7k上拉电阻也不见效果。
线短能读出来说明我的读写函数、rom搜索都是正确的,那还差什么事呢?下面是我的读写程序,麻烦做过长距离多个并联的大侠给点指点
/*===================================================================
// 函数功能:判断总线应答
// 输入参数:void
// 返回参数:unsigned char true为应答//如果总线上有18b20则返回0
===================================================================*/
unsigned char ds1820_rst(void)
{
    unsigned char ack = 1;
    unsigned char i = 0;
cli();
    SET_DIR_1WIRE;        //Maga16控制总线
    SET_OP_1WIRE;        //
    CLR_OP_1WIRE;        //强制拉低
    _delay_us(600);       //480us~600us
    SET_OP_1WIRE;        //
    CLR_DIR_1WIRE;    //释放总线,总线自动上拉
    _delay_us(50);       //15~60us  
sei();
for(i = 250;i > 1;i--)
{
    ack = CHECK_IP_1WIRE;
if(ack == 0)
break;
}
    SET_DIR_1WIRE;   
    SET_OP_1WIRE;

    _delay_us(240);       //240us  
if(ack == 0)
{return 0;}
else
{return 1;}
}

/*===================================================================
// 函数功能: 从 1-wire 总线上读取一个字节
// 形参: void
// 返回: unsigned char 读到的值
===================================================================*/
unsigned char read_1820(void)
{
    unsigned char i;
    unsigned char   value = 0;
cli();
    for(i = 8; i > 0; i--)
    {
        value >>= 1;                 // low bit first
        SET_OP_1WIRE;
        CLR_OP_1WIRE;                       //  pull DQ low to start timeslot
        _delay_us(3);
        SET_OP_1WIRE;
        CLR_DIR_1WIRE;                 // release bus
        _delay_us(15);
        if(CHECK_IP_1WIRE)
        value |= 0x80;
        _delay_us(100);
        SET_DIR_1WIRE;
        _delay_us(5);                 // time interval
    }
sei();
    return(value);
}
/*===================================================================
// 函数功能: 向 1-WIRE 总线上写一个字节
// 形参: value 写到总线上的值
// 返回: void
===================================================================*/
void write_1820(unsigned char value)
{
    unsigned char i;
cli();
    SET_DIR_1WIRE;
    for(i = 8; i > 0; i--)
    {
        if(value & 0x01)
     {
            CLR_OP_1WIRE;                   //  pull DQ low to start timeslot
            _delay_us(10);
            SET_OP_1WIRE;
            _delay_us(100);
     }
        else
     {
            CLR_OP_1WIRE;                   //  pull DQ low to start timeslot
            _delay_us(100);
            SET_OP_1WIRE;
            _delay_us(10);
     }
        value >>= 1;
    }
sei();
}
/*===================================================================
函数功能:写一个位
输入参数:unsigned char *tp
返回参数:void
备    注:
程序编制:孙可
修改日期:2009.10.28
===================================================================*/
void WriteB20Bit(unsigned char *tp)
{
    if((*tp)& 0x01)
{
CLR_OP_1WIRE; // pull DQ low to start timeslot
_delay_us(1);
SET_OP_1WIRE;
_delay_us(60);
}
else
{
CLR_OP_1WIRE; // pull DQ low to start timeslot
_delay_us(60);
SET_OP_1WIRE;
_delay_us(10);
}
}
/*===================================================================
函数功能:读一个位
输入参数:unsigned char *tp
返回参数:void
备    注:
程序编制:孙可
修改日期:2009.10.28
===================================================================*/
void ReadB20Bit(unsigned char *tp)
{
    SET_DIR_1WIRE;
CLR_OP_1WIRE; // pull DQ low to start timeslot
_delay_us(3);
SET_OP_1WIRE;
CLR_DIR_1WIRE; // release bus
_delay_us(10);
if(CHKBIT(DS18B20_PIN,DS18B20_DQ))
{(*tp)|=0x80;}
_delay_us(60);
SET_DIR_1WIRE;
_delay_us(60); // time interval
}

相关帖子

沙发
麻辣鸭脖子| | 2010-4-1 22:02 | 只看该作者
可能是电压在导线上损耗掉了

使用特权

评论回复
板凳
xiaomifan| | 2010-4-1 22:27 | 只看该作者
if(ack == 0)
{return 0;}
else
{return 1;}
这个是return给谁啊

使用特权

评论回复
地板
lpydidi| | 2010-4-1 22:56 | 只看该作者
函数注释一下会好懂点,这么长

使用特权

评论回复
5
SUNKE9|  楼主 | 2010-4-2 07:58 | 只看该作者
3# xiaomifan
retrun给调用的函数

使用特权

评论回复
6
SUNKE9|  楼主 | 2010-4-2 07:59 | 只看该作者
2# 麻辣鸭脖子

导线还没长到那种程度现在也就80cm

使用特权

评论回复
7
SUNKE9|  楼主 | 2010-4-2 08:02 | 只看该作者
我再看看时间能不能调整一下,同样的硬件别人的程序能识别出来两个传感器,我的就不行。

使用特权

评论回复
8
SUNKE9|  楼主 | 2010-4-2 10:25 | 只看该作者
问题已经解决,是复位函数中那个240US时间短了,我改成410就好了。谢谢上面热心回答的朋友们!
/*===================================================================
// 函数功能:判断总线应答
// 输入参数:void
// 返回参数:unsigned char true为应答//如果总线上有18b20则返回0
===================================================================*/
unsigned char ds1820_rst(void)
{
  unsigned char ack = 1;
  unsigned char i = 0;
cli();
  SET_DIR_1WIRE;     //Maga16控制总线
  SET_OP_1WIRE;     //
  CLR_OP_1WIRE;     //强制拉低
  _delay_us(600);     //480us~600us
  SET_OP_1WIRE;     //
  CLR_DIR_1WIRE;   //释放总线,总线自动上拉
  _delay_us(50);     //15~60us
sei();
for(i = 250;i > 1;i--)
{
  ack = CHECK_IP_1WIRE;
if(ack == 0)
break;
}
  SET_DIR_1WIRE;   
  SET_OP_1WIRE;

  _delay_us(240);     //240us
if(ack == 0)
{return 0;}
else
{return 1;}
}

使用特权

评论回复
9
ym2008| | 2010-4-2 15:23 | 只看该作者
延时很重要!

使用特权

评论回复
10
houhyousei| | 2010-4-2 15:37 | 只看该作者
:L

使用特权

评论回复
11
yl616768| | 2018-5-9 17:05 | 只看该作者
SUNKE9 发表于 2010-4-2 10:25
问题已经解决,是复位函数中那个240US时间短了,我改成410就好了。谢谢上面热心回答的朋友们!
/*========= ...

你好,我最近在写单线多个18B20的代码,遇到了点问题,能互相交流一下嘛

使用特权

评论回复
12
一路向北lm| | 2018-5-12 06:09 | 只看该作者
调节延时,或者改变上拉电阻,一般延时调节下就可以。

使用特权

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

本版积分规则

个人签名:执着!

50

主题

355

帖子

1

粉丝