打印

关于DS18B20 温度传感器的问题

[复制链接]
2681|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
天凡云赐|  楼主 | 2015-5-7 12:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序如下:
#include<reg51.h>
#include<intrins.h>
#define lcd P0
#define uchar unsigned char
#define uint unsigned int

sbit RS=P2^6;
sbit E=P2^7;
sbit RW=P2^5;

sbit DS_DQ=P3^7;
sbit led=P1^7;

uint xum;
uchar flag;

uchar code table[]="wendu";
uchar code table1[]="   . C";

void delay_long(uint delay)         //延迟函数
{
   uchar i,j;
   for(i=delay;i>0;i--)
    for(j=110;j>0;j--);
        }


void tempdelay(uint us)
{
   while(us--);
   }



void delay(uint count)
{
  uint i;
  while(count)
  {
   i=200;
   while(i>0)
   i--;
   count--;
   }
  }




//  DS温度传感器部分



  
  void  init_DS()                  //初始化DS总线
{
   DS_DQ=1;
   _nop_();
   DS_DQ=0;
   tempdelay(80);
   _nop_();
   DS_DQ=1;
   tempdelay(5);
   _nop_();
   _nop_();
   _nop_();
   if(DS_DQ==0)
   flag=1;
        else
        flag=0;
        tempdelay(20);
        _nop_();
        _nop_();
        DS_DQ=1;
        }
            



  void DS_writeBY(uchar BY)         //写字节函数
{
  uchar j;
  bit testb;

  for(j=0;j<8;j++)
  {
         testb=BY&0x01;                                       
         BY=BY>>1;                                                 
           if(testb)
         {
           DS_DQ=0;
           _nop_();
           _nop_();
           DS_DQ=1;
           tempdelay(5);
           }
         else
         {
          DS_DQ=0;
          tempdelay(8);
          DS_DQ=1;
          _nop_();
          _nop_();
          }
                                                            
         }
  }



  bit DS_readBIT()
  {
        bit dat;
        DS_DQ=0;
        _nop_();
        DS_DQ=1;
        _nop_();
        _nop_();
        dat=DS_DQ;
        tempdelay(10);

        return(dat);
        }



    uchar DS_readBY()              //读一个字节
{
   uchar k,i,date;
   date=0;
    for(k=0;k<8;k++)
   {
      i=DS_readBIT();
    date=(i<<8)|(date>>1);        //date从最低位开始读 J从最高位开始传输       
         
     }

        return (date);
         
}



  void DS_zhuanhuan_com()                   //温度转换指令
{
   init_DS();                                        //初始化
   delay(1);
   DS_writeBY(0xcc);
   DS_writeBY(0x44);                         //开始温度转换 0X44
                                         //温度转换需要时间 具体 参考手册
        }




  uchar read_DS_wendu()                     //读取温度 因为有正负 所以用int 类型
{
   uchar tml=0;
   uchar tmh=0;
   float xum1;

   init_DS();
   delay(1);
   DS_writeBY(0xcc);
   DS_writeBY(0xbe);
                                  
   tml=DS_readBY();                                   //温度值16位 低位
   tmh=DS_readBY();                                   // 高位
    xum=tmh;                                           //读低位
    xum<<=8;                                           //左移8位
    xum|=tml;                                           //或上高位
        xum1=xum*0.0625;
        xum=xum1*10+0.5;

   return xum;
  }








// LCD部分




   void lcd_write_com(uchar xun)
  {
     RS=0;
         RW=0;
         lcd=xun;
         delay(5);
         E=1;
         E=0;
         }




  void lcd_write_date(uchar xun1)
  {
     RS=1;
         RW=0;
         lcd=xun1;
         delay(5);
         E=1;
         E=0;
         }


   void init_lcd()
{
        uchar i,j;

        lcd_write_com(0x38);
        lcd_write_com(0x0c);
        lcd_write_com(0x06);
        lcd_write_com(0x01);

        lcd_write_com(0x80);

        for(i=0;i<5;i++)
         {
           lcd_write_date(table[i]);
           delay(20);
           }

         lcd_write_com(0xc0);

        for(j=0;j<6;j++)
         {
          lcd_write_date(table1[j]);
          delay(20);
          }


        }


        void LCD_xianshi(uint num)
  {
             uchar bai,shi,ge;

       
           bai=num/100;
           shi=(num%100)/10;
           ge=(num%100)%10;


         lcd_write_com(0xc1);
         lcd_write_date(0x30+bai);

         lcd_write_com(0xc2);
         lcd_write_date(0x30+shi);

         lcd_write_com(0xc4);
         lcd_write_date(0x30+ge);

        }







  //   主函数部分


void main()
{
  uchar c;
        init_lcd();
        DS_zhuanhuan_com();
    while(1)
   {
                for(c=25;c>0;c--)
           {
                LCD_xianshi(read_DS_wendu);   
                led=flag;
                }                  
         }
        }  


程序固定显示90.6C 请问是怎么回事啊??时序我查了很多次应该没问题啊  

不过在调试的时候keil无法设置DS18B20程序段的断点是怎么回事啊~~

求高手帮看看 !!万分感谢!

相关帖子

