久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2638|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

溫度傳感器DS18B20原理詳解 附STM32單片機(jī)源程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1017494 發(fā)表于 2022-4-15 10:32 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
DS18B20原理
傳感器參數(shù)
測(cè)溫范圍為-55℃到+125℃,在-10℃到+85℃范圍內(nèi)誤差為±0.4°
返回16位二進(jìn)制溫度數(shù)值
主機(jī)和從機(jī)通信使用單總線,即使用單線進(jìn)行數(shù)據(jù)的發(fā)送和接收
在使用中不需要任何外圍元件,獨(dú)立芯片即可完成工作
掉電保護(hù)功能 DS18B20 內(nèi)部含有 EEPROM ,通過(guò)配置寄存器可以設(shè)定數(shù)字轉(zhuǎn)換精度和報(bào)警溫度,在系統(tǒng)掉電以后,它仍可保存分辨率及報(bào)警溫度的設(shè)定值
每個(gè)DS18B20都有獨(dú)立唯一的64位-ID,此特性決定了它可以將任意多的DS18b20掛載到一根總線上,通過(guò)ROM搜索讀取相應(yīng)DS18B20的溫度值
寬電壓供電,電壓2.5V~5.5V
DS18B20 返回的16位二進(jìn)制數(shù)代表此刻探測(cè)的溫度值,其高五位代表正負(fù)。如果高五位全部為1,則代表返回的溫度值為負(fù)值。如果高五位全部為0,則代表返回的溫度值 為正值。后面的11位數(shù)據(jù)代表溫度的絕對(duì)值,將其轉(zhuǎn)換為十進(jìn)制數(shù)值之后,再乘以0.0625即可獲得此時(shí)的溫度值
傳感器引腳及原理圖
DS18B20傳感器的引腳及封裝圖如下:
DS18B20一共有三個(gè)引腳,分別是:
GND:電源地線
DQ:數(shù)字信號(hào)輸入/輸出端
VDD:外接供電電源輸入端


單個(gè)DS18B20接線方式:VDD接到電源,DQ接單片機(jī)引腳,同時(shí)外加上拉電阻,GND接地。
注意這個(gè)上拉電阻是必須的,就是DQ引腳必須要一個(gè)上拉電阻。
DS18B20上拉電阻
首先來(lái)看一下什么是場(chǎng)效應(yīng)管(MOSFET),如下圖。


場(chǎng)效應(yīng)管是電壓控制型元器件,只要對(duì)柵極施加一定電壓,DS就會(huì)導(dǎo)通。
漏極開(kāi)路:MOS管的柵極G和輸入連接,源極S接公共端,漏極D懸空(開(kāi)路)什么也沒(méi)有接,直接輸出 ,這時(shí)只能輸出低電平和高阻態(tài),不能輸出高電平。
那么這個(gè)時(shí)候會(huì)出現(xiàn)三種情況:
下圖a為正常輸出(內(nèi)有上拉電阻):場(chǎng)效應(yīng)管導(dǎo)通時(shí),輸出低電位輸出低電位,截止時(shí)輸出高電位
下圖b為漏極開(kāi)路輸出,外接上拉電阻:場(chǎng)效應(yīng)管導(dǎo)通時(shí),驅(qū)動(dòng)電流是從外部的VCC流經(jīng)電阻通過(guò)MOSFET到GND,輸出低電位,截止時(shí)輸出高電位
下圖c為漏極開(kāi)路輸出,無(wú)外接上拉電阻:場(chǎng)效應(yīng)管導(dǎo)通時(shí)輸出低電位,截止呈高阻態(tài)(斷開(kāi))


