找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4030|回复: 12
收起左侧

为什么单片机DS18B20程序一直显示0°C

  [复制链接]
ID:1011399 发表于 2022-3-28 20:21 | 显示全部楼层 |阅读模式
为什么DS18B20在LCD12864上显示,温度一直是0°C,求大佬们帮忙看看,谢谢了

单片机源程序如下:
#include "DS18B20.h"
#include<intrins.h>

uchar flag_temper = 0;

//****************************************************
//DS18B20延时函数
//****************************************************
void DS18B20_Delay(uint n )
{
        uint i;
        for(i = 0 ; i < n ; i++ );
}
//****************************************************
//DS18B20写1字节
//****************************************************
void DS18B20_Write_Byte( uchar dat)
{
        uchar i;
        for( i = 0 ; i < 8 ; i++ )
        {
                DS18B20_DQ = 0;
                _nop_();                        //延时>1us
                _nop_();
                DS18B20_DQ = dat&0x01;                 //先写低位
                dat >>= 1;
                DS18B20_Delay(6);        //延时60~120us
                DS18B20_DQ = 1;                //释放总线
                _nop_();                        //延时>1us
                _nop_();        
        }               
}

//****************************************************
//DS18B20读1字节
//****************************************************
uchar DS18B20_Read_Byte( )
{
        uchar dat,i;
        for( i = 0 ; i < 8 ; i++ )
        {
                DS18B20_DQ = 0;
                _nop_();                        //延时>1us
                _nop_();               
                DS18B20_DQ = 1;                //释放总线
                _nop_();                        //延时>1us
                _nop_();
                dat >>= 1;
                if( DS18B20_DQ == 1)
                {
                        dat |= 0X80;
                }
                else
                {
                        dat &= 0x7f;
                }

                DS18B20_Delay(6);        //延时60~120us                        
        }
        return dat;               
}

//****************************************************
//DS18B20初始化
//****************************************************
bit DS18B20_Init()
{
        bit Flag_exist = 1;
        DS18B20_DQ = 1;                        //释放总线
        _nop_();                                //延时>1us
        _nop_();
        DS18B20_DQ = 0;        
        DS18B20_Delay(50);                //延时480~960us        
        DS18B20_DQ = 1;                        //释放总线
        DS18B20_Delay(3);                //延时15~60us
        Flag_exist = DS18B20_DQ;
        DS18B20_Delay(10);                //延时60~240us
        DS18B20_DQ = 1;                        //释放总线
        return Flag_exist;                        
}

//**********************************************************
//读取温度函数,返回温度的绝对值,并标注flag_temper,flag_temper=1表示负,flag_temper=0表示正
//**********************************************************
uint Get_temp(void)         //读取温度值
{  
        float tt;
        uchar a,b;
        uint temp;
        if( DS18B20_Init() == 0 )                //初始化
        {
                DS18B20_Write_Byte(0xcc);          //忽略ROM指令
                DS18B20_Write_Byte(0x44);          //温度转换指令
                if( DS18B20_Init() == 0 )                 //初始化
                {
                        DS18B20_Write_Byte(0xcc);          //忽略ROM指令
                        DS18B20_Write_Byte(0xbe);          //读暂存器指令
                        a = DS18B20_Read_Byte();           //读取到的第一个字节为温度LSB
                        b = DS18B20_Read_Byte();           //读取到的第一个字节为温度MSB
                        temp = b;                      //先把高八位有效数据赋于temp
                        temp <<= 8;                    //把以上8位数据从temp低八位移到高八位
                        temp = temp|a;                //两字节合成一个整型变量
                        if(temp>0xfff)
                        {
                                flag_temper=1;                                //温度为负数
                                temp=(~temp)+1;
                        }
                        else
                        {                                                                                                                                                           
                                flag_temper=0;                                //温度为正或者0
                        }
                        
                        tt = temp*0.0625;              //得到真实十进制温度值
                                                        //因为DS18B20可以精确到0.0625度
                                                        //所以读回数据的最低位代表的是0.0625度
                        temp = tt*100;               //放大百倍
                                                        //这样做的目的将小数点也转换为可显示数字
                }
        }
        return temp;
}









#include"lcd12864.h"

/*******************************************************************************
* 函 数 名         : LCD12864_Delay1ms
* 函数功能                   : 延时1MS
* 输    入         : c
* 输    出         : 无
*******************************************************************************/
void LCD12864_Delay1ms(uint c)
{
        uint j,k;
        for(j=c; j>0; j--)
                for(k=114; k>0; k--);
}

