<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)中使用DS18B20溫度傳感器C語言程序(參考1)

          單片機(jī)中使用DS18B20溫度傳感器C語言程序(參考1)

          作者: 時(shí)間:2016-11-18 來源:網(wǎng)絡(luò) 收藏
          單片機(jī)中使用DS18B20溫度傳感器C語言程序(參考1)

          /********************************************************************************
          DS18B20 測溫程序

          本文引用地址:http://www.ex-cimer.com/article/201611/315667.htm

          硬件:AT89S52
          (1)單線ds18b20接 P2.2
          (2)七段數(shù)碼管接P0口
          (3)使用外部電源給ds18b20供電,沒有使用寄生電源
          軟件:Kei uVision 3

          **********************************************************************************/
          #include "reg52.h"
          #include "intrins.h"
          #define uchar unsigned char
          #define uint unsigned int
          sbit ds=P2^2;
          sbit dula=P2^6;
          sbit wela=P2^7;
          uchar flag ;
          uint temp; //參數(shù)temp一定要聲明為 int 型
          uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
          0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //不帶小數(shù)點(diǎn)數(shù)字編碼

          uchar code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
          0x87,0xff,0xef}; //帶小數(shù)點(diǎn)數(shù)字編碼

          /*延時(shí)函數(shù)*/
          void TempDelay (uchar us)
          {
          while(us--);
          }

          void delay(uint count) //延時(shí)子函數(shù)
          {
          uint i;
          while(count)
          {
          i=200;
          while(i>0)
          i--;
          count--;
          }
          }

          /*串口初始化,波特率9600,方式1 */
          void init_com()
          {
          TMOD=0x20; //設(shè)置定時(shí)器1為模式2
          TH1=0xfd; //裝初值設(shè)定波特率
          TL1=0xfd;
          TR1=1; //啟動(dòng)定時(shí)器
          SM0=0; //串口通信模式設(shè)置
          SM1=1;
          // REN=1; //串口允許接收數(shù)據(jù)
          PCON=0; //波特率不倍頻
          // SMOD=0; //波特率不倍頻
          // EA=1; //開總中斷
          //ES=1; //開串行中斷
          }

          /*數(shù)碼管的顯示 */
          void display(uint temp)
          {
          uchar bai,shi,ge;
          bai=temp/100;
          shi=temp%100/10;
          ge=temp%100%10;

          dula=0;
          P0=table[bai]; //顯示百位
          dula=1; //從0到1,有個(gè)上升沿,解除鎖存,顯示相應(yīng)段
          dula=0; //從1到0再次鎖存

          wela=0;
          P0=0xfe;
          wela=1;
          wela=0;
          delay(1); //延時(shí)約2ms

          P0=table1[shi]; //顯示十位
          dula=1;
          dula=0;

          P0=0xfd;
          wela=1;
          wela=0;
          delay(1);

          P0=table[ge]; //顯示個(gè)位
          dula=1;
          dula=0;

          P0=0xfb;
          wela=1;
          wela=0;
          delay(1);
          }
          /*****************************************
          時(shí)序:初始化時(shí)序、讀時(shí)序、寫時(shí)序。
          所有時(shí)序都是將主機(jī)(單片機(jī))作為主設(shè)備,單總
          線器件作為從設(shè)備。而每一次命令和數(shù)據(jù)的傳輸
          都是從主機(jī)主動(dòng)啟動(dòng)寫時(shí)序開始,如果要求單總
          線器件回送數(shù)據(jù),在進(jìn)行寫命令后,主機(jī)需啟動(dòng)
          讀時(shí)序完成數(shù)據(jù)接收。數(shù)據(jù)和命令的傳輸都是低
          位在先。
          初始化時(shí)序:復(fù)位脈沖 存在脈沖
          讀;1 或 0時(shí)序
          寫;1 或 0時(shí)序
          只有存在脈沖信號(hào)是從18b20(從機(jī))發(fā)出的,其
          它信號(hào)都是由主機(jī)發(fā)出的。
          存在脈沖:讓主機(jī)(總線)知道從機(jī)(18b20)已
          經(jīng)做好了準(zhǔn)備。
          ******************************************/
          /*--------------------------------------------------------------------------------------------------------------------
          初始化:檢測總線控制器發(fā)出的復(fù)位脈沖
          和ds18b20的任何通訊都要從初始化開始

          初始化序列包括一個(gè)由總線控制器發(fā)出的復(fù)位脈沖
          和跟在其后由從機(jī)發(fā)出的存在脈沖。

          初始化:復(fù)位脈沖+存在脈沖

          具體操作:
          總線控制器發(fā)出(TX)一個(gè)復(fù)位脈沖 (一個(gè)最少保持480μs 的低電平信號(hào)),然后釋放總線,
          進(jìn)入接收狀態(tài)(RX)。單線總線由5K 上拉電阻拉到高電平。探測到I/O 引腳上的上升沿后
          DS1820 等待15~60μs,然后發(fā)出存在脈沖(一個(gè)60~240μs 的低電平信號(hào))。

          具體看18b20 單線復(fù)位脈沖時(shí)序和1-wire presence detect "的時(shí)序圖
          -------------------------------------------------------------------------------------------------------------------*/
          void ds_reset(void)
          {
          ds=1;
          _nop_(); //1us
          ds=0;
          TempDelay(80); //當(dāng)總線停留在低電平超過480us,總線上所以器件都將被復(fù)位,這里//延時(shí)約530us總 線停留在低電平超過480μs,總線上的所有器件都
          //將被復(fù)位。
          _nop_();
          ds=1; //產(chǎn)生復(fù)位脈沖后,微處理器釋放總線,讓總線處于空閑狀態(tài),原因查//18b20中文資料

          TempDelay(5); //釋放總線后,以便從機(jī)18b20通過拉低總線來指示其是否在線,
          //存在檢測高電平時(shí)間:15~60us, 所以延時(shí)44us,進(jìn)行 1-wire presence //detect(單線存在檢測)
          _nop_();
          _nop_();
          _nop_();
          if(ds==0)
          flag=1; //detect 18b20 success
          else
          flag=0; //detect 18b20 fail
          TempDelay(20); //存在檢測低電平時(shí)間:60~240us,所以延時(shí)約140us
          _nop_();
          _nop_();
          ds=1; //再次拉高總線,讓總線處于空閑狀態(tài)
          /**/
          }

          /*----------------------------------------
          讀/寫時(shí)間隙:
          DS1820 的數(shù)據(jù)讀寫是通過時(shí)間隙處理
          位和命令字來確認(rèn)信息交換。
          ------------------------------------------*/
          bit ds_read_bit(void) //讀一位
          {
          bit dat;
          ds=0; //單片機(jī)(微處理器)將總線拉低
          _nop_(); //讀時(shí)隙起始于微處理器將總線拉低至少1us
          ds=1; //拉低總線后接著釋放總線,讓從機(jī)18b20能夠接管總線,輸出有效數(shù)據(jù)
          _nop_();
          _nop_(); //小延時(shí)一下,讀取18b20上的數(shù)據(jù) ,因?yàn)閺膁s18b20上輸出的數(shù)據(jù)
          //在讀"時(shí)間隙"下降沿出現(xiàn)15us內(nèi)有效
          dat=ds; //主機(jī)讀從機(jī)18b20輸出的數(shù)據(jù),這些數(shù)據(jù)在讀時(shí)隙的下降沿出現(xiàn)//15us內(nèi)有效
          TempDelay(10); //所有讀"時(shí)間隙"必須60~120us,這里77us
          return(dat); //返回有效數(shù)據(jù)
          }
          uchar ds_read_byte(void ) //讀一字節(jié)
          {

          uchar value,i,j;
          value=0; //一定別忘了給初值
          for(i=0;i<8;i++)
          {
          j=ds_read_bit();
          value=(j<<7)|(value>>1); //這一步的說明在一個(gè)word文檔里面
          }
          return(value); //返回一個(gè)字節(jié)的數(shù)據(jù)
          }
          void ds_write_byte(uchar dat) //寫一個(gè)字節(jié)
          {
          uchar i;
          bit onebit; //一定不要忘了,onebit是一位
          for(i=1;i<=8;i++)
          {
          onebit=dat&0x01;
          dat=dat>>1;
          if(onebit) //寫 1
          {
          ds=0;
          _nop_();
          _nop_(); //看時(shí)序圖,至少延時(shí)1us,才產(chǎn)生寫"時(shí)間隙"
          ds=1; //寫時(shí)間隙開始后的15μs內(nèi)允許數(shù)據(jù)線拉到高電平
          TempDelay(5); //所有寫時(shí)間隙必須最少持續(xù)60us
          }
          else //寫 0
          {
          ds=0;
          TempDelay(8); //主機(jī)要生成一個(gè)寫0 時(shí)間隙,必須把數(shù)據(jù)線拉到低電平并保持至少60μs,這里64us
          ds=1;
          _nop_();
          _nop_();
          }
          }
          }

          /*****************************************
          主機(jī)(單片機(jī))控制18B20完成溫度轉(zhuǎn)換要經(jīng)過三個(gè)步驟:
          每一次讀寫之前都要18B20進(jìn)行復(fù)位操作,復(fù)位成功后發(fā)送
          一條ROM指令,最后發(fā)送RAM指令,這樣才能對(duì)DS18b20進(jìn)行
          預(yù)定的操作。
          復(fù)位要求主CPU將數(shù)據(jù)線下拉500us,然后釋放,當(dāng)ds18B20
          受到信號(hào)后等待16~60us,后發(fā)出60~240us的存在低脈沖,
          主CPU收到此信號(hào)表示復(fù)位成功
          ******************************************/

          /*----------------------------------------
          進(jìn)行溫度轉(zhuǎn)換:
          先初始化
          然后跳過ROM:跳過64位ROM地址,直接向ds18B20發(fā)溫度轉(zhuǎn)換命令,適合單片工作
          發(fā)送溫度轉(zhuǎn)換命令
          ------------------------------------------*/

          void tem_change()
          {
          ds_reset();
          delay(1); //約2ms
          ds_write_byte(0xcc);
          ds_write_byte(0x44);
          }

          /*----------------------------------------
          獲得溫度:
          ------------------------------------------*/
          uint get_temperature()
          {
          float wendu;
          uchar a,b;
          ds_reset();
          delay(1); //約2ms
          ds_write_byte(0xcc);
          ds_write_byte(0xbe);
          a=ds_read_byte();
          b=ds_read_byte();
          temp=b;
          temp<<=8;
          temp=temp|a;
          wendu=temp*0.0625; //得到真實(shí)十進(jìn)制溫度值,因?yàn)镈S18B20
          //可以精確到0.0625度,所以讀回?cái)?shù)據(jù)的最低位代表的是 //0.0625度

          temp=wendu*10+0.5; //放大十倍,這樣做的目的將小數(shù)點(diǎn)后第一位
          //也轉(zhuǎn)換為可顯示數(shù)字,同時(shí)進(jìn)行一個(gè)四舍五入操作。
          return temp;
          }
          /*----------------------------------------
          讀ROM
          ------------------------------------------*/
          /*
          void ds_read_rom() //這里沒有用到
          {
          uchar a,b;
          ds_reset();
          delay(30);
          ds_write_byte(0x33);
          a=ds_read_byte();
          b=ds_read_byte();
          }
          */
          void main()
          {
          uint a;
          init_com();
          while(1)
          {
          tem_change(); //12位轉(zhuǎn)換時(shí)間最大為750ms
          for(a=10;a>0;a--)
          {
          display( get_temperature());
          }
          }
          }



          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();