總結(jié)一下:
開(kāi)漏輸出只能輸出低電平,不能輸出高電平。漏極開(kāi)路輸出高電平時(shí)必須在輸出端與正電源(VCC)間外接一個(gè)上拉電阻。否則只能輸出高阻態(tài)。
DS18B20 是單線通信,即接收和發(fā)送都是這個(gè)通信腳進(jìn)行的。其接收數(shù)據(jù)時(shí)為高電阻輸入,其發(fā)送數(shù)據(jù)時(shí)是開(kāi)漏輸出,本身不具有輸出高電平的能力,即輸出0時(shí)通過(guò)MOS 下拉為低電平,而輸出1時(shí),則為高阻,需要外接上拉電阻將其拉為高電平。因此,需要外接上拉電阻,否則無(wú)法輸出1。
外接上拉電阻阻值:
DS18B20的工作電流約為1mA,VCC一般為5V,則電阻R=5V/1mA=5KΩ,所以正常選擇4.7K電阻,或者相近的電阻值。
DS18B20寄生電源
DS18B20的另一個(gè)特點(diǎn)是不需要再外部供電下即可工作。當(dāng)總線高電平時(shí)能量由單線上拉電阻經(jīng)過(guò)DQ引腳獲得。高電平同時(shí)充電一個(gè)內(nèi)部電容,當(dāng)總線低電平時(shí)由此電容供應(yīng)能量。這種供電方法被稱為“寄生電源”。另外一種選擇是DSl8B20由接在VDD的外部電源供電。


DS18B20內(nèi)部構(gòu)成
主要由以下3部分組成:
64 位ROM
高速暫存器
存儲(chǔ)器
64位ROM存儲(chǔ)獨(dú)有的序列號(hào),ROM中的64位序列號(hào)是出廠前被光刻好的,它可以看作是該DS18B20的地址序列碼,每個(gè)DS18B20的64位序列號(hào)均不相同。這樣就可以實(shí)現(xiàn)一根總線上掛接多個(gè)DS18B20的目的。
高速暫存器包含:
溫度傳感器
一個(gè)字節(jié)的溫度上限和溫度下限報(bào)警觸發(fā)器(TH和TL)
配置寄存器允許用戶設(shè)定9位,10位,11位和12位的溫度分辨率,分別對(duì)應(yīng)著溫度的分辨率為:0.5°C,0.25°C,0.125°C,0.0625°C,默認(rèn)為12位分辨率
存儲(chǔ)器:由一個(gè)高速的RAM和一個(gè)可擦除的EEPROM組成,EEPROM存儲(chǔ)高溫和低溫觸發(fā)器(TH和TL)以及配置寄存器的值,(就是存儲(chǔ)低溫和高溫報(bào)警值以及溫度分辨率)


DS18B20溫度讀取與計(jì)算
DS18B20采用16位補(bǔ)碼的形式來(lái)存儲(chǔ)溫度數(shù)據(jù),溫度是攝氏度。當(dāng)溫度轉(zhuǎn)換命令發(fā)布后,經(jīng)轉(zhuǎn)換所得的溫度值以二字節(jié)補(bǔ)碼形式存放在高速暫存存儲(chǔ)器的第0和第1個(gè)字節(jié)。
高字節(jié)的五個(gè)S為符號(hào)位,溫度為正值時(shí)S=1,溫度為負(fù)值時(shí)S=0。
剩下的11位為溫度數(shù)據(jù)位,對(duì)于12位分辨率,所有位全部有效,對(duì)于11位分辨率,位0(bit0)無(wú)定義,對(duì)于10位分辨率,位0和位1無(wú)定義,對(duì)于9位分辨率,位0,位1,和位2無(wú)定義。


對(duì)應(yīng)的溫度計(jì)算:
當(dāng)五個(gè)符號(hào)位S=0時(shí),溫度為正值,直接將后面的11位二進(jìn)制轉(zhuǎn)換為十進(jìn)制,再乘以0.0625(12位分辨率),就可以得到溫度值。
當(dāng)五個(gè)符號(hào)位S=1時(shí),溫度為負(fù)值,先將后面的11位二進(jìn)制補(bǔ)碼變?yōu)樵a(符號(hào)位不變,數(shù)值位取反后加1),再計(jì)算十進(jìn)制值。再乘以0.0625(12位分辨率),就可以得到溫度值。
舉兩個(gè)例子:
數(shù)字輸出07D0(00000111 11010000),轉(zhuǎn)換成10進(jìn)制是2000,對(duì)應(yīng)攝氏度:0.0625x2000=125°C
數(shù)字輸出為 FC90,首先取反,然后+1,轉(zhuǎn)換成原碼為:11111011 01101111,數(shù)值位轉(zhuǎn)換成10進(jìn)制是870,對(duì)應(yīng)攝氏度:-0.0625x870=-55°C
溫度對(duì)應(yīng)表如下:

