找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2106|回復: 0
收起左側

注釋詳細的51單片機讀取DS18B20溫度C語言源代碼

[復制鏈接]
ID:618342 發(fā)表于 2020-9-16 15:18 | 顯示全部樓層 |閱讀模式
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uchar unsigned  char

  4. sbit   DQ=P3^7;
  5. bdata  uchar dat;
  6. sbit   dat0=dat^0;
  7. sbit   dat7=dat^7;
  8. uchar dp[16]={0,0,1,1,2,3,3,4,5,5,6,6,7,8,8,9};

  9. uchar code segtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
  10. 0x80,0x90, 0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0x8c,0xbf,0xff};

  11. uchar dbuf[4]={0,0,0,0x12};

  12. void disp(void)
  13. {
  14.         uchar i,n,bsel;
  15.         bsel=0x01;
  16.         for(n=0;n<4;n++)
  17.         {
  18.                 P2=0xf0|bsel;
  19.                 P0=segtab[dbuf[n]];
  20.                 if(n==1)P0=P0&0x7f;
  21.                 bsel=_crol_(bsel,1);
  22.                 for(i=1;i<200;i++);
  23.                 P0=0xff;
  24.                
  25.         }
  26.         
  27. }

  28. void  delay15(uchar n)                //15us????
  29. { do {
  30.         _nop_();
  31.         _nop_();
  32.         _nop_();
  33.         _nop_();
  34.         _nop_();
  35.         _nop_();
  36.         _nop_();
  37.         _nop_();
  38.         _nop_();
  39.         _nop_();
  40.         _nop_();
  41.         _nop_();               
  42.                 n--;
  43.         }while(n);
  44.   }
  45. bit reset(void)         //初始化DS18B20
  46. {
  47.          bit err;
  48.    DQ=0;                        //在數(shù)據(jù)線上產生600US低電平
  49.    delay15(40);               
  50.    DQ=1;                        //數(shù)據(jù)線電平拉高
  51.    delay15(4);        //延時60us
  52.    err=DQ;                        //將讀數(shù)據(jù)線狀態(tài),如果為低則復位成功
  53.    delay15(18);        //     如果數(shù)據(jù)線為高則復位不成功
  54.    return(err);
  55. }

  56. void wrbyte(uchar d)        //單片機向DS18B20發(fā)送一個字節(jié)的命令
  57. {
  58.          uchar i;
  59.    dat=d;         
  60.    for(i=8;i>0;i--)           //循環(huán)寫入8位
  61.    {
  62.                  DQ=0;                            //數(shù)據(jù)低電平產生15us
  63.      delay15(1);
  64.            DQ=dat0;                        //將當前數(shù)據(jù)為送至數(shù)據(jù)總線
  65.            dat=dat>>1;                //將下一位要寫入的數(shù)據(jù)移到最低位
  66.            delay15(1);                //延時15us
  67.      DQ=1;                            //數(shù)據(jù)線拉高為寫入下一位做準備
  68.     }
  69. }

  70. uchar  rdbyte(void)        //從DS18B20讀取一個字節(jié)數(shù)據(jù)
  71.   {  
  72.                 uchar i;
  73.     dat=0;                                 //讀取數(shù)據(jù)初始值要為0
  74.     for(i=8;i>0;i--)         //循環(huán)讀取8位(先低后高)
  75.     {  
  76.                           dat=dat>>1;   //讀出數(shù)據(jù)線右移一位        
  77.                                 DQ=0;         //產生1us負脈沖
  78.                                 _nop_();
  79.         DQ=1;                            // 產生15us高電平
  80.         delay15(1);     
  81.         dat7=DQ;            // 讀取到數(shù)據(jù)放入暫存·
  82.         delay15(4);  // 延時,為讀取下一位做準備
  83.       }
  84.      return(dat);  //將讀取到的溫度值返回給單片機
  85.   }   
  86.         
  87. void convert(void) //啟動DS18B20開始溫度轉換
  88. {
  89.         bit err;
  90.         err=reset();     //先復位溫度傳感器
  91.         wrbyte(0xcc);   //由于我們本次只用了一個溫度傳感器,則這里跳過傳感器的識別
  92.         wrbyte(0x44);   //啟動溫度傳感器
  93.         
  94. }
  95. int readt(void)//讀取DS18B20暫存器中的值
  96. {
  97.         uchar h,l;
  98.         bit err;
  99.         err=reset();  //復位溫度傳感器
  100.         wrbyte(0xcc);//跳過多傳感器識別
  101.         wrbyte(0xbe);//讀暫存指令
  102.         l=rdbyte();  //讀取溫度低位
  103.         h=rdbyte();  //讀取溫度高位
  104.         return(h*256+l);  //返回讀取到的溫度
  105. }

  106. void format(int t)//將讀取到的溫度值轉換為帶一位小數(shù)的BCD碼格式送至緩存區(qū),并滅掉高位0
  107. {
  108.         bit zf;     // 正負標記,0正數(shù);1負數(shù)
  109.         zf=0;      
  110.         if(t<0)     //如果溫度在0度以下
  111.         {
  112.                 zf=1;     //置為負數(shù)標志
  113.                 t=-t;     //求補碼
  114.         }
  115.         dbuf[0]=dp[t&0x0f]; //求出溫度的小數(shù)
  116.         t=t>>4;   //移掉小數(shù)部分
  117.         
  118.         if(t==0xff)t=99;  //字節(jié)擴展
  119.         dbuf[3]=t/100;    //求出百位
  120.         t=t%100;
  121.         dbuf[2]=t/10;    //求出十位
  122.         dbuf[1]=t%10;   // 求出個位
  123.         if(zf==1)         //如果是負數(shù)
  124.         {
  125.                 if(dbuf[2]==0)  // 如果十位為零
  126.                 {
  127.                         dbuf[3]=0x13;   //顯示格式為“-x.x"
  128.                         dbuf[2]=0x12;
  129.                         
  130.                 }
  131.                 else        // 如果十位不為零
  132.                 dbuf[3]=0x12;  //顯示格式為“-xx.x"
  133.                
  134.         }
  135.         else  //如果是正數(shù)
  136.         {
  137.         
  138.       if(dbuf[3]==0) //如果百位,十位都為零
  139.                         {
  140.                                 if(dbuf[2]==0)  //顯示格式為x.x
  141.                                  dbuf[2]=0x13;   //如果只有百位為零
  142.                            dbuf[3]=0x13;   //顯示格式為xx.x
  143.                            
  144.                         }        
  145.         }

  146. }

  147. main()
  148. {
  149.         int temp;   //保存測量的溫度值
  150.         while(1)
  151.         {
  152.                 temp=0;  
  153.                 convert();  //啟動溫度轉換
  154.                 temp=readt(); // 讀取溫度值
  155.                 format(temp);  //將溫度值轉換為BCD碼送至顯緩區(qū)
  156.                 disp();

  157.         }
  158. }
復制代碼

DS18B20.7z

19.7 KB, 下載次數(shù): 29, 下載積分: 黑幣 -5

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表