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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 初步認識51單片機-2.3單片機控制DS18B20溫度傳感器模塊

          初步認識51單片機-2.3單片機控制DS18B20溫度傳感器模塊

          作者: 時間:2016-11-21 來源:網(wǎng)絡(luò) 收藏
          通過前面LCD1602的例子我相信對IO口的控制和延時基本有所了解,下面再來一個例子溫度傳感器,同樣只需要IO口操作和延時。先來個DS18B20溫度傳感器的簡介。既然是溫度傳感器,那么一定有個感知溫度的感應(yīng)器。這個感應(yīng)器能把它周圍的溫度直接轉(zhuǎn)成數(shù)字并存儲在scratchpad存儲器中。這個感知溫度和轉(zhuǎn)換成數(shù)字信號的過程我們可以不用理解。我們要做的事情就是讀存儲器的內(nèi)容及其他一些配置。其原理圖如下:
          圖1 DS18B20溫度傳感器概述?

          在DS18B20中有一個溫度傳感器(如上圖所示),它能感知周圍環(huán)境溫度,并能將溫度的結(jié)果直接轉(zhuǎn)成數(shù)字信號存儲起來。溫度信號轉(zhuǎn)成數(shù)字信號的過程我們可以不用關(guān)心。那么數(shù)字信號存在哪里了?DS18B20中有一個叫做ScratchPad的存儲器,一共9個字節(jié)(Byte0-Byte8),數(shù)字信號就存儲在Byte0_LSM和Byte1_MSB中。其中Byte0為低位,Byte1為高位。事實上,我們的目的就是讀出Byte0和Byte1中存儲的數(shù)字信號而已。由此可見,雖然名字是溫度傳感器模塊,但是在我們的思考過程中絲毫不用關(guān)心傳感的過程,這一點與前面講到的LCD1602其實是一樣,我們要做的事情只是去讀或者寫。這就是模塊的作用,我們可以把它當作黑盒子,按照它的規(guī)則,只要掌握往里面輸入,它會產(chǎn)出什么就行了,不需要關(guān)注中間的過程。我們把Byte0_LSM和Byte1_MSB組合成一個16bit的數(shù)字信號,Byte0_LSB為低位,Byte1_MSB為高位,并給它取個名字叫”T-16bit”,如上圖所示。那么如何把這個”T-16bit”的數(shù)字信號轉(zhuǎn)換成溫度呢?從圖中看出,bit11-bit15為S,表示溫度的正負,如果S=0,那么溫度為正,如果S=1那么溫度為負。后面的bit10-bit0,數(shù)值每增加一就表示溫度增加0.0625°C,舉個例子: 假如LSB中讀出來的是1100 0011,MSB讀出來的是0000 0110,那么LSB和MSB結(jié)合起來”T-16bit”就是0000 0110 1100 0011,高5位為0,表示溫度為正,余下11位bit10-bit0(110 1100 0011=1731),把1731×0.0625=108.1875,那么測量的溫度為+108.1875°C. 如果LSB和MSB結(jié)合起來”T-16bit”為1111 1110 1100 0011,那么測量的溫度為-108.1875°C. 在”T-16bit”中,我們也可以這樣理解,bit0位每加1,表示20×0.0625°C,bit1位每變化1表示21×0.0625°C, 依此類推, bit4位每變化1為24×0.0625°C=1°C.

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

          接著就是Byte2_TH和Byte3_TL報警的功能了,圖中Byte2_TH表示設(shè)置的最高溫度,Byte3_TL表示設(shè)置的最低溫度。同樣S表示溫度的正負,如果S=0,那么表示正,如果S=1,那么溫度為負。Byte2_TH和Byte3_TL就表示設(shè)定溫度的范圍了。注意這里的Byte2_TH與Byte3_TL與”T-16bit”中的bit11到bit4是對應(yīng)的,如圖中藍色部分所示。前面講了,在”T-16bit”中,bit4每變化1為1°C,因此在Byte2_TH與Byte3_TL中的最低位每變化1,表示溫度變化1°C. 比如Byte2_TH設(shè)定為,01111001(十進制為121),首位為0,表示+121°C, Byte3_TL為01001001(十進制為73),首位為0,表示+73°C .因此溫度的設(shè)定范圍為:73-121°C. 當”T-16bit”中的溫度高于/等于+121°C,或者低于/等于73°C時,將觸發(fā)報警。

          接下來就是溫度采集的精度設(shè)置了,如圖中的Byte4_Config所示。bit5和bit6分別為R0和R1,其他幾位是固定的。R0和R1分別可以取0或者1,因此可以組合成4種情況,00/01/10/11,分別對應(yīng)不同的精度,如下表所示:

          Byte5-Byte7未給出,Byte8為CRC用與通信錯誤檢測,我們暫且不用管它,我們先考慮簡單的部分

          通過上面的講解,相信對DS18B20有了初步的認識,現(xiàn)在再來談?wù)勊c單片機如何溝通的。DS18B20一共三個引腳,兩個電源引腳(電源正負極),一個數(shù)據(jù)引腳DQ.其結(jié)構(gòu)圖如下所示。黑色殼體朝上,引腳朝下,平面對著自己,左手邊第一個引腳為GND. DS18B20的正負極如果接反,可能會燒掉。

          可見單片機與DS18B20的溝通只能靠這一根線了,另外這一根線上可以同時接很多個DS18B20. 那么單片機是如何通過這一根線準確的與多個DS18B20溝通的呢?單片機是不知道DQ線上有沒有DS18B20的,或者有多個,或者有但是壞了。與人的溝通方式一樣,當你不知道屋里情況的時候,會先打個招呼,問下有人沒。同樣,單片機也一樣,先來個初始化,打個招呼,看看DQ線上有沒有18B20。怎么樣打招呼呢,與前面講LCD1602一樣,當然按照DS18B20的規(guī)則。單片機先要把DQ拉低至少480μS, 然后釋放DQ,大約在15-60μS后,如果線上有DS18B20并能正常工作,那么DS18B20將DQ拉低并維持60-240μS. 單片機通過檢查這個信號,從而判斷線上是否有能正常工作的DS18B20,有多少個信號就掛著多少個DS18B20,這個就是DS18B20的規(guī)則,具體如下,

          初始化后之后就可以與DS18B20溝通了?線上如果有多個DS18B20,你到底是要與哪個溝通呢?因此溝通之前要先來個確定對象。這里我們?nèi)∽詈唵我粋€DS18B20,搞懂了一個,自然會做控制多個DS18B20了。我們來看看初始化代碼如何寫,

          step1:首先DQ拉低,要維持至少480Us,這里我們?nèi)?00Us保險一點

          step2:釋放總線(DQ=1),大約等待15-60Us后,DS18B20會把DQ拉低。那么這里到底是選15Us,還是60Us?

          step3:此時DS18B20把DQ拉低信號(L_DQ)能持續(xù)60-240Us.那么到底選60Us還是240Us?

          注意我們這里的目的是要檢測出DS18B20是否拉低DQ的信號(L_DQ)。那么在step2中,釋放總線(DQ=1)后,我們到底要延時多長時間(Tdelay),去讀DQ是否等于0的信號?

          我們來個極端假設(shè),最小值和最大值

          (1)在step2中, 單片機釋放總線(DQ=1),等待15Us(最小值)后,DS18B20把DQ拉低,在step3中,DQ拉低持續(xù)了60Us(最小值)

          在這種情況下,如果Tdelay>75Us,你就不能檢測到L_DQ信號了。因此Tdelay要小于75Us.

          (2)在step2中, 單片機釋放總線(DQ=1),等待60Us(最大值)后,DS18B20把DQ拉低,在step3中,DQ拉低持續(xù)了60/240Us(兩種情況)

          在這種情況下,如果Tdelay<60Us,你就檢測不到L_DQ信號了。比如你設(shè)置Tdelay=50Us然后去讀DQ,此時DQ仍然為1,為什么?因為60Us后

          DS18B20才把DQ拉低。因此Tdelay>60Us.

          綜上所述,保險時間為:75Us>Tdelay>60Us,代碼如下:

          void ds18b20_init(void)

          {

          DQ=0;//總線拉低

          delayUs(240); //延時526Us

          DQ=1;//釋放總線

          delayUs(28);//延時66Us(60-75Us之間)

          if(DQ==0)

          {

          LED1=0;//(設(shè)置一個LED,如果檢測到DQ=0,就把LED1點亮)

          }

          else

          {

          LED2=0;

          }

          delayUs(240);//注意讀完DQ后要繼續(xù)延時480Us

          }

          DS18B20的ID信號在ROM中,因此這里我們可以跳過讀ROM(Skip ROM[CCh]).

          接下來就到了與DS18B20溝通的部分了。DS18B20一上電的時候是鈍態(tài)的,就是說它是被動的,沒有指令它就不干活。所以,單片機給DS18B20的第一個指令就是讓它開始測量溫度(Convert T [44h]). 當DS18B20收到這條指令后干什么呢?這里就要回到前面的我們講的圖1,DS18B20開始感知周圍溫度并把溫度高低轉(zhuǎn)成數(shù)字信號存儲在ScratchPad中的Byte0和Byte1中。從這里我們知道,我們僅僅通過一條指令Convert T,就讓DS18B20開始溫度測量并存儲,至于這個過程怎么發(fā)生的我們并不關(guān)心。從這里我們看到,其實控制DS18B20模塊與LCD1602模塊沒有本質(zhì)上區(qū)別,我們要做的事情僅僅是去讀懂規(guī)則,這些規(guī)則來源與它們的芯片手冊,那么簡單的講就是閱讀理解芯片手冊。這一點其實被很多初學者忽略了,不愿意或者不習慣查看芯片手冊。DS18B20把溫度信號轉(zhuǎn)成數(shù)字信號需要一定的時間,因此在發(fā)布下一條指令前,我們這里需要檢測DS18B20是否仍處于工作之中,如果你想簡化,來個延時也行。轉(zhuǎn)換完成后,DS18B20又處于鈍態(tài)了,這個轉(zhuǎn)換過程不是持續(xù)的,因此你想讓它再轉(zhuǎn)換,那么就必須再發(fā)一次Convert T指令。

          那么怎么發(fā)指令呢?這個就涉及到‘DS18B20寫’的部分了。參考數(shù)據(jù)手冊,找到‘寫時序

          首先看單片機如何往DS18B20中寫0和1,

          (1)寫0:DQ拉低,維持至少60Us,在大約15-60Us的時候,DS18B20開始接受數(shù)據(jù)

          (2)寫1: DQ拉低,延時2Us,然后釋放DQ,此時,上拉電阻會把DQ拉高,延時至少60Us,在15-60Us的時候,DS18B20開始接受數(shù)據(jù)

          因此寫指令的代碼如下

          void ds18b20_com(unsigned char mycom)

          {

          unsigned char temp;

          unsigned char i;

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

          {

          temp=mycom & 0x01;

          if (temp==1)

          {

          DQ=0;

          _nop_();

          _nop_();

          DQ=1;

          delayUs(35);

          }

          else

          {

          DQ=0;

          delayUs(35);

          DQ=1;

          }

          mycom>>=1;

          }

          }

          所以,如果你要發(fā)指令 ds18b20_com(0xcch)//skip rom,DS18B20就知道了要跳過讀ROM,如果要發(fā)指令Convert T, ds18b20_com(0x44h),DS18B20就開始溫度轉(zhuǎn)換,并存儲在ScratchPad中的前兩個字節(jié)。

          當轉(zhuǎn)換完成后,數(shù)據(jù)存儲在Byte0和Byte1中,下面的任務(wù)就是去讀Byte0和Byte1了。這里需要注意的是,再單片機每發(fā)一次指令之前都要: 初始化->ROM指令->功能指令。這個是芯片手冊上規(guī)定的。因此在讀Byte0和Byte1之前要再初始化一次,Skip ROM([CCh]), 就可以讀Byte0和Byte1了。之后將Byte0和Byte1合并,然后轉(zhuǎn)換成溫度就可以了。

          現(xiàn)在我們來看看如何讀DS18B20,同樣查看芯片手冊,找到讀的時序圖

          DS18B20要把數(shù)據(jù)發(fā)送給單片機,那么DS18B20怎么知道單片機什么時候開始要數(shù)據(jù)呢?這里同樣有個規(guī)則,當單片機將DQ拉低,延時1Us,然后釋放DQ。此時,DS18B20就知道了,哦,單片機開始要數(shù)據(jù)了。如果此時DS18B20要給0,就把DQ拉低,相反,如果要寫1就讓DQ維持高的狀態(tài)。從單片機發(fā)出讀數(shù)據(jù)信息,DS18B20給數(shù)據(jù),單片機采集數(shù)據(jù),這個過程要在15Us完成,之后需要延時45Us,為保險,我們這里取65Us。兩個讀之間,至少要有1Us的間隔。因此很容易得出單片機讀DS18B20的代碼:

          unsigned int ds18b20_read(void)

          {

          unsigned char temp1=0;

          unsigned int temp2=0;

          unsigned int temp=0;

          unsigned char i;

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

          {

          temp1>>=1;

          DQ=0;

          _nop_();

          _nop_();

          DQ=1;

          if(DQ==1)

          temp1 |=0x80;

          delayUs(35);

          }

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

          {

          temp2>>=1;

          DQ=0;

          _nop_();

          _nop_();

          DQ=1;

          if(DQ==1)

          temp2 |=0x80;

          delayUs(35);

          }

          temp2 <<=8;

          temp=temp1+temp2;

          return temp;

          }

          通過LCD1602和DS18B20兩個例子可以看出,對這兩個模塊的控制,其實只用了單片機的引腳控制和延時程序。重點和難點其實在理解各模塊的控制規(guī)則。其實這些只需要通過仔細閱讀對應(yīng)的芯片手冊就能找到。而單片機引腳的控制和延時部分與LED的操作并無區(qū)別,難怪有人說,如果你把操作LED的過程真正搞懂了,單片機你就學會了一半。后面我們會反復的使用LED作為例子,講解單片機其它相關(guān)內(nèi)容。



          評論


          技術(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); })();