/*******************************************************************************
* 函 数 名         : LCD12864_Busy
* 函数功能                   : 检测LCD是否忙
* 输    入         : 无
* 输    出         : 1或0(1表示不忙,0表示忙)
*******************************************************************************/
uchar LCD12864_Busy(void)
{
        uchar i = 0;

        LCD12864_RS = 0;           //选择命令
        LCD12864_RW = 1;        //选择读取
        LCD12864_EN = 1;
        LCD12864_Delay1ms(1);
        while((LCD12864_DATAPORT & 0x80) == 0x80)        //检测读取到的值
        {
                i++;
                if(i > 100)
                {
                        LCD12864_EN = 0;
                        return 0;           //超过等待时间返回0表示失败
                }
        }
        LCD12864_EN = 0;
        return 1;
}

/*******************************************************************************
* 函 数 名         : LCD12864_WriteCmd
* 函数功能                   : 写命令
* 输    入         : cmd
* 输    出         : 无
*******************************************************************************/

void LCD12864_WriteCmd(uchar cmd)
{
        uchar i;
        i = 0;
        while( LCD12864_Busy() == 0)
        {
                LCD12864_Delay1ms(1);
                i++;
                if( i>100)
                {
                        return;           //超过等待退出
                }        
        }
        LCD12864_RS = 0;     //选择命令
        LCD12864_RW = 0;     //选择写入
        LCD12864_EN = 0;     //初始化使能端
        LCD12864_DATAPORT = cmd;   //放置数据
        LCD12864_EN = 1;                   //写时序
        LCD12864_Delay1ms(5);
        LCD12864_EN = 0;                                            
}

/*******************************************************************************
* 函 数 名         : LCD12864_WriteData
* 函数功能                   : 写数据
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/
void LCD12864_WriteData(uchar dat)
{
        uchar i;
        i = 0;
        while( LCD12864_Busy() == 0)
        {
                LCD12864_Delay1ms(1);
                i++;
                if( i>100)
                {
                        return;           //超过等待退出
                }        
        }

        LCD12864_RS = 1;     //选择数据
        LCD12864_RW = 0;     //选择写入
        LCD12864_EN = 0;     //初始化使能端
        LCD12864_DATAPORT = dat;   //放置数据
        LCD12864_EN = 1;                   //写时序
        LCD12864_Delay1ms(5);
        LCD12864_EN = 0;                                                                    
}

/*******************************************************************************
* 函 数 名         : LCD12864_ReadData
* 函数功能                   : 读取数据
* 输    入         : 无
* 输    出         : 读取到的8位数据
*******************************************************************************/
#ifdef LCD12864_PICTURE

uchar LCD12864_ReadData(void)
{
        uchar i, readValue;
        i = 0;
        while( LCD12864_Busy() == 0)
        {
                LCD12864_Delay1ms(1);
                i++;
                if( i>100)
                {
                        return 0;           //超过等待退出
                }        
        }
        LCD12864_RS = 1;       //选择命令
        LCD12864_RW = 1;
        LCD12864_EN = 0;
        LCD12864_Delay1ms(1);  //等待
        LCD12864_EN = 1;
        LCD12864_Delay1ms(1);
        readValue = LCD12864_DATAPORT;
        LCD12864_EN = 0;
        return readValue;
}

#endif

