jqfsjt 发表于 2015-12-25 08:21:18

STC15W408AS + DS18B20的DQ 脚需要用手指拿着才有数据输出?

现在有个设计,采用的是STC15W408AS,电源电压 3.3V,P1.3脚接DS18B20的DQ,移植原来正常工作的程序,没有数据输出,但是用手指接触DQ脚,能够输出数据,用示波器的探头接DQ ,也有数据,接512上拉电阻,故障依旧,很是疑惑,和大家请教下。
下面是测试程序:
void main()
{   
        unsigned int Temperature;       
    Init_Mcu();
    DS18B20_Reset();             //设备复位   
    delayms(400);
    delayms(400);                                               
        flag_uart=0;               //清空标志位
        while(1)
    {          
                flag_uart=0;         //清空标志位
                //采集温度数据
                Temperature = GET_TEMP();
                DATA='@';
                DATA= Temperature%100000/10000 + 0x30;
                DATA= Temperature%10000/1000 + 0x30;
                DATA= Temperature%1000/100 + 0x30;
                DATA= Temperature%100/10 + 0x30;
                DATA= Temperature%10 + 0x30;
                num_txd=0;
                num_txd_max=6;
                EN_485=1;
                delayms(1);                                                                                                               
                SBUF=DATA;
                delayms(500);
                delayms(1000);
        }
}

jqfsjt 发表于 2015-12-25 08:22:49


/**************************************
延时X微秒(STC15L@5.5296M)
不同的工作环境,需要调整此函数
**************************************/
void DelayXus(unsigned char n)
{
    while (n--)
    {
      _nop_();
    }
}

/**************************************
复位DS18B20,并检测设备是否存在
**************************************/
void DS18B20_Reset()
{
    CY = 1;
    while (CY)
    {
      DQ = 0;                     //送出低电平复位信号
      DelayXus(240);            //延时至少480us
      DelayXus(240);
      DQ = 1;                     //释放数据线
      DelayXus(60);               //等待60us
      CY = DQ;                  //检测存在脉冲
      DelayXus(240);            //等待设备释放数据线
      DelayXus(180);
    }
}
/**************************************
从DS18B20读1字节数据
**************************************/
unsigned char DS18B20_ReadByte()
{
    unsigned char i;
    unsigned char dat = 0;

    for (i=0; i<8; i++)             //8位计数器
    {
      dat >>= 1;
      DQ = 0;                     //开始时间片
      DelayXus(1);                //延时等待
      DQ = 1;                     //准备接收
      DelayXus(1);                //接收延时
      if (DQ) dat |= 0x80;      //读取数据
      DelayXus(60);               //等待时间片结束
    }

    return dat;
}

/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte(unsigned char dat)
{
    char i;

    for (i=0; i<8; i++)             //8位计数器
    {
      DQ = 0;                     //开始时间片
      DelayXus(1);                //延时等待
      dat >>= 1;                  //送出数据
      DQ = CY;
      DelayXus(60);               //等待时间片结束
      DQ = 1;                     //恢复数据线
      DelayXus(1);                //恢复延时
    }
}


//************************************
unsigned int GET_TEMP()
{       
        unsigned int temp;
        unsigned char TPL,TPH;
        EA = 0;
        DS18B20_Reset();                //设备复位
    DS18B20_WriteByte(0xCC);      //跳过ROM命令
    DS18B20_WriteByte(0x44);      //开始转换命令
    while (!DQ);                  //等待转换完成
        //第一次转换前,在此加入延时毫秒
    DS18B20_Reset();                //设备复位
    DS18B20_WriteByte(0xCC);      //跳过ROM命令
    DS18B20_WriteByte(0xBE);      //读暂存存储器命令
    TPL = DS18B20_ReadByte();       //读温度低字节
    TPH = DS18B20_ReadByte();       //读温度高字节
        EA =1;
    temp=(TPH<<8)|TPL;
    temp=(temp*10)>>4;                        //精确到小数点后1位
        return temp;
}


sbit DQ = P1^3;   //定义单片机接ds18b20的数据端

haibaogk 发表于 2015-12-25 08:34:12

上拉电阻,频率。。。。

河图洛书 发表于 2015-12-25 09:05:25

最好看下,延时函数,坛友好多提出是,延时除了问题,楼主可以借鉴下,修改下延时,看可以吗DS18B20好像是4.7k上拉

sddp001 发表于 2015-12-25 09:24:56

512上拉电阻,这么狠?

jqfsjt 发表于 2015-12-25 09:50:17

延时修改了。现在改成6--12个_nop_();都不行。
void DelayXus(unsigned char n)
{
    while (n--)
    {
      _nop_();
    }
}

ayumi8 发表于 2015-12-25 10:18:40

买块 猪肉 挂上去试试{:titter:}




你重新找一个驱动函数试试啊

jqfsjt 发表于 2015-12-25 12:04:22

ayumi8 发表于 2015-12-25 10:18
买块 猪肉 挂上去试试




有这想法,{:cry:}
这个函数在别的地方用过,是验证过的。
现在怀疑是MCU的原因。

jqfsjt 发表于 2015-12-25 15:39:10

找到原因了。
oid DS18B20_Reset()
{
    CY = 1;
    while (CY)
    {
      DQ = 0;


去掉while (CY)

结贴吧。
页: [1]
查看完整版本: STC15W408AS + DS18B20的DQ 脚需要用手指拿着才有数据输出?