打印

ds18b20测温

[复制链接]
1198|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wll711|  楼主 | 2015-5-15 11:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
调了好久,总是显示30多度,可是现在室温只有20多度啊,而且有时还跳到60多。时序也用示波器查了很久,实在是没招了,还望有大侠能给出出主意。
#include<reg51.h>
#include<intrins.h>
#include<math.h>
#include<stdio.h>
#include<string.h>


typedef unsigned char uchar;
typedef unsigned int uint;


bit Measure_temp_flag;
bit Display_flag;
bit flag;
sbit LE=P2^4;//573锁存端
sbit DQ=P3^7;//DS18B20的数据通信线
int tpl_test,tph_test;//温度值的低位和高位字节
int temp_Dis[]={0,0,0,0,0};//测试温度的十进制数值
int temp_Set_Dis[]={0,0,0,0};//设置温度的十进制数值
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79}; //共阴字符表,不显示小数点(0~9,P,I,d,F,灭)
unsigned char code table_p[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //共阴字符表,显示小数点(0~9)
unsigned char code table_Wei[6]= {0x02,0x01,0x00,0x05,0x04,0x03};//位选,对应U3低位中位高位,u5低位中位高位

uint TIM0;//定时器0发生定时的次数
uint TIM1;//定时器1发生定时的次数
uint INTO_TIME;//外中断0发生次数


void display(int Dis[], uint U_D)
{
        int i=0,j=0;
        if(U_D==0)//U3数码管显示测试的温度
        {
                for(i=0;i<3;i++)//选择某一位数码管
                {
                        P2&=0xf0;
                        P2|=table_Wei[i];
                        LE=1;
                        if(i==1)
                        {
                                P0=table_p[Dis[i]];//中间位显示带小数点的
                        }
                        else
                        {
                                P0=table[Dis[i]];//送要显示的数
                        }
                        LE=0;
                        for(j=0;j<=1000;j++);//延时
                //        delay(2);
                //        P0=0x00;
                }
        }
        if(U_D==1)//U5数码管显示设置的温度
        {
                for(i=0;i<3;i++)//选择某一位数码管
                {
                        P2&=0xf0;
                        P2=P2|table_Wei[i+3];
                        LE=1;
                        if(i==1)//if((i==1)&&(INTO_TIME==1))
                        {
                                P0=table_p[Dis[i]];//中间位显示带小数点的
                        }
                        else P0=table[Dis[i]];//送要显示的数
                        LE=0;
                        for(j=0;j<=1000;j++);//延时
                }
        }
}

void BtoD(int value_h,int value_l)
{
        uint j=0;
        uint tempD;
        int tzheng,txiao,a,b;
        float k;
       
        a=(value_l&0xf0)>>4;b=value_h;
       
        tzheng=a|b;//取整       
        txiao=value_l&0x0f; //取小数

        if(value_h&0x80)//说明是负数
        {
                tzheng=~tzheng;
                txiao=(txiao^0x0f)+0x01;
                k=((float)(tzheng|0x80)+(float)txiao*0.0625);
        }
        else//说明是正数
        {
                k=(float)(b*16+a)+(float)(txiao*0.0625);       
        }
        k=k*10;//只取前三位
        tempD=(uint)k;
       
        while(tempD!=0)//分离用于显示,temp_Dis[0]最低位,其次为temp_Dis[1],temp_Dis[2],其中temp_Dis[1]要求显示小数点
   {
      temp_Dis[j]=tempD%10;
      tempD/=10;
      j++;
   }
       
}

void delay2us(uchar t)//延时2us,误差最大5us
{
        while(--t);
}
void delay(unsigned int t)//延时函数,实测延时1.52ms
{
        unsigned int i;
        while(t--)
        {
                for(i=0;i<125;i++)//延时1ms
                {}
        }
}

bit TxReset(void)
{
                DQ=1;//DQ复位;
                delay2us(4);//稍做延迟,实测拉低14us

                DQ=0;
                delay2us(240);//拉低至少480us,本操作实测拉低490us
                delay2us(80);//实测拉低170us;
                                       
                DQ=1;
                delay2us(25);//实测拉高56us

                flag=DQ;
                delay2us(100);
                DQ=1;
                return (flag);
}

void WrByte(uchar dat)//写时序
{
        uint i;
        bit btmp;
        for(i=0;i<8;i++)
        {
                btmp=dat&0x01;
                dat>>=1;
                if(btmp)//写1
                {
                        DQ=1;
                        _nop_();
                        DQ=0;
                        _nop_();
                        DQ=1;
                        delay2us(30);//写1至少释放60us,实测
                }
                else//写0
                {
                        DQ=1;
                        _nop_();
                        DQ=0;
                        delay2us(30);//写0拉低至少60us
                        DQ=1;
                        _nop_();
                        _nop_();
                }
        delay2us(5);
        }
}

uchar RdByte(void)
{
        uchar i,dat;
        dat=0;
        for(i=0;i<8;i++)
        {
                DQ=1;
                _nop_();
                DQ=0;
                _nop_();
                DQ=1;
                delay2us(1);//实测
                if(DQ)
                {dat|=0x80;}
                dat>>=1;
                delay2us(20);
               
        }
        return (dat);
}

void t_test(void)
{
       
        TxReset();//产生复位脉冲,初始化DS18B20
        if(flag==0)
        {
        WrByte(0xcc);//0xcc表示DS18B20的skip rom命令
        WrByte(0x44);//DS18B20温度转换命令
        delay(200);//实测延时304ms
        delay(200);
        TxReset();
        WrByte(0xcc);
        WrByte(0xbe);//DS18B20的Read Scratchpad 命令,用于读取暂存器内容
        tpl_test=RdByte();//温度值的低位字节
        tph_test=RdByte();//温度值的高位字节  
   }
                                                                                    
}

void timer0(void) interrupt 1 using 1//定时器0
{
        TIM0++;
        P2_6=0;
         if(TIM0==500)//1000ms
        {
                Measure_temp_flag=1;
                TIM0=0;
                P2_6=!P2_6;
        }
        TH0=-(10000/256);// 重新装载T0定时器
        TL0=-(10000%256);
       
}

void main(void)
{

        P2_6=1;P2_7=1;//初始灭灯
        Measure_temp_flag=0;   

   TIM0=0;TIM1=0;
   INTO_TIME=0;

        IE=0x8B;//打开ET1,ET0,EX0
        IP=0x01;//INTO优先级最高
        TMOD=0x11;//T1T0同为定时器,方式1
       
        TR0=1;//定时器0启动
        TH0=-(10000/256);//
        TL0=-(10000%256);

        do
        {
       
                do
                {
                BtoD(tph_test,tpl_test);
                //调用显示温度子程序
                display(temp_Dis,0);//数码管U3显示
                       
                }while(!Measure_temp_flag);
                        Measure_temp_flag=0;
                        t_test();        //调用测温函数       
        }while(1);

}

相关帖子

沙发
wll711|  楼主 | 2015-5-15 11:07 | 只看该作者
用的是STC89C52,12M的晶振

使用特权

评论回复
板凳
XZL| | 2015-5-15 13:23 | 只看该作者
18B20的程序有好多,你百度一下吧!
问题应该还是出在程序上了

使用特权

评论回复
地板
ningling_21| | 2015-5-15 14:08 | 只看该作者
通电后芯片本身也会发热,关键看加热芯片时温度是否也会升高

使用特权

评论回复
5
dirtwillfly| | 2015-5-15 17:14 | 只看该作者
经过校准了吗?

使用特权

评论回复
6
wll711|  楼主 | 2015-5-18 09:13 | 只看该作者

什么叫 校准? 能详细说下吗?

使用特权

评论回复
7
wll711|  楼主 | 2015-5-18 09:15 | 只看该作者
XZL 发表于 2015-5-15 13:23
18B20的程序有好多,你百度一下吧!
问题应该还是出在程序上了

百度很多了,参考别人的程序,对着18b20的文档用示波器调的时序。。。

使用特权

评论回复
8
DianGongN| | 2015-5-18 10:23 | 只看该作者
硬件上,引线先做成最短,上拉电阻用推荐值.先确保硬件没有问题.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

4

帖子

0

粉丝