这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 求助关于ds18b20温度显示的问题恳求个位人士帮忙解决

共10条 1/1 1 跳转至

求助关于ds18b20温度显示的问题恳求个位人士帮忙解决

菜鸟
2012-05-19 13:06:47     打赏

程序::#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
sbit DQ=P1^0;
bdata uchar dat;
sbit dat0=dat^0;
sbit dat7=dat^7;
uchar dp[16]={0,0,1,1,2,3,3,4,5,5,6,6,7,8,8,9};
uchar code segtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xef,0xbf};
uchar dbuf[4]={0,0,0,0};
void disp(void)
  {   uchar i,n,wx;
      wx=0xfe;
   for(n=0;n<4;n++)
    { P2=wx;
      P0=segtab[dbuf[n]];
   if(n==1)  P0=P0&0x7f;
   wx=(wx<<1)+1;
     for(i=1;1<200;i++);
     P0=0xff;
  }
   }
void delay(unsigned int i)
   { unsigned int j;
      for(j=i;j>0;j--);
 }
bit  reset(void)
   { bit flag;
     DQ=0;
  delay(60);
  DQ=1;
  delay(3);
  flag=DQ;
  delay(25);
  return(flag);
 }
void ds18b20_init(void)
  {
     while(1)
   {
     if(!reset())
    {
       DQ=1;
    delay(30);
      break;
     }
   else
      reset();
    }
   }
void wrbyte(uchar t)
   {
     uchar i,dat;
    dat=t;
     for(i=8;i>0;i--)
    {
          DQ=0;
   _nop_();
   DQ=dat&0x01;
   dat=dat>>1;
   delay(5);
   DQ=1;
            delay(1);
     }
 }
uchar rdbyte(void)
    { uchar i;
    uchar dat=0;
    DQ=1;_nop_();
    for(i=8;i>0;i--)
    {
       DQ=0;
    dat>>=1;
    DQ=1;_nop_();_nop_();
    if(DQ)  dat|=0x80;
    delay(30);
    DQ=1;
    _nop_();
  }
   return(dat);
 }
void convert(void)
    {
    ds18b20_init();
    wrbyte(0xcc);
    wrbyte(0x44);
          delay(40);
 }
int readt(void)
    { uchar h,l;
   ds18b20_init();
   wrbyte(0xcc);
   wrbyte(0x44);
   l=rdbyte();
   h=rdbyte();
   return(h*256+l);
     }
void tdatacl(int x)
    {
    bit zf;
    zf=0;
    if(x<0)
      {zf=1;
    x=-x;
    }
   dbuf[0]=dp[x&0x0f];
   x=x>>4;
   dbuf[3]=x/100;
   x=x%100;
   dbuf[2]=x/10;
   dbuf[1]=x%10;
   if(zf==1)
    { if(dbuf[2]==0)
        { dbuf[3]=0xff;
        dbuf[2]=0xbf;
      }
     else
       dbuf[3]=0xbf;
     }
    else
     { if(dbuf[3]==0)
         if(dbuf[2]==0)
        {dbuf[2]=0xff;
         dbuf[3]=0xff;
        }
                      else dbuf[3]=0xff;
      }
  }
void main()
{
    int t;
    uchar i;
 while(1)
 { convert();
   t=rdbyte();
   tdatacl(t);
          for(i=50;i>0;i--)
   disp();
 }
仿真图搞不上来!!下楼继续




关键词: 求助     关于     ds18b20     温度     显示     问题     恳求    

菜鸟
2012-05-19 13:11:49     打赏
2楼

仿真时数码管只亮不显示数字!一直停留在0000!仿真图搞不上来!!帮忙看看程序有没有错误!!如有帮忙改正一下万分感谢!!!


高工
2012-05-19 14:49:09     打赏
3楼
显示0,可能是18b20的数据没传过来,也可能是数码管驱动那部分的问题
所以先确定问题在哪里,一步一步来
可以先不用18B20,直接送数给数码管,看能不能正常显示,
把数码管显示弄好之后,再搞18B20

菜鸟
2012-05-19 15:53:56     打赏
4楼
感谢您的帮助

助工
2012-05-20 15:27:34     打赏
5楼

我当年使用的版本之一。

#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit DS=P3^3;           //定义DS18B20接口

int temp;            

uchar flag1;           

void display(unsigned char *lp,unsigned char lc);//数字的显示函数;lp为指向数组的地址,lc为显示的个数

void delay();//延时子函数,5个空指令

code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
       0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,
       0x40,
       0x39,
       0x00};
   //共阴数码管显示数的组成是 "0-9""0-9有小数点的" "-" "C" "空 表"

unsigned char l_tmpdate[8]={0,0,10,0,0,0,0,0};//定义数组变量,并赋值1,2,3,4,5,6,7,8,就是本程序显示的八个数
int tmp(void);
void tmpchange(void);
void tmpwritebyte(uchar dat);
uchar tmpread(void);
bit tmpreadbit(void);
void dsreset(void);
void delayb(uint count);


void main()               //主函数