DS18B20工作步驟
DS18B20的工作步驟可以分為三步:
初始化DS18B20
執(zhí)行ROM指令
執(zhí)行DS18B20功能指令
其中第二步執(zhí)行ROM指令,也就是訪問(wèn)每個(gè)DS18B20,搜索64位序列號(hào),讀取匹配的序列號(hào)值,然后匹配對(duì)應(yīng)的DS18B20,如果我們僅僅使用單個(gè)DS18B20,可以直接跳過(guò)ROM指令。而跳過(guò)ROM指令的字節(jié)是0xCC。
初始化DS18B20
任 何器件想要使用,首先就是需要初始化,對(duì)于DS18B20單總線設(shè)備,首先初始化單總線為高電平,然后總線開(kāi)始也需要檢測(cè)這條總線上是否存在 DS18B20這個(gè)器件。如果這條總線上存在DS18B20,總線會(huì)根據(jù)時(shí)序要求返回一個(gè)低電平脈沖,如果不存在的話,也就不會(huì)返回脈沖,即總線保持為高 電平。
初始化具體時(shí)序步驟如下:
單片機(jī)拉低總線至少480us,產(chǎn)生復(fù)位脈沖,然后釋放總線(拉高電平)
這時(shí)DS8B20檢測(cè)到請(qǐng)求之后,會(huì)拉低信號(hào),大約60~240us表示應(yīng)答
DS8B20拉低電平的60~240us之間,單片機(jī)讀取總線的電平,如果是低電平,那么表示初始化成功
DS18B20拉低電平60~240us之后,會(huì)釋放總線

采用多個(gè)DS18B20時(shí),需要寫(xiě)ROM指令來(lái)控制總線上的某個(gè)DS18B20。如果是單個(gè)DS18B20,直接寫(xiě)跳過(guò)ROM指令0xCC即可。DS18B20寫(xiě)入ROM功能指令如下表:


DS18B20的一些RAM功能指令如下表。其中常用的是溫度轉(zhuǎn)換指令,開(kāi)啟溫度讀取轉(zhuǎn)換,讀取好的溫度會(huì)存儲(chǔ)在高速暫存器的第0個(gè)和第一個(gè)字節(jié)中。另一個(gè)常用的是讀取溫度指令,讀取高速暫存器存儲(chǔ)的數(shù)據(jù)。


讀時(shí)序
讀時(shí)隙由主機(jī)拉低總線電平至少1μs然后再釋放總線,讀取DS18B20發(fā)送過(guò)來(lái)的1或者0。
DS18B20在檢測(cè)到總線被拉低1微秒后,便開(kāi)始送出數(shù)據(jù),若是要送出0就把總線拉為低電平直到讀周期結(jié)束。若要送出1則釋放總線為高電平。


注意:所有讀時(shí)隙必須至少需要60us,且在兩次獨(dú)立的時(shí)隙之間至少需要1ps的恢復(fù)時(shí)間。
同時(shí)注意:主機(jī)只有在發(fā)送讀暫存器命令(0xBE)或讀電源類型命令(0xB4)后,立即生成讀時(shí)隙指令,DS18B20才能向主機(jī)傳送數(shù)據(jù)。也就是先發(fā)讀取指令,再發(fā)送讀時(shí)隙。
最后一點(diǎn):寫(xiě)時(shí)序注意是先寫(xiě)命令的低字節(jié),比如寫(xiě)入跳過(guò)ROM指令0xCC(11001100),寫(xiě)的順序是“零、零、壹、壹、零、零、壹、壹”。
讀時(shí)序時(shí)是先讀低字節(jié),在讀高字節(jié),也就是先讀取高速暫存器的第0個(gè)字節(jié)(溫度的低8位),在讀取高速暫存器的第1個(gè)字節(jié)(溫度的高8位) 我們正常使用DS18B20讀取溫度讀取兩個(gè)溫度字節(jié)即可。

