williamseu1984 发表于 2007-6-16 16:57:54

马老师救救我啊,我的多个DS18B20测温时打架了阿

我做的测温系统由上位机和下位机组成。上位机用MFC编写,下位机用了AT89S51。下位机接了两个DS18b20,没有采用单总线方式,而是分别用一个脚控制一个传感器。上位机发送信息帧,下位机接收、判断地址然后开始测温。测得温度用液晶1602显示,并回传上位机。

调试发现故障如下:

    在不与上位机通行的情况下,读取两个传感器的温度值均能正常显示在1602上。

    在与上位机通信情况下,单独读取任意一个传感器的温度时显示正常,但读取两个传感器的温度时数据打架,只有先读取的一个值正常。

我实在搞不清怎么回事,是谁与谁打架,为什么会打架,怎么打起来的。马老师救救我啊!!!

machao 发表于 2007-6-16 18:04:25

先读取两个传感器的温度值(注意不能被任何中断打断),然后再一个一个的送到上位机。

==============================================================================



在与上位机通信情况下,单独读取任意一个传感器的温度时显示正常,但读取两个传感器的温度时数据打架,只有先读取的一个值正常。我实在搞不清怎么回事,是谁与谁打架,为什么会打架,怎么打起来的。



估计你读第2个18b20时,时序被UART通信打乱了(UART在送第一个的数据),如果你用了UART中断,那么就更能肯定问题所在了。

williamseu1984 发表于 2007-6-16 20:08:43

我没有用UART中断,现经过测试发现液晶显示串行收发都没问题,问题出在18B20的函数,我发现我写的函数不稳定,代码贴这里了,马老师帮忙看一下,谢谢



#define SET_DQ_HighP2|=(1<<(n-1))      

#define SET_DQ_LOW   P2&=~(1<<(n-1))



void delay_ms(uint n)

{

uint i,j;

for(i=n;i>0;i--)

    for(j=0;j<1140;j++);

}



void Init_DS18B20(uchar num)       //初始化函数

{

        uchar x=0;

        uchar n;

        n=num;



        SET_DQ_High;

        //DQ = 1;      //DQ复位

        delay(8);//稍做延时

        SET_DQ_LOW;

//        DQ = 0;    //单片机将DQ拉低

        delay(80); //精确延时 大于480us

        SET_DQ_High;

// DQ = 1;    //拉高总线

        delay(14);       

        x=P2&(1<<(n-1));



//        x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败

}

////////////////////////////////////////////////////////////////

char ReadOneChar(uchar num)       //读一个字节

{

        unsigned char i=0;

        unsigned char dat = 0;

       

        uchar n;

        n=num;

       

        for (i=8;i>0;i--)

        {

                SET_DQ_LOW;

        //        DQ = 0;      // 给脉冲信号

                dat>>=1;

                SET_DQ_High;

        //        DQ = 1;      // 给脉冲信号

               

                if((P2&(1<<(n-1)))>>(n-1))

    //        if(DQ)

                        dat|=0x80;

                delay(4);

        }

        return(dat);

}

/////////////////////////////////////////////////////////////

void WriteOneChar(uchar dat,uchar num)//写一个字节

{

        unsigned char i=0;

        uchar n;

        n=num;

       

        for (i=8; i>0; i--)

        {

                SET_DQ_LOW;

        //        DQ = 0;

       

                if(dat&0x01)

                {

                  P2|=(1<<(n-1));

                }

                else

                  P2&=~(1<<(n-1));



        //        DQ = dat&0x01;



                delay(5);

                SET_DQ_High;       

        //        DQ = 1;

                dat>>=1;

        }

        delay(4);

}

/////////////////////////////////////////////////////////////

uint ReadTemperature(uchar num)//读取温度

{

        unsigned char a=0,c=0;   //低字节

        unsigned char b=0;      //高字节

        unsigned int t=0;       //温度

       

        uchar n;

        n=num;

       

        Init_DS18B20(n);

        WriteOneChar(0xCC,n); // 跳过读序号列号的操作

        WriteOneChar(0x44,n); // 启动温度转换

        Init_DS18B20(n);

        WriteOneChar(0xCC,n); //跳过读序号列号的操作

        WriteOneChar(0xBE,n); //读取温度寄存器等(共可读9个寄存器)前两个就是温度

        a=ReadOneChar(n);    //Read the   low   byte of the temperature

        b=ReadOneChar(n);   //            high

        c=a;

        a>>=4;            //低字节右移四位

        b<<=4;            //高字节左移四位

        t=a|b;

        t<<=8;

        c&=0x0F;

        t|=c;

//        tt=c;

//        tt*=0.0625;

//        c=tt*10+0.5;

//        t=t*10+c;

        return t;

}

/////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////////

void delay10ms(unsigned char time) //延时程序

{

        uchar a,b,c;

        for(a=0;a<time;a++)

                for(b=0;b<10;b++)

                        for(c=0;c<12;c++);

}

///////////////////////////////////////////////////////////////

void delay(unsigned int i)//延时函数

{

        while(i--);

}

williamseu1984 发表于 2007-6-16 20:57:15

ReadTemperature(1)和ReadTemperature(2)都没有问题,ReadTemperature(3)开始就有问题,温度读出23.9375来,并始终保持不变,我知道这里面肯定有问题,但是就是看不出来

machao 发表于 2007-6-17 02:04:34

单总线的时序要求比较严格,可能你的定时会出问题。建议你,



1。使用外部晶体,不要使用内部的RC振荡。

2。使用CVAVR环境,它提供了专用的单总线函数供使用。

zjybest 发表于 2007-6-19 20:41:47

点击此处打开armok01158499.pdf

请注意写和读的时序!
页: [1]
查看完整版本: 马老师救救我啊,我的多个DS18B20测温时打架了阿