R88 发表于 2014-10-23 15:38:54

18B20的时序是对的,为何读不出数据呢?

uchar read_bit(void)//读一位(bit)
{
        unsigned char i,j;
        TRISC&=0xfd;//配置RC1为输出
        RC1=0;       //将RC1拉低开始读时间隙
        //RC1=1;//then return high
        for(i=0;i<1;i++);// 延时
        TRISC|=0x02;//配置RC1为输入
        for(i=0;i<1;i++);
        return(RC1);// 返回RC1线上的电平值
}

uchar ReadOneChar(void) //读一个字节
{
        unsigned char i = 0;
        unsigned char dat = 0;
        for (i=0;i<8;i++)
        {   
                if(read_bit())
                dat|=(0x01<<i);    // 然后将其左移
          Delay(4);
        }
    return (dat);
}

void write_bit(char bitval)        //写一位
{
        RC1=0;         // 将RC1拉低开始写时间隙
        if(bitval==1)
        RC1=1;   // 如果写1,RC1返回高电平
        Delay(5);      // 在时间隙内保持电平值,
        RC1=1;         // Delay函数每次循环延时16μs,因此delay(5) = 104μs
}

void WriteOneChar(unsigned char dat) //写一个字节
{
    unsigned char i = 0;
    unsigned char temp;
    for (i=0; i<8; i++)// 写入字节, 每次写入一位
    {
            temp=(dat>>i);
               temp&=0x01;
                   write_bit(temp);
    }
    Delay(5);
}


在网上的找的51程序,移植到PIC的单片机上,主程序就这2句
WriteOneChar(0x33);       
a=ReadOneChar();
TXREG=a;
把18B20的序列号的第一位28h发生到串口;

jiaowoxiaolu 发表于 2014-10-23 15:42:51

没用过pic,看代码瞎猜,你读bit时候设置的输入端口,写bit的时候没看到设置为输出端口,不知道对不对

R88 发表于 2014-10-23 15:49:43

jiaowoxiaolu 发表于 2014-10-23 15:42
没用过pic,看代码瞎猜,你读bit时候设置的输入端口,写bit的时候没看到设置为输出端口,不知道对不对 ...

设置了。。你仔细看看你几行

R88 发表于 2014-10-23 15:50:33


时序图完全满足啊?

myin4 发表于 2014-10-23 15:53:09

真心觉得18B20难用,还容易受干扰,还不如用TC1047直接AD读,又便宜。

bi大痣 发表于 2014-10-23 16:12:04

额,楼主是几个18B20啊?你这是想读取温度呢还是读取序列号呢?

size327948964 发表于 2014-10-23 16:15:08

延时 对不对?

R88 发表于 2014-10-23 16:17:05

bi大痣 发表于 2014-10-23 16:12
额,楼主是几个18B20啊?你这是想读取温度呢还是读取序列号呢?

1个,读序列号的第一个

bi大痣 发表于 2014-10-23 16:29:55

额一个的话没有必要直接读取温度就可以了,初始化的时候跳过序列号就可以了!不知道你为啥要读取序列号!要是想读取DS18B20的序列号的话,你主函数里有初始化DS18B20吗?

R88 发表于 2014-10-23 17:36:34

bi大痣 发表于 2014-10-23 16:29
额一个的话没有必要直接读取温度就可以了,初始化的时候跳过序列号就可以了!不知道你为啥要读取序列号! ...

while1外面有读取,我看了下时序也是正确的:

xhp0912 发表于 2014-10-23 17:45:04

还是TC1047好用

xiaobendan 发表于 2014-10-23 17:56:02

1820并联没有试过,单个还是很好的,抗干扰,也很好,很温度,30米线寄生电源都很好的。

n0831 发表于 2014-10-23 18:01:18

貌似没给出复位脉冲!

R88 发表于 2014-10-23 18:12:01

n0831 发表于 2014-10-23 18:01
貌似没给出复位脉冲!

对应哪个时序图没有给复位脉冲??

hkjabcd 发表于 2014-10-23 18:32:18

温度转换时,需要的时间比较长,应该给足够延时

n0831 发表于 2014-10-23 22:57:44

R88 发表于 2014-10-23 18:12
对应哪个时序图没有给复位脉冲??

18b20的一个完整操作过程为 复位-rom操作指令-ram操作指令!
你的程序里没见到有复位时序呢。

n0831 发表于 2014-10-23 22:58:16

R88 发表于 2014-10-23 18:12
对应哪个时序图没有给复位脉冲??