單片機(jī)源程序如下:
  1. DS18B20.c代碼:
  2. #include "ds18b20.h"
  3. #include "delay.h"
  4. //復(fù)位DS18B20
  5. void DS18B20_Rst(void)
  6. {
  7. DS18B20_IO_OUT(); //SET PG11 OUTPUT
  8. DS18B20_DQ_OUT=0; //拉低DQ
  9. delay_us(750); //拉低750us
  10. DS18B20_DQ_OUT=1; //DQ=1
  11. delay_us(15); //15US
  12. }
  13. //等待DS18B20的回應(yīng)
  14. //返回1:未檢測(cè)到DS18B20的存在
  15. //返回0:存在
  16. u8 DS18B20_Check(void)
  17. {
  18. u8 retry=0;
  19. DS18B20_IO_IN(); //SET PG11 INPUT
  20. while (DS18B20_DQ_IN&&retry<200)
  21. {
  22. retry++;
  23. delay_us(1);
  24. };
  25. if(retry>=200)return 1;
  26. else retry=0;
  27. while (!DS18B20_DQ_IN&&retry<240)
  28. {
  29. retry++;
  30. delay_us(1);
  31. };
  32. if(retry>=240)return 1;
  33. return 0;
  34. }
  35. //從DS18B20讀取一個(gè)位
  36. //返回值:1/0
  37. u8 DS18B20_Read_Bit(void)
  38. {
  39. u8 data;
  40. DS18B20_IO_OUT(); //SET PG11 OUTPUT
  41. DS18B20_DQ_OUT=0;
  42. delay_us(2);
  43. DS18B20_DQ_OUT=1;
  44. DS18B20_IO_IN(); //SET PG11 INPUT
  45. delay_us(12);
  46. if(DS18B20_DQ_IN)data=1;
  47. else data=0;
  48. delay_us(50);
  49. return data;
  50. }
  51. //從DS18B20讀取一個(gè)字節(jié)
  52. //返回值:讀到的數(shù)據(jù)
  53. u8 DS18B20_Read_Byte(void)
  54. {
  55. u8 i,j,dat;
  56. dat=0;
  57. for (i=1;i<=8;i++)
  58. {
  59. j=DS18B20_Read_Bit();
  60. dat=(j<<7)|(dat>>1);
  61. }
  62. return dat;
  63. }
  64. //寫(xiě)一個(gè)字節(jié)到DS18B20
  65. //dat:要寫(xiě)入的字節(jié)
  66. void DS18B20_Write_Byte(u8 dat)
  67. {
  68. u8 j;
  69. u8 testb;
  70. DS18B20_IO_OUT(); //SET PG11 OUTPUT;
  71. for (j=1;j<=8;j++)
  72. {
  73. testb=dat&0x01;
  74. dat=dat>>1;
  75. if (testb)
  76. {
  77. DS18B20_DQ_OUT=0; // Write 1
  78. delay_us(2);
  79. DS18B20_DQ_OUT=1;
  80. delay_us(60);
  81. }
  82. else
  83. {
  84. DS18B20_DQ_OUT=0; // Write 0
  85. delay_us(60);
  86. DS18B20_DQ_OUT=1;
  87. delay_us(2);
  88. }
  89. }
  90. }
  91. //開(kāi)始溫度轉(zhuǎn)換
  92. void DS18B20_Start(void)
  93. {
  94. DS18B20_Rst();
  95. DS18B20_Check();
  96. DS18B20_Write_Byte(0xcc); // skip rom
  97. DS18B20_Write_Byte(0x44); // convert
  98. }
  99. //初始化DS18B20的IO口 DQ 同時(shí)檢測(cè)DS的存在
  100. //返回1:不存在
  101. //返回0:存在
  102. u8 DS18B20_Init(void)
  103. {
  104. GPIO_InitTypeDef GPIO_InitStructure;
  105. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE); //使能PORTG口時(shí)鐘
  106. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //PORTG.11 推挽輸出
  107. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  108. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  109. GPIO_Init(GPIOG, &GPIO_InitStructure);
  110. GPIO_SetBits(GPIOG,GPIO_Pin_11); //輸出1
  111. DS18B20_Rst();
  112. return DS18B20_Check();
  113. }
  114. //從ds18b20得到溫度值
  115. //精度:0.1C
  116. //返回值:溫度值 (-550~1250)
  117. short DS18B20_Get_Temp(void)
  118. {
  119. u8 temp;
  120. u8 TL,TH;
  121. short tem;
  122. DS18B20_Start (); // ds1820 start convert
  123. DS18B20_Rst();
  124. DS18B20_Check();
  125. DS18B20_Write_Byte(0xcc); // skip rom
  126. DS18B20_Write_Byte(0xbe); // convert
  127. TL=DS18B20_Read_Byte(); // LSB
  128. TH=DS18B20_Read_Byte(); // MSB
  129. if(TH>7)
  130. {
  131. TH=~TH;
  132. TL=~TL;
  133. temp=0; //溫度為負(fù)
  134. }else temp=1; //溫度為正
  135. tem=TH; //獲得高八位
  136. tem<<=8;
  137. tem+=TL; //獲得底八位
  138. tem=(float)tem*0.625; //轉(zhuǎn)換
  139. if(temp)return tem; //返回溫度值
  140. else return -tem;
  141. }


  142. DS18B20.h代碼:
  143. #ifndef __DS18B20_H
  144. #define __DS18B20_H
  145. #include "sys.h"
  146. //IO方向設(shè)置
  147. #define DS18B20_IO_IN() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=8<<12;}
  148. #define DS18B20_IO_OUT() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=3<<12;}
  149. //IO操作函數(shù)
  150. #define DS18B20_DQ_OUT PGout(11) //數(shù)據(jù)端口 PA0
  151. #define DS18B20_DQ_IN PGin(11) //數(shù)據(jù)端口 PA0
  152. u8 DS18B20_Init(void);//初始化DS18B20
  153. short DS18B20_Get_Temp(void);//獲取溫度
  154. void DS18B20_Start(void);//開(kāi)始溫度轉(zhuǎn)換
  155. void DS18B20_Write_Byte(u8 dat);//寫(xiě)入一個(gè)字節(jié)
  156. u8 DS18B20_Read_Byte(void);//讀出一個(gè)字節(jié)
  157. u8 DS18B20_Read_Bit(void);//讀出一個(gè)位
  158. u8 DS18B20_Check(void);//檢測(cè)是否存在DS18B20
  159. void DS18B20_Rst(void);//復(fù)位DS18B20
  160. #endif
