• DS18B20


    DS18B20驱动 
    [ 2012-5-14 12:01:00 | By: 吴师傅 ]
     
    14

    .概述

    DS18B20是一种单总线数字温度传感器。測试温度范围-55-125℃,温度数据位可配置为9101112位,相应的刻度值分别为0.5℃、0.25℃、0.125℃、0.0625℃,相应的最长转换时间分别为93.75ms187.5ms375ms750ms。出厂默认配置为12位数据,刻度值为0.0625℃,最长转换时间为750ms。从以上数据能够看出,DS18B20数据位越低、转换时间越短、反应越快、精度越低。

    单总线,意味着没有时钟线,仅仅有一根通信线。单总线读写数据是靠控制起始时间和採样时间来完毕,所以时序要求非常严格,这也是DS18B20驱动编程的难点。

    须要注意的是,DS18B20和同一系列的DS18S20,在读写上,时序、命令一致,但因温度值存放的位置不一样,对温度数据的处理也不一样,所以程序不能直接套用。

    .电路设计

    WSF-51DB开发板上,利用AT89S52单片机的P1.1脚来驱动DS18B20,上拉电阻阻值为4.7K欧姆。DS18B20的上拉电阻的阻值是一个须要注意的參数,假设DS18B20放置的位置离电路板较远,须要用较长的电缆来连接时,上拉电阻要对应减小,以弥补线路损耗,并且连接电缆要选用优质的三芯带屏蔽层的电缆,否则不能正常读写数据。

                        

                      

    .软件设计

    /*****************************************************************

    *程序名称:DS18B20驱动

    *程序功能:读写DS18B20,数码管显示温度值,温度值精度为0.1度。

    *开发工具:WSF-51DB开发板

    * MCU型号:AT89S52-24PU

    *时钟频率:11.0592-12MHZ

    *程序作者:吴师傅

    *版权说明:吴师傅版权全部,转载请注明来源和作者。

    *****************************************************************/

    #i nclude <reg52.h>

    #i nclude <intrins.h>

    unsigned char tempflag,fraction,tempr;

    unsigned char code segmcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

    //共阴极数码管段码0-9

    unsigned char code bitcode[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

    //8位共阴极数码管位码

    unsigned char code fractioncode[]={0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,9};

    //DS18B20的小数部分的0-f刻度转换为0-9刻度的查找表,将精度化为0.1

    sbit ser=P2^0;//74HC595串行数据输入

    sbit oe=P2^1;//74HC595使能

    sbit rclk=P2^2; //74HC595数据锁存

    sbit srclk=P2^3;// 74HC595串行时钟

    sbit DQ=P1^1; //温度总线

     

    //延时函数(12MHZ晶振):

    void Delayus(unsigned char t)

    {  //此函数精确计算:18+6*(t-1)=延时时间(us)

        while(t--);

    }

     

    //延时ms延时函数:

    void Delayms(unsigned int t)

    {

           unsigned int i,j;

           for(i=t;i>0;i--)

                   for(j=0;j<120;j++);

    }

     

    //随意位数码管显示一个字符函数:

    void DTDisplayChar(unsigned char segmd,unsigned char bitd )//数码管段码和数码管位码

    {

            unsigned char i;

            unsigned int dat;

            oe=1;//输出为高阻

            dat=bitd;

            dat=dat<<8|segmd; //位码段码合并为一个int型数据

            for(i=0;i<16;i++)//16位数据从高位依次移入74HC595

            {

                     ser=(dat&0x8000)?1:0; //推断最高位,为真取1,为假取0

                     srclk=1;    //上升沿送数据

                     srclk=0;

                     dat<<=1;   //左移取下一位

            }

            rclk=1;//74HC595锁存数据

            rclk=0;

            oe=0;//输出数据

    }

     

    //DS18B20复位函数:

    void Reset18B20(void)

    {

            DQ=0;//拉低,開始复位操作

            Delayus(100);//延时至少480us

            DQ=1;//拉高,释放总线控制权

            while(DQ);//等待器件应答(器件拉低),约15-60us后

            while(!DQ);//应答脉冲出现后,等待器件拉高,约60-240us后

    }

    //DS18B20写命令函数:

    void Write18B20(unsigned char com)

    {

            unsigned char i;

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

            {   

                   DQ=0;//開始写操作

                   _nop_(); _nop_();//至少延时1us

                   DQ=com&0x01;//写数据

                   Delayus(2);//延时,器件在45us内採样

                   DQ=1;//释放总线控制权

                   com>>=1; //右移1位,写下一位

            }

    }

     

    //DS18B20读数据函数:

    unsigned char Read18B20()

    {

              unsigned char i,rdata=0;

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

              {

                       DQ=0;//開始读操作

                       _nop_();_nop_();//至少延时1us

                       DQ=1;//释放总线控制权,15us内要读取数据

                       if(DQ==1) rdata|=0x01<<i;

                       Delayus(10);//延时要大于45us.0时45us后器件才拉高总线

               }

               return rdata;

    }

     

    //读出温度函数:

     void Read18B20Temperature()

    {

            unsigned char templ,temph,temp;

            unsigned int tempv;

            Reset18B20();//复位

            Write18B20(0xcc);//写命令,跳过ROM编码命令

            Write18B20(0x44);//转换命令

         while(!DQ);//等待转换完毕

            Reset18B20();//复位

            Write18B20(0xcc);//写命令,跳过ROM编码命令

            Write18B20(0xbe);//读取暂存器字节命令

            templ=Read18B20();//读低字节

            temph=Read18B20();//读高字节

            Reset18B20();//复位

            tempv=temph;

            tempv=tempv<<8|templ;//两个字节合并为一个int型数据

            temp=(unsigned char)(tempv>>4);//去掉小数部分,化成char型数据

            if((temph&0x80)==0x80)//假设是负温度

            {

                  tempflag=1; //负号显示

                  tempr=~temp+1; //实际温度值为读取值的补码

                  fraction=fractioncode[(~templ+1)&0x0f];

    //取小数部分补码,将16刻度转换为10刻度,精度为0.1

             }

             else//假设是正温度

             {

                    tempflag=0;//正温度,负号不显示

                    tempr=temp;//

                    fraction=fractioncode[templ&0x0f];

    //取小数部分,将16刻度转换为10刻度,精度为0.1

              }     

    }

       

    //主函数:

    int main(void)

    {

          tempflag=0;

          while(1)

          {

                  Read18B20Temperature();//读取温度值

                  DTDisplayChar(segmcode[fraction],0x7f);//显示小数部分

                  Delayms(1);

                  DTDisplayChar(segmcode[tempr%10]|0x80,0xbf);//显示个位和小数点

                  Delayms(1);

                  DTDisplayChar(segmcode[tempr%100/10],0xdf);//显示十位

                  Delayms(1);

                  if(tempflag==1) DTDisplayChar(0x40,0xef);//假设是负温度就显示“-

                  else DTDisplayChar(segmcode[tempr/100],0xef);//显示百位

                  Delayms(1);

                  DTDisplayChar(0xff,0xff);//均衡数码管亮度

          }

          return 0;

    }

     
  • 相关阅读:
    java反编译工具
    javascript
    微信小程序
    微信小程序
    微信小程序
    微信小程序
    微信小程序
    微信小程序
    微信小程序
    微信小程序
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/3939192.html
Copyright © 2020-2023  润新知