原创 DS18B2的取温程序

2007-8-13 19:45 5759 10 10 分类: MCU/ 嵌入式

/*<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


温度传感器DS18B20的控制程序


从一blog里找的程序,感觉好用


这里给大家发出来,有少许改动


大家改改也可以自己用,硬件电


路很简单,只要把B20DQ端接


P1.4就可以了。但是要注间,个


人在调试中发现B20对时序要求


相当严格,所用调用读温度程序


时,关了中断,不然得到的结果


与实际相差万分。本程序用来做


与计时有关的程序不太好用。但


也能让大家更好的了解B20,故在


此帖出来。


 


注意:B20一定要外接电源,否则


下面的程序不可用。至于单片机,


可任意选用,51都行。P0口有上拉。


用作LED段选,P00~P07->a~dp.


P2口接LED位选。P20~P27接1~8


位LED,1在右,7在左。


 


*/


 


#define uchar unsigned char


#define  uint  unsigned int


#include<reg51.h>


#include <intrins.h> // _nop_()function


 


 


 


#define NOP _nop_();_nop_();_nop_()


 


uchar code ledcode[]={0x<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />3f,0x06,0x5b,0x4f,


                       0x66,0x6d,0x7d,0x07,


                       0x7f,0x6f,0x77,0x7c,


                       0x39,0x5e,0x79,0x71,0x00,0x40,0x80


      


};


uchar code ledbitselect[8]={1,2,4,8,0x10,0x20,0x40,0x80};


uchar dispbuf[8]={16,16,16,16,16,16,16,12};


uchar cnt_t;


uint count_int;


 


sbit PORT_BIT_1820=P1^4;


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


void wr_1820(uchar  val);


float get_tmpr(void);


void init_1820(void);


void wr_1820(uchar val);


float rd_1820(void);


void delay1(uchar t);


void start(void);


 


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


void delay1(uchar t)


{


   uchar i;


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


         {


         _nop_();


         }


 


}


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


void start(void)


{


     init_1820();


      wr_1820(0xcc);            //跳过读ROM


    wr_1820(0x44);


  }


 


 


float get_tmpr(void)


{


       float tmpr;


       uchar  cnt,i;


       cnt=0;


ag: EA="0";                          //慎用


      init_1820();


      wr_1820(0xcc);            //跳过读序列号的操作


    wr_1820(0x44);            //启动温度转换


     delay1(125);


    init_1820();


       wr_1820(0xcc);            //跳过读序列号的操作


       wr_1820(0xbe);            //读温度寄存器


      tmpr=rd_1820();           //读温度


      init_1820();


      wr_1820(0xcc);           


       wr_1820(0x44);   /* start convert */


     EA=1;                            //慎用


       if (tmpr<-10.0) tmpr="25".0;


     return tmpr;


}


 


void init_1820(void)


{


       uchar  i;


       PORT_BIT_1820=1;       //1.6us


       PORT_BIT_1820=0; /* 1--8+7us */


       for(i=0;i<100;i++);/* delay 400--960us */  //300us


      PORT_BIT_1820=1;


      for(i=0;i<200;i++)  /* delay 15--60us */


           { if (PORT_BIT_1820==0) break;}


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


           { if (PORT_BIT_1820==1)  break;


 


          }


      for(i=0;i<60;i++); /* delay 480us */


}


 


void wr_1820(uchar  val)


{


      uchar i,j;


   PORT_BIT_1820=1;  //1.6us


   NOP;              //3.6us


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


            { PORT_BIT_1820=0;


                 NOP;


            NOP;  /* delay 6us  */


                 if ((val&0x01)==1)


                     PORT_BIT_1820=1;


                 else


                     PORT_BIT_1820=0;


     for(i=0;i<6;i++);    /* delay 5-6 us */   //20.6us


     PORT_BIT_1820=1;


     val=val>>1;


   }


}


 


float rd_1820(void)


{ uchar  j,i,k,tt[9],vv;


  float tmpr;


  vv=0;


  for(k=0;k<9;k++)


    {  for(j=0;j<8;j++)


      {


            PORT_BIT_1820=0;


             NOP;NOP;NOP;NOP;              //delay 12 us


             PORT_BIT_1820=1;


             vv=vv>>1;


             if(PORT_BIT_1820) vv="vv|0x80";


 


             for(i=0;i<6;i++);/*delay 120 us */


             PORT_BIT_1820=1;


      }


      tt[k]=vv;


     }


   i=tt[1]&0xf8;


   if( (i!=0)&&(i!=0xf8)) return -100.0;


 


   tmpr=tt[1]*256.0;


   tmpr=(tmpr+tt[0])/16.0;


   if(tmpr>100.0 ) return -100.0;


   return  tmpr;


}


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


 


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


main()


{


        float tt;


        uchar i;


        TMOD=0X02;


        TL0=0X06;


        TH0=0X06;


        IE=0x82;


        TR0=1;                               //设好了定时器,方便调试,但使用时要小心。


        EA=0;


        init_1820();


        wr_1820(0x33);


        start();


        count_int=0;


       cnt_t=0;


        while(1)


       {


              tt=get_tmpr();


              _nop_();


             dispbuf[7]=(uchar)tt/10;


              dispbuf[6]=(uchar)tt%10;


              dispbuf[5]=(uchar)tt*10%10;


              dispbuf[4]=(uchar)tt*100%10;


              //


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


              {


                     P2=ledbitselect;


                     P0=ledcode[dispbuf];


                     if(i==6)P0=ledcode[dispbuf]|0x80;


                     delay1(100);


              }


              //


       }


 


}


 


void time0() interrupt 1


{    


       count_int++;


       if(count_int=200)


       {


              count_int=0;


              cnt_t++;


              if(cnt_t==8)cnt_t=0;


              P2=ledbitselect[cnt_t];


              P0=ledcode[dispbuf[cnt_t]];


              if(cnt_t==6)P0=ledcode[dispbuf[cnt_t]]|0x80;


       }


}


 


/*


这个程序中用的分辨率是12位,程序我本人都没有完全消化,还不会改分辨率,如果有会的朋友,希望能给我留言或者emailto:lbj_01@163.com


 这里的中断用来扫描显示。但闪烁,反不如用主函数中的显示程序。


 

中断对B20读数有很大的影响,希望大家在使用中注意。


 


 


*/

文章评论0条评论)

登录后参与讨论
我要评论
0
10
关闭 站长推荐上一条 /2 下一条