沙发
天凡云赐|  楼主 | 2015-5-7 12:35 | 只看该作者
  uchar DS_readBY()              //读一个字节
{
   uchar k,i,date;
   date=0;
    for(k=0;k<8;k++)
   {
      i=DS_readBIT();
    date=(i<<8)|(date>>1);        //date从最低位开始读 J从最高位开始传输     


这里已经改成 date=(i<<7)|(date>>1);了 但是读数还是固定90.6 百思不得其解啊~求帮助~

使用特权

评论回复
板凳
ayb_ice| | 2015-5-7 13:40 | 只看该作者
天凡云赐 发表于 2015-5-7 12:35
uchar DS_readBY()              //读一个字节
{
   uchar k,i,date;

改为
i=DS_readBIT();
date >>= 1;
if(i != 0){
    date |= 0x80;
}

使用特权

评论回复
地板
天凡云赐|  楼主 | 2015-5-7 14:15 | 只看该作者
ayb_ice 发表于 2015-5-7 13:40
改为
i=DS_readBIT();
date >>= 1;

谢谢大哥 可以帮忙解答 我改成这样了
    uchar DS_readBY()              //读一个字节
{
   uchar k,i,date;
   date=0;
   for(k=0;k<8;k++)
        {
          i=DS_readBIT();
          date>>=1;
          if(i!=0)
          {
            date|=0x80;
                }
         }
        return (date);
         
}

这个对吗? 我刚才烧录进去 发现还是显示90.6 没有变化啊

使用特权

评论回复
5
ningling_21| | 2015-5-7 14:25 | 只看该作者
天凡云赐 发表于 2015-5-7 14:15
谢谢大哥 可以帮忙解答 我改成这样了
    uchar DS_readBY()              //读一个字节
{

对照18B20芯片的资料和你用示波器的实测的波形对比,看看哪里不对再慢慢改

使用特权

评论回复
6
天凡云赐|  楼主 | 2015-5-7 14:26 | 只看该作者
ningling_21 发表于 2015-5-7 14:25
对照18B20芯片的资料和你用示波器的实测的波形对比,看看哪里不对再慢慢改 ...

悲剧了大哥..我这里没有示波器~

使用特权

评论回复
7
ningling_21| | 2015-5-7 14:30 | 只看该作者
天凡云赐 发表于 2015-5-7 14:26
悲剧了大哥..我这里没有示波器~

那只能慢慢摸索着调试(先确认器件有没有应答),或者调用别人写好的程序

使用特权

评论回复
8
ayb_ice| | 2015-5-7 14:41 | 只看该作者
天凡云赐 发表于 2015-5-7 14:15
谢谢大哥 可以帮忙解答 我改成这样了
    uchar DS_readBY()              //读一个字节
{

一个uchar型变量左移8位就等于0了

改了没有效果,说明其它地方还有问题

使用特权

评论回复
9
TJJ14520| | 2015-5-7 19:22 | 只看该作者
你的初始化写错了,好好对应下时序图,我帮你改了下,你试试看
void  init_DS()                  //初始化DS总线
{
   DS_DQ=0;
   tempdelay(500);
   DS_DQ=1;
   tempdelay(80);
  tempdelay(500);
   if(DS_DQ==0)
   flag=1;
    else
    flag=0;
}
      

使用特权

评论回复
10
TJJ14520| | 2015-5-7 19:31 | 只看该作者
正因为你初始化失败,才导致你无法在ds18b20的程序里设置断点,因为程序不会跑到这里来

使用特权

评论回复
11
天凡云赐|  楼主 | 2015-5-7 21:05 | 只看该作者
TJJ14520 发表于 2015-5-7 19:31
正因为你初始化失败,才导致你无法在ds18b20的程序里设置断点,因为程序不会跑到这里来 ...

谢谢你啊 大哥  不过显示结果还是90.6 没有变 不过可以设置断点了 刚才是怎么错了呢? 不过只有初始化和写那里可以设置断点 读依然不能设置断点

使用特权

评论回复
12
枯木梅花| | 2015-5-7 21:16 | 只看该作者
换个18B20试试

使用特权

评论回复
13
TJJ14520| | 2015-5-7 21:23 | 只看该作者
天凡云赐 发表于 2015-5-7 21:05
谢谢你啊 大哥  不过显示结果还是90.6 没有变 不过可以设置断点了 刚才是怎么错了呢? 不过只有初始化和 ...

改了初始化程序还是不行么?

使用特权

评论回复
14
TJJ14520| | 2015-5-7 21:24 | 只看该作者
TJJ14520 发表于 2015-5-7 21:23
改了初始化程序还是不行么?

你把初始化部分改成我给你的那个

使用特权

评论回复
15
天凡云赐|  楼主 | 2015-5-7 21:25 | 只看该作者
TJJ14520 发表于 2015-5-7 21:24
你把初始化部分改成我给你的那个

就是改的您给我的这个 依然还是90.6C 不过初始化和写函数可以设置断点了 不过读依然不行

使用特权

评论回复
16
天凡云赐|  楼主 | 2015-5-7 21:26 | 只看该作者

我用的开发板和PROTUES 都一样的

使用特权

评论回复
17
TJJ14520| | 2015-5-7 21:32 | 只看该作者
天凡云赐 发表于 2015-5-7 21:25
就是改的您给我的这个 依然还是90.6C 不过初始化和写函数可以设置断点了 不过读依然不行 ...

你的读函数有问题,今天我没空了,明天上午再跟你说详细的

使用特权

评论回复
18
天凡云赐|  楼主 | 2015-5-7 22:11 | 只看该作者
TJJ14520 发表于 2015-5-7 21:32
你的读函数有问题,今天我没空了,明天上午再跟你说详细的

好的 多麻烦大哥了 如果大哥方便 不知能否留个QQ? 好向您请教

使用特权

评论回复
19
jordan1111| | 2015-5-8 08:37 | 只看该作者
你的主函数只读了一次把。温度不会更新。

使用特权

评论回复
20
jordan1111| | 2015-5-8 08:41 | 只看该作者
把这个加到循环里面看看。 DS_zhuanhuan_com();

使用特权

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

本版积分规则

5

主题

60

帖子

1

粉丝