復(fù)制代碼

評(píng)分

參與人數(shù) 1黑幣 +10 收起 理由
admin + 10 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 91在线看片 | 成人亚洲在线 | 国产一级视屏 | 午夜精品福利视频 | 亚洲高清视频一区二区 | 日韩精品在线观看免费 | 999www视频免费观看 | 欧美不卡在线 | 91视频在线看 | 亚洲国产欧美一区二区三区久久 | 欧美一区二区视频 | 一区欧美 | 国产综合在线视频 | 成人在线视频免费播放 | 国产精品视频一区二区三区四区国 | 亚洲视频三区 | 国产精品日本一区二区在线播放 | 国产精品成av人在线视午夜片 | 国产成人高清在线观看 | 免费看啪啪网站 | 国产精品视频一二三 | 亚洲一区二区在线视频 | 国产福利在线看 | h在线播放 | 久久精品亚洲精品国产欧美 | 久久久久国产精品免费免费搜索 | www.久久精品视频 | 蜜桃视频在线观看www社区 | 亚洲精品在线播放 | 欧美激情在线观看一区二区三区 | 欧美精品乱码久久久久久按摩 | 国产日批| 久久久久久久久久久丰满 | 欧美日韩综合精品 | 精品视频在线播放 | 男人天堂国产 | 久久99精品久久久久久 | 理论片87福利理论电影 | 亚州精品天堂中文字幕 | 色悠悠久| 一区二区三区中文 |