18b20的一个完整操作过程为 复位-rom操作指令-ram操作指令!
你的程序里没见到有复位时序呢。

lyxer 发表于 2014-10-23 23:02:34

某个上啦没写···我曾经就是这样 在示波器上看了2天的温度显示····但单片机就是读不出来

R88 发表于 2014-10-24 08:54:59

n0831 发表于 2014-10-23 22:58
18b20的一个完整操作过程为 复位-rom操作指令-ram操作指令!
你的程序里没见到有复位时序呢。 ...

有啊,上面不是贴出来时序波形了么

qq910130528 发表于 2014-10-24 09:17:15

R88 发表于 2014-10-23 17:36
while1外面有读取,我看了下时序也是正确的:

初始化多次?

johnlj 发表于 2014-10-24 09:53:25

线有几米长,长的话要用屏蔽线

还有就是要多复位,每次读都复位一下

yaxiaoyu 发表于 2014-10-24 10:05:24

检查电路,可以还一个传感器试试{:lol:}

markdif 发表于 2014-10-24 10:09:57

也认为这个TC1047好用点。。。

huojianfei 发表于 2014-10-24 10:11:50

480us 一定要够

codeman 发表于 2014-10-24 10:15:21

曾做过 10来米线上IO口取电并30来个,通讯稳定可靠。
数据手册上写的很详细,记得大约步骤如下
先复位总线 -> 跳过ROM -> 启动温度转换 -> 延时 ->匹配ROM(总线上单个器件可跳过)-> 读数据->获取温度

shandong 发表于 2014-10-24 10:51:21

产品中用到,一直不错,没出过问题

R88 发表于 2014-10-24 11:01:13

codeman 发表于 2014-10-24 10:15
曾做过 10来米线上IO口取电并30来个,通讯稳定可靠。
数据手册上写的很详细,记得大约步骤如下
先复位总线 ...

uchar RomCode = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

void Delay(uint num)
{
while( --num );
}

uchar Init_DS18B20(void)//初始化ds1820,RC1作为单总线通信口
{   
           uchar presence=1;
           TRISC|=0x02;//配置RC1为输入
    Delay(8);    //稍做延时
    TRISC&=0xfd;//配置RC1为输出
    RC1=0;      //将RC1拉低
    Delay(150);   //精确延时 大于 480us
    TRISC|=0x02;//配置RC1为输入
    Delay(20);
    presence=RC1;    //读取存在信号
    Delay(8);
    return(presence); //返回信号,0=presence,1= no presence
}

bit read_bit(void)//读一位(bit)
{
        unsigned char i;
        TRISC&=0xfd;//配置RC1为输出
        RC1=0;       //将RC1拉低开始读时间隙
        TRISC|=0x02;//配置RC1为输入
        return(RC1);// 返回RC1线上的电平值
}

uchar ReadOneChar(void) //读一个字节
{
        unsigned char i = 0;
        unsigned char dat = 0;
        for (i=0;i<8;i++)
        {   
                if(read_bit())
                dat|=(0x01<<i);    // 然后将其左移
          Delay(4);
        }
    return (dat);
}

void write_bit(uchar bitval)        //写一位
{
        TRISC&=0xfd;//配置RC1为输出
        RC1=0;         // 将RC1拉低开始写时间隙
        Delay(1);
        if(bitval==1)
        TRISC|=0x02;//配置RC1为输入   // 如果写1,RC1返回高电平
        Delay(10);      // 在时间隙内保持电平值,
        TRISC|=0x02;
}

void WriteOneChar(unsigned char dat) //写一个字节
{
    unsigned char i = 0;
    unsigned char temp;
    for (i=0; i<8; i++)// 写入字节, 每次写入一位
    {
            temp=(dat>>i);
               temp&=0x01;
                   write_bit(temp);
    }
    Delay(5);
}

uchar Read_RomCord(void) //读取64位序列码
{
    unsigned char j;
    Init_DS18B20();
    WriteOneChar(0x33);// 读序列码的操作
    for (j = 0; j < 8; j++)
        {
                RomCode = ReadOneChar() ;
        }
        return (RomCode);
}
       

while(1)里面就这三句:       
a=Read_RomCord();
TXREG=a;
delay_1ms();
我看过时序,波形完全对的,但是读得都是FF。
下面是时序图,完全跟Read_RomCord的时序一样:

R88 发表于 2014-10-24 12:13:34

搞定了,跟上次调AD一样,就差点延时。。{:sweat:}
页: [1]
查看完整版本: 18B20的时序是对的,为何读不出数据呢?