一乐电子

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 2407|回复: 5

18b20 怎么做都不成功,什么问题?

[复制链接]
发表于 2011-4-30 22:45 | 显示全部楼层 |阅读模式
头都快大了,濒临绝望!弄了无数次都没有成功。
程序也是参照本论坛的,也不行。  我用的单片机是:12c5a60s2   晶振12M     16X80的led点阵屏
现在温度总显示16.0度。用吹风筒吹ds18b20,数据不变。。。
麻烦各位大侠为小弟解答下。

sbit DQ =P2^6;  // -- 定义通信端口
extern unsigned char T_int,T_dec;
unsigned char code t_tab[16]={0,0,1,1,2,3,3,4,5,5,6,6,7,8,8,9}; //小数第一位查表
void delay(unsigned char i) //(2*i+3) us
{
while(--i);
}
unsigned char DS18B20_init(void) //初始化函数
{
unsigned char x=0;
DQ = 1;      //DQ复位
delay(8);    //稍做延时
DQ = 0;      //单片机将DQ拉低
delay(240);  //精确延时 大于 480us
DQ = 1;      //拉高总线
delay(10);   //15~60us
x=DQ;        //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(50);  //60~240us
return(x);
}
unsigned char  ReadOneChar(void)//读一个字节
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
  DQ = 0; // 给脉冲信号
  dat>>=1;
  DQ = 1; // 给脉冲信号
  if(DQ)
  dat|=0x80;
  delay(40); //60~120us
}
return(dat);
}
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
  DQ = 0;
  DQ = dat&0x01;
  delay(20);   //15~60us
  DQ = 1;
  dat>>=1;
}
}
void ReadTemperature(void)//读取温度
{
unsigned char data_H,data_L;
DS18B20_init();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
DS18B20_init();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
data_L=ReadOneChar();
data_H=ReadOneChar();

    if(data_H>15) data_H=(~data_H+1),data_L=(~data_L+1); //低于零度为补码,取反加1
    T_int=(data_H<<4)|(data_L>>4);  //合并后得到原始温度数据 整数部分
    T_dec=t_tab[(data_L&0x0F)];
}
发表于 2011-4-30 23:10 | 显示全部楼层
你这个情况以前看到论坛有讨论过,刚才没有找到连接。

程序不会分析,看了你的程序,发现和论坛上的有点不一样,不知道是不是有关系。
#include "ds18b20.h"
extern unsigned char T_int,T_dec;
unsigned char code t_tab[16]={0,0,1,1,2,3,3,4,5,5,6,6,7,8,8,9}; //小数第一位查表
void delay(unsigned char i) //(2*i+3) us
{  
    unsigned char j=i;
while(--j);
while(--i);
}
unsigned char DS18B20_init(void) //初始化函数
{
unsigned char x=0;
DQ = 1;      //DQ复位
delay(8);    //稍做延时
DQ = 0;      //单片机将DQ拉低
delay(255);  //精确延时 大于 480us
    delay(40);  //精确延时 大于 480us
DQ = 1;      //拉高总线
delay(20);   //15~60us
x=DQ;        //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(80);  //60~240us
return(x);
}
unsigned char  ReadOneChar(void)//读一个字节
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
  DQ = 0; // 给脉冲信号
  dat>>=1;
  DQ = 1; // 给脉冲信号
  if(DQ)
  dat|=0x80;
  delay(70); //60~120us
}
return(dat);
}
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
  DQ = 0;
  DQ = dat&0x01;
  delay(30);   //15~60us
  DQ = 1;
  dat>>=1;
}
}
void ReadTemperature(void)//读取温度
{
unsigned char data_H,data_L;
DS18B20_init();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
DS18B20_init();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
data_L=ReadOneChar();
data_H=ReadOneChar();

    if(data_H>15) data_H=(~data_H+1),data_L=(~data_L+1); //低于零度为补码,取反加1
    T_int=(data_H<<4)|(data_L>>4);  //合并后得到原始温度数据 整数部分
    T_dec=t_tab[(data_L&0x0F)];
}
回复

使用道具 举报

发表于 2011-4-30 23:12 | 显示全部楼层
另外印象中晶体好像是24M,不是12M的。
回复

使用道具 举报

发表于 2011-4-30 23:27 | 显示全部楼层
你这stc单片机是 1T的么?  如果是的话,延时时间不一样,delay要长一点.
回复

使用道具 举报

发表于 2011-4-30 23:42 | 显示全部楼层
凡是有delay的地方,再复制1-2个在后面即可。
回复

使用道具 举报

 楼主| 发表于 2011-5-1 00:18 | 显示全部楼层
非常各位,找到答案了,现在在这里说下,希望能帮到遇到同样问题的朋友。

上面几位朋友已经说得很对了,是延时的问题,单片机不同,所以延时不一样。我的是1T的单片机。
下面是程序
/**************************************
延时X微秒(STC12C5A60S2@12M)
不同的工作环境,需要调整此函数
此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同
**************************************/
void DelayXus(BYTE n)
{
    while (n--)
    {
        _nop_();
        _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字节数据
**************************************/
BYTE DS18B20_ReadByte()
{
    BYTE i;
    BYTE 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(BYTE dat)
{
    char i;

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

使用道具 举报

本版积分规则

QQ|一淘宝店|手机版|商店|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2025-12-16 04:10 , Processed in 0.032484 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表