901|10

69

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

读出的温度是0 [复制链接]

用51单片机和ds1822,在仿真上读出的温度是0.图是单总线上的时序图。问题出在哪里?请指点。

 

此帖出自51单片机论坛

最新回复

R2  用47 ohm 似乎不太對, 請用4.7K or 10K ohm 試試. 因為電阻太小, 8051  GPIO 無法將電位拉低. 8051的Sink電流應該小於20mA, 5/47 = 約100mA   详情 回复 发表于 2023-8-22 14:59
点赞 关注
 

回复
举报

1668

帖子

0

TA的资源

五彩晶圆(初级)

沙发
 

问题出在代码上

此帖出自51单片机论坛
 
 
 

回复

1万

帖子

25

TA的资源

版主

板凳
 

时序不对,检查时钟频率

此帖出自51单片机论坛
 
 
 

回复

6060

帖子

6

TA的资源

版主

4
 

单总线最重要的额就是时序了,这时序看不出来什么,把一些中断都关一下,再试试

此帖出自51单片机论坛
 
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 

回复

69

帖子

0

TA的资源

一粒金砂(中级)

5
 

改为 :temp=(temp*625/1);    

显示 -62.5 度,可是不随温度调整而变化》

此帖出自51单片机论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(中级)

6
 

#include <reg51.h>
#include <intrins.h>

#define uchar unsigned char    // 以后unsigned char就可以用uchar代替
#define uint  unsigned int    // 以后unsigned int 就可以用uint 代替

sbit LcdRs_P   = P3^5;        // 1602液晶的RS管脚       
sbit LcdRw_P   = P3^6;        // 1602液晶的RW管脚 
sbit LcdEn_P   = P3^7;        // 1602液晶的EN管脚
sbit DQ= P3^4;        // 温度传感器的引脚定义

/*********************************************************/
// 毫秒级的延时函数,time是要延时的毫秒数
/*********************************************************/
void DelayMs(uint time)
{
    uint i,j;
    for(i=0;i<time;i++)
        for(j=0;j<112;j++);
}


/*********************************************************/
// 延时15微秒
/*********************************************************/
void Delay15us(void)
{
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
}


/*********************************************************/
// 1602液晶写命令函数,cmd就是要写入的命令
/*********************************************************/
void LcdWriteCmd(uchar cmd)

    LcdRs_P = 0;
    LcdRw_P = 0;
    LcdEn_P = 0;
    P2=cmd;
    DelayMs(2);
    LcdEn_P = 1;    
    DelayMs(2);
    LcdEn_P = 0;    
}


/*********************************************************/
// 1602液晶写数据函数,dat就是要写入的数据
/*********************************************************/
void LcdWriteData(uchar dat)
{
    LcdRs_P = 1; 
    LcdRw_P = 0;
    LcdEn_P = 0;
    P2=dat;
    DelayMs(2);
    LcdEn_P = 1;    
    DelayMs(2);
    LcdEn_P = 0;
}


/*********************************************************/
// 1602液晶初始化函数
/*********************************************************/
void LcdInit()
{
    LcdWriteCmd(0x38);        // 16*2显示,5*7点阵,8位数据口
    LcdWriteCmd(0x0C);        // 开显示,不显示光标
    LcdWriteCmd(0x06);        // 地址加1,当写入数据后光标右移
    LcdWriteCmd(0x01);        // 清屏
}


/*********************************************************/
// 液晶光标定位函数
/*********************************************************/
void LcdGotoXY(uchar line,uchar column)
{
    // 第一行
    if(line==0)        
        LcdWriteCmd(0x80+column); 
    // 第二行
    if(line==1)        
        LcdWriteCmd(0x80+0x40+column); 
}

/*********************************************************/
// 液晶输出字符串函数
/*********************************************************/
void LcdPrintStr(uchar *str)
{
    while(*str!='\0')
            LcdWriteData(*str++);
}


/*********************************************************/
// 液晶输出数字
/*********************************************************/
void LcdPrintNum(uint num)
{
    LcdWriteData(num/100+0x30);                // 百位
    LcdWriteData(num%100/10+0x30);        // 十位
    LcdWriteData(num%10+0x30);                // 个位
}