{
uchar i;
int l_tmp;
  while(1)
  {
  tmpchange();      //温度转换
 l_tmp=tmp(); //读取温度值
 if(l_tmp<0)  
 l_tmpdate[0]=20; //判断温度为负温度,前面加"-"
 else
 {
 l_tmpdate[0]=l_tmp/1000; //显示百位,这里用1000,是因为我们之前乖以10了
 if(l_tmpdate[0]==0)  
  l_tmpdate[0]=22;//判断温度为正温度且没有上百,前面不显示,查表第12是空
 }
l_tmp=l_tmp%1000;
l_tmpdate[1]=l_tmp/100;//获取十位
l_tmp=l_tmp%100;
l_tmpdate[2]=l_tmp/10;//获取个位再
l_tmpdate[2]+=10;//加入小数点,查表可得出有小数点的排在后10位,所以加10
l_tmpdate[3]=l_tmp%10;//获取小数第一位
l_tmpdate[4]=21;

for(i=0;i<10;i++){  //循环输出10次,提高亮度
display(l_tmpdate,5);

   }             
}
 

}

void display(unsigned char *lp,unsigned char lc)//显示
{
 unsigned char i;  //定义变量
 P2=0;     //端口2为输出
 P1=P1&0xF8;    //将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管
 for(i=0;i<lc;i++){  //循环显示
 P2=table[lp[i]];  //查表法得到要显示数字的数码段
 delay();    //延时5个空指令 
 if(i==7)    //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据
  break;
 P2=0;     //清0端口,准备显示下位
 P1++;     //下一位数码管
 }
}
void delay(void)        //空5个指令
{
_nop_();_nop_();_nop_();_nop_();_nop_();
}
void delayb(uint count)      //delay

{

  uint i;

  while(count)

  {

    i=200;

    while(i>0)

    i--;

    count--;

  }

}


void dsreset(void)       //DS18B20初始化

{

  uint i;               

  DS=0;

  i=103;

  while(i>0)i--;

  DS=1;

  i=4;

  while(i>0)i--;

}

 

bit tmpreadbit(void)       // 读一位

{

   uint i;

   bit dat;

   DS=0;i++;          //小延时一下

   DS=1;i++;i++;

   dat=DS;

   i=8;while(i>0)i--;

   return (dat);

}

 

uchar tmpread(void)   //读一个字节

{

  uchar i,j,dat;

  dat=0;

  for(i=1;i<=8;i++)

  {

    j=tmpreadbit();

    dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好//一个字节在DAT里

  }

  return(dat);             //将一个字节数据返回

}

 

void tmpwritebyte(uchar dat)  

{                           //写一个字节到DS18B20里

  uint i;

  uchar j;

  bit testb;

  for(j=1;j<=8;j++)

  {

    testb=dat&0x01;

    dat=dat>>1;

    if(testb)     // 写1部分

    {

      DS=0;

      i++;i++;

      DS=1;

      i=8;while(i>0)i--;

    }

    else

    {

      DS=0;       //写0部分

      i=8;while(i>0)i--;

      DS=1;

      i++;i++;

    }

  }

}

 

void tmpchange(void)  //发送温度转换命令

{

  dsreset();             //初始化DS18B20

  delayb(1);             //延时

  tmpwritebyte(0xcc);  // 跳过序列号命令

  tmpwritebyte(0x44);  //发送温度转换命令

}

int tmp()               //获得温度

{

  float tt;

  uchar a,b;

  dsreset();

  delayb(1);

  tmpwritebyte(0xcc);  

  tmpwritebyte(0xbe);    //发送读取数据命令

  a=tmpread();          //连续读两个字节数据

  b=tmpread();

  temp=b;

  temp<<=8;            

  temp=temp|a;         //两字节合成一个整型变量。

  tt=temp*0.0625;       //得到真实十进制温度值,因为DS18B20

//可以精确到0.0625度,所以读回数据的最低位代表的是

//0.0625度。

  temp=tt*10+0.5;   //放大十倍,这样做的目的将小数点后第一位

//也转换为可显示数字,同时进行一个四舍五入操作。

  return temp;     //返回温度值

}

void readrom()          //read the serial 读取温度传感器的序列号

{                      //本程序中没有用到此函数

  uchar sn1,sn2;

  dsreset();

  delayb(1);

  tmpwritebyte(0x33);

  sn1=tmpread();

  sn2=tmpread();

}

void delay10ms()           
  {

    uchar a,b;

    for(a=10;a>0;a--)

      for(b=60;b>0;b--);

}

 


菜鸟
2012-05-21 00:07:12     打赏
6楼
特别感谢!!!

高工
2012-05-22 22:38:09     打赏
7楼
时序一定要搞对行。

菜鸟
2012-06-28 13:24:48     打赏
8楼

给点建议:
首先能显示出任意数字,其次在处理DS18B20

DS18B20的代码到处可以下载到,但是移植到自己的工程中很多时候不能用,问题在哪?
DS18B20有非常严格的时序要求,你要根据自己的主频去修改延时函数的参数,这个事极其重要的


院士
2012-06-28 13:43:15     打赏
9楼
非常赞同。
我觉得ds18b20的程序主要是延时的问题。

高工
2012-06-29 12:55:53     打赏
10楼
系统时钟不一样,造成延时也不一样
+1

共10条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]