/*******************************************************************************
* 函 数 名         : LCD12864_Init
* 函数功能                   : 初始化LCD12864
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void LCD12864_Init()
{
        LCD12864_PSB = 1;          //选择并行输入
        LCD12864_RST = 1;          //复位
        LCD12864_WriteCmd(0x30);  //选择基本指令操作
        LCD12864_WriteCmd(0x0c);  //显示开,关光标
        LCD12864_WriteCmd(0x01);  //清除LCD12864的显示内容
}

/*******************************************************************************
* 函 数 名         : LCD12864_ClearScreen
* 函数功能                   : 在画图模式下,LCD12864的01H命令不能清屏,所以要自己写一个清
*                  * 屏函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
#ifdef LCD12864_PICTURE

void LCD12864_ClearScreen(void)
{
        uchar i,j;
        LCD12864_WriteCmd(0x34);          //开启拓展指令集
        for(i=0;i<32;i++)                          //因为LCD有纵坐标32格所以写三十二次
        {
                LCD12864_WriteCmd(0x80+i);                  //先写入纵坐标Y的值
                LCD12864_WriteCmd(0x80);                  //再写入横坐标X的值
                for(j=0;j<32;j++)                  //横坐标有16位,每位写入两个字节的的数据,也
                {                                                  //就写入32次以为当写入两个字节之后横坐标会自
                        LCD12864_WriteData(0xFF);          //动加1,所以就不用再次写入地址了。
                }
        }
        LCD12864_WriteCmd(0x36);         //0x36扩展指令里面打开绘图显示
        LCD12864_WriteCmd(0x30);         //恢复基本指令集
}

#endif
/*******************************************************************************
* 函 数 名         : LCD12864_SetWindow
* 函数功能                   : 设置在基本指令模式下设置显示坐标。注意:x是设置行,y是设置列
* 输    入         : x, y
* 输    出         : 无
*******************************************************************************/
void LCD12864_SetWindow(uchar x, uchar y)
{
        uchar pos;
        if(x == 0)           // 第一行的地址是80H
        {
                x = 0x80;
        }
        else if(x == 1)  //第二行的地址是90H
        {
                x = 0x90;        
        }
        else if(x == 2)  //第三行的地址是88H
        {
                x = 0x88;
        }
        else if(x == 3)
        {
                x = 0x98;
        }
        
        pos = x + y;
        LCD12864_WriteCmd(pos);
}


回复

使用道具 举报

ID:584814 发表于 2022-3-29 08:18 | 显示全部楼层
多是网上抄的程序应该没问题,但并不表示运行没问题。
不同的单片机运行速度不一样,所以延时的时长也有区别,需要按实调整。
回到问题:一直显示0极大可能是读不出数据,一般程序与单片机协调问题居多,不排除硬件接错。
回复

使用道具 举报

ID:161164 发表于 2022-3-29 16:34 | 显示全部楼层
一直显示0可能是初始化不成功
Flag_exist保持为1
同意沙发的说法
请检查DS18B20的各个延时时间
回复

使用道具 举报

ID:625730 发表于 2022-3-30 10:04 | 显示全部楼层
显示值是0,是没把ds18b20里的数据读出来,把main函数贴出来,有时是延时不够造成的。
回复

使用道具 举报

ID:1006510 发表于 2022-3-30 14:45 | 显示全部楼层
问题可能:1.程序问题(大多数网上程序复制下了是要微调的),这就要求你做到移植而非复制;2.延时问题,一些采样器件对延时是有要求的,要确保延时是正确的,可以看一下官方手册;3.硬件电路问题,刚开始经常会出现仿真能用,但是实物有问题。这时候不要慌张,一点一点排除错误,可以测通断,测电压,检查一下PCB画原理图或是连线,通过不断的缩小范围,找到问题所在。这个回答是一般错误检查的步骤,希望对你有用。
回复

使用道具 举报

ID:941205 发表于 2022-3-30 16:38 | 显示全部楼层
用PROTEUS搭个电路仿真吧这样你能快速找到问题。
回复

使用道具 举报

ID:480627 发表于 2022-4-8 18:25 | 显示全部楼层
在复位成功后加一个亮灯啊或声音提示啊,看看是不是复位成为了。。然后再查读写的步骤和延时,要是18B20接线长一些的话,对时序更严格。。
回复

使用道具 举报

ID:956669 发表于 2022-4-9 21:49 来自手机 | 显示全部楼层
ds18b20就是单总线协议,极有可能是时序不对导致数据就没读好,你可以先自己设一个数据,看看能不能显示,要是可以显示,那就是读的问题,建议看看数据手册对应时序,先调一个简单的复位,看看ds18b20有没有响应工作
回复

使用道具 举报

ID:382454 发表于 2022-4-9 22:28 | 显示全部楼层
网上抄的程序也要自己重新整理过,你这样肯定是乱七八招的。单片机也不知什么型号,时序频率等等。。。。。。。。。!
回复

使用道具 举报

ID:1012747 发表于 2022-4-10 09:57 | 显示全部楼层
移植要考虑目标的硬件环境和源程序的硬件环境的区别。
回复

使用道具 举报

ID:139866 发表于 2022-4-10 14:30 | 显示全部楼层
用示波器测一下波形不就什么都知道了
回复

使用道具 举报

ID:166475 发表于 2022-4-10 15:27 来自手机 | 显示全部楼层
无外乎时序不对
回复

使用道具 举报

ID:166475 发表于 2022-4-10 15:28 来自手机 | 显示全部楼层
用逻辑分析仪测一下就晓得了
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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