/*********************************************************/
// 在液晶上显示温度
/*********************************************************/
void LcdPrintTemp(int temp)
{
    if(temp<0)                                 
    {
        LcdWriteData('-');                            // 负号    
        temp=0-temp;                                        // 负数转为正数
    }
    if(temp>999)                                   
    {
        LcdWriteData(temp/1000+0x30);        // 百位    
    }
    LcdWriteData(temp%1000/100+0x30);    // 十位
    LcdWriteData(temp%100/10+0x30);        // 个位
    LcdWriteData('.');                                 // 小数点
    LcdWriteData(temp%10+0x30);                // 小数后一位
    LcdWriteData(0xdf);                                // 摄氏度符号
    LcdWriteData('C');
    LcdWriteData(' ');
}

/*********************************************************/
// 复位DS18B20(初始化)
/*********************************************************/
void DS18B20_ReSet(void)
{
    uchar i;
    DQ=0;
    i=240;
    while(--i);
    DQ=1;
    i=30;
    while(--i);
    while(~DQ);
    i=4;
    while(--i);
}


/*********************************************************/
// 向DS18B20写入一个字节
/*********************************************************/
void DS18B20_WriteByte(uchar dat)
{
    uchar j;
    uchar btmp;
    
    for(j=0;j<8;j++)
    {
        btmp=0x01;
        btmp=btmp<<j;
        btmp=btmp&dat;
        
        if(btmp>0)        // 写1
        {
            DQ=0;//DQ=0
            Delay15us();
            DQ=1;
            Delay15us();
            Delay15us();
            Delay15us();
            Delay15us();
        }
        else            // 写0
        {
            DQ=0;
            Delay15us();
            Delay15us();
            Delay15us();
            Delay15us();
            DQ=1;
            Delay15us();
        }
    }
}


/*********************************************************/
// 读取温度值
/*********************************************************/
int DS18B20_ReadTemp(void)
{
    uchar j;
    int b,temp=0;    

    DS18B20_ReSet();                            // 产生复位脉
    DS18B20_WriteByte(0xcc);            // 忽略ROM指令
    DS18B20_WriteByte(0x44);            // 启动温度转换指令

    DS18B20_ReSet();                            // 产生复位脉
    DS18B20_WriteByte(0xcc);            // 忽略ROM指令
    DS18B20_WriteByte(0xbe);            // 读取温度指令

    for(j=0;j<16;j++)                            // 读取温度数量
    {                        
        DQ=0;
        _nop_();
        _nop_();
        DQ=1;    
        Delay15us();
        b=DQ;
        Delay15us();
        Delay15us();
        Delay15us();
        b=b<<j;
        temp=temp|b;
    }
    
    temp=(temp*625/1);                    // 合成温度值并放大10倍                    
    return (temp);                                // 返回检测到的温度值
}


/*********************************************************/
// 主函数
/*********************************************************/
void main()
{
    int  temp;                                                // 保存温度传感器测量到的结果

    LcdInit();                                                // 执行液晶初始化

    LcdGotoXY(0,0);                                    // 定位到第0行第0列
    LcdPrintStr("  temp=         ");    // 第0行显示“  temp=         ”
//    LcdGotoXY(1,0);                                    // 定位到第1行第0列
//    LcdPrintStr("  dist=   cm    ");    // 第1行显示“  dist=   cm    ”
    
    while(DS18B20_ReadTemp()==850)        // 等待温度传感器初始化完成
    {
        DelayMs(10);
    }
    
    while(1)
    {
        temp=DS18B20_ReadTemp();                // 获取温度传感器的温度值
        LcdGotoXY(0,7);                                    // 定位到第0行第7列
        LcdPrintTemp(temp);                            // 显示当前的温度值
        LcdGotoXY(1,7);                                // 光标定位

    }
}

这是修改的下载代码。

此帖出自51单片机论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(中级)

7
 

 

此帖出自51单片机论坛
 
 
 

回复

4817

帖子

4

TA的资源

版主

8
 

确保时序图与DS1822的时序要求一致,包括时间延迟、写入脉冲宽度等参数。

此帖出自51单片机论坛
 
 
 

回复

114

帖子

6

TA的资源

一粒金砂(中级)

9
 

R2  用47 ohm 似乎不太對, 請用4.7K or 10K ohm 試試.

因為電阻太小, 8051  GPIO 無法將電位拉低.

8051的Sink電流應該小於20mA,

5/47 = 約100mA

此帖出自51单片机论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(中级)

10
 

是的,r2阻值写错了,我也发现了,时序在示波器调整后能读温度了,现在的问题是读出的温度和DS1822的不一致。谢谢!

此帖出自51单片机论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(中级)

11
 

好了.

此帖出自51单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表