关于DS18B20温度测量的小程序,求找错

2019-07-16 01:14发布

本帖最后由 沐雨枫林 于 2013-4-21 22:25 编辑

初学单片机,仿照视频用郭天祥的TX-1C开发板写了个温度计的小程序,温度高于20度时还正常,但以低于20度就出错。用别人的程序试了一下板子,温度测量都正常,应该是代码问题,实在找不出错了,有木有高人能指点一下哈
#include<reg52.h>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int


/**************************************************
DS18B20相关数据定义
**************************************************/
sbit DQ=P2^2;//声明DS18B20

uchar th;//用于存储温度高字节
uchar tl;//用于存储温度低字节

short int temp;//用于存储转换完成以后的温度
float t;






/**************************************************
1602相关数据定义
**************************************************/
sbit lcden=P3^4;
sbit lcdrs=P3^5;

short int tem[5];
uint i;
uint j;

sbit dula=P2^6;
sbit wela=P2^7;






/**************************************************
公共数据定义
**************************************************/
uint time;


/**************************************************
公共函数
**************************************************/

//延时1微秒
void delay1ms()
{
   unsigned char i,j;        
         for(i=0;i<4;i++)
          for(j=0;j<33;j++);                 
}

//延时n微秒
void delaynms(unsigned char n)
{
   unsigned char i;
        for(i=0;i<n;i++)
           delay1ms();
}




/**************************************************
DS18B20操作函数
**************************************************/

//初始化DS18B20
bit Init_DS18B20()
{
        uint flag=1;
        DQ=1;
        for(time=2;time>0;time--);
        DQ=0;
        for(time=200;time>0;time--);
        DQ=1;
        for(time=10;time>0;time--);
        flag=DQ;
        for(time=200;time>0;time--);
        return flag;
}

//从DS18B20读取一个字节
uchar ReadOneChar()
{
        uint i;
        uchar dat;
        for(i=0;i<8;i++)
        {
                DQ=1;
                _nop_();
                DQ=0;
                _nop_();
                DQ=1;
                for(time=0;time<2;time++);
                dat>>=1;
                if(DQ==1)
                {
                        dat|=0x80;
                }else
                {
                        dat|=0x00;
                }
                for(time=0;time<8;time++);
        }
        return dat;
}

//向DS18B20写入一个字节
WriteOneChar(uchar dat)
{
        uchar i;
        for(i=0;i<8;i++)
        {
        
        DQ=1;
        _nop_();
        DQ=0;
        _nop_();
        DQ=dat&0x01;
        for(time=0;time<15;time++);
        DQ=1;
        for(time=0;time<1;time++);
        dat>>=1;
        }
        for(time=0;time<4;time++);
}

//温度换算
void TempByteToInt()
{
        temp=th;
        temp<<=8;
        temp|=tl;
        t=temp*0.0625;
        temp=t*10+0.5;
}

//读取一次温度
void ReadOneTemp()
{
        Init_DS18B20();
        WriteOneChar(0xCC);
        WriteOneChar(0x44);
        delaynms(200);

        Init_DS18B20();
        WriteOneChar(0xCC);
        WriteOneChar(0xBE);

        tl=ReadOneChar();
        th=ReadOneChar();

        TempByteToInt();

}



/**************************************************
1602操作函数
**************************************************/

//向1602写指令
void write_com(uchar com)
{
        lcdrs=0;
        P0=com;
        delaynms(5);
        lcden=1;
        delaynms(5);
        lcden=0;
}

//向1602写数据
void write_data(uchar date)
{
        lcdrs=1;
        P0=date;
        delaynms(5);
        lcden=1;
        delaynms(5);
        lcden=0;
}

//初始化1602
void init_1260()
{
        dula=0;
        wela=0;
        lcden=0;
        write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);
        write_com(0x80);
}

//显示温度
void writeTemp()
{
        if(temp!=0){
                        
                if(temp>0)
                {
                        write_data('+');
                }
                if(temp<0)
                {
                        temp*=-1;
                        write_data('-');
                }
                i=0;
                while(temp){
                        tem=temp%10;
                        temp/=10;
                        i++;
                }
                j=i;
                for(;i>0;i--){
                        if(j==1){
                                write_data('0');
                        }
                        if(i==1){
                                write_data(0x2e);
                        }
                        write_data('0'+tem[i-1]);        
                }
        }else
        {
                write_data('0');
                write_data(0x2E);
                write_data('0');
        }
        write_data(0x43);
        write_data(0xDF);
}

void main()
{
        while(1)
        {
                ReadOneTemp();
                init_1260();
                writeTemp();
                for(time=0;time<20;time++)
                {
                        delaynms(100);
                }
        }
}


低于20度时


20度以上正常 20度以上正常
低于20度时 低于20度时
低于20度时 低于20度时
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
1条回答
动寒川
1楼-- · 2019-07-16 05:05
给你个参考
程序的一部分:
/********************DS18B20初始化操作***************************/
uchar init_DS18B20()
{
                         ucharstatus ;
                         DQ=1;
                         delay10us();       //延时10us
                         DQ=0;
                         delay614us();
                         DQ=1;              //延时等待30us
                         delay10us();
                         delay10us();
                         delay10us();
                         status=DQ;  //这个时间一定要长最少204us
                         delay102us();
                         delay102us();
                         delay102us();
                         delay102us();
                         DQ=1;               //最后总线又拉高
                         returnstatus;
}  
/**************************DS18B20读操作*****************************/
uchar DS18B20_readbyte()
{                        
                         uchari,dat=0;
                         DQ=1;
    _nop_();       //稍微延时1us
                         for(i=0;i<8;i++)
                         {
                            DQ=0;            //最少延时1us
                            _nop_();
                            _nop_();
                            _nop_();
                            dat>>=1;
                            DQ=1;      
                            _nop_();
                            _nop_();
                            if(DQ)dat|=0x80;
                            else
                            dat=dat|0x00;
/****下面的延时时间一定要搞仔细了,时间太短会闪烁,估计是每两个读之间必须得隔离相当长的时间*****/               
                            delay102us();
                            delay102us();
                            delay102us();
                            delay102us();  
                            DQ=1;       //数据线拉高
                         }
                         returndat;
}
/**************************************DS18B20写操作************************************/
void DS18B20_writebyte(uchar dat)
{
                         uchar i;
                         for(i=0;i<8;i++)
                         {
                           
                            DQ=0;
                            DQ=dat&0x01;   //要延时确定时间15us
                            delay10us();
                            delay5us();
                            dat>>=1;         //延时为45us     ,同时需要注意写的时候是一位一位的写。
                            delay10us();
                            delay10us();
                            delay10us();
                            delay10us();
                            delay5us();
                            DQ=1;
                         }
                         DQ=1;                      //数据线最后又拉高
}
/************************************读取DS18B20当前温度值***********************************/
void  read_temperature()
{
                         if(init_DS18B20()==0)
                         {
                            DS18B20_writebyte(0xcc);    //跳过ROM
                            DS18B20_writebyte(0x44);    //温度转换
                          }
                         if(init_DS18B20()==0)                   //注意啊,每一次读写操作都得先要将DS18B20初始化,而且还得确保初始化成功
                          {                                 
                            DS18B20_writebyte(0xcc);    //跳过ROM               
                            DS18B20_writebyte(0xbe);   //读取RAM中温度
                            temperature0=DS18B20_readbyte();
                            temperature1=DS18B20_readbyte();
                         }
                        
}

一周热门 更多>