DS18B20是數位溫度感測器,使用單一匯流排時序與主機通訊. 僅有的 1 需要接線才能完成溫度資料讀取;
DS18B20內建64位元產品序號,方便辨識. 可連接多個 DS18B20 感測器 1 金屬絲, 並通過64位身份認證, 可以分別讀取不同感測器採集的溫度訊息.
DS18B20簡介
2.1 DS18B20的主要特點
1. 全數位溫度轉換和輸出.
2. 先進的單總線數據通信.
3. 高達 12 位元分辨率, 精度高達±0.5攝氏度.
4. 12 位元解析度下的最大工作週期為 750 毫秒.
5. 可選擇寄生工作模式.
6. 檢測溫度範圍 –55°C ~+125°C (–67°F ~+257°F).
7. 內建EEPROM, 溫度超限警報功能.
8. 64-位光刻ROM, 內建產品序號, 方便多機連接.
9. 多種包裝形式, 適應不同的硬體系統.
2.2 DS18B20腳位功能
GND 電壓地;
DQ單資料匯流排;
VDD電源電壓;
NC空針;
2.3 DS18B20工作原理及應用
DS18B20 溫度偵測和數位資料輸出完全整合在一顆晶片上, 因此具有更強的抗干擾能力. 其一個工作循環可分為兩個部分, 即溫度檢測和數據處理.
18B20有三種形式的記憶體資源. 他們是: ROM只讀記憶體, 用於儲存DS18B20ID碼; 首先 8 位元是單行系列程式碼 (DS18B20代碼為19H), 下列 48 位是晶片的唯一序號; 最後一個 8 位元是 CRC 碼 (冗餘校驗) 上述的 56 位元. 數據在生產時設置,用戶無法更改. DS18B20共有 64 ROM 位元.
RAM資料暫存器, 用於內部計算和數據訪問, 斷電後資料遺失, DS18B20共有 9 RAM 位元組, 每個位元組是 8 位元. 第一、二位元組為溫度轉換後的資料值訊息; 第三和第四位元組是用戶EEPROM的鏡像 (常用於溫度警報值存儲). 當電源重設時其值會被刷新. 第五個位元組是用戶第三個EEPROM的鏡像. 第六號, 7th, 第8個位元組是計數暫存器, 旨在讓使用者獲得更高的溫度分辨率. 它們也是內部溫度轉換和計算的暫存單元. 第9個位元組是第一個位元組的CRC碼 8 位元組. EEPROM是一種非揮發性記憶體,用於儲存需要長期保存的數據, 上、下溫度警報值, 和驗證數據. DS18B20共有 3 EEPROM 位元, RAM中有鏡像,方便使用者操作.
DS18B20預設工作在12位元解析度模式. 轉換後得到的12位元資料儲存在DS18B20的兩個8位元RAM中 (前兩個位元組). 首先 5 二進位中的位是符號位. 如果測量的溫度大於 0, 這些 5 位元是 0. 只需將測量值乘以 0.0625 取得實際溫度. 如果溫度低於 0, 這些 5 位元是 1. 測量值需要取反, 添加者 1, 然後乘以 0.0625 取得實際溫度. 或使用位元運算提取溫度: 小數點佔據較低位 4 位元, 高位為整數位 (不考慮負數).
2.4 DS18B20晶片ROM指令表
1. 讀取ROM [33H] (十六進位命令字在方括號中).
此指令允許總線控制器讀取DS18B20的64位元ROM. 此指令僅當總線上只有一個DS18B20時才能使用. 如果連接了多個, 通訊過程中會出現資料衝突.
2. 補丁ROM [55H]
該指令後面跟著控制器發出的 64 位元序號. 當總線上有多個DS18B20時, 只有與控制器發出的序號相同的晶片才能響應, 其他晶片將等待下一次復位. 此指令適用於單晶片和多晶片連接.
3. 跳過ROM [中西醫結合中心]
該指令使晶片不響應ROM程式碼. 單總線情況下, 此指令可用於節省時間. 如果連接多個晶片時使用該指令, 會發生資料衝突, 導致錯誤.
4. 搜尋ROM [調頻]
晶片初始化後, 當多個晶片連接到總線上時,搜尋指令允許透過消除來識別所有裝置的64位元ROM.
5. 警報搜索 [每個]
多晶片情況下, 警報晶片搜尋指令只回應滿足溫度高於TH或低於TL警報條件的晶片. 只要晶片沒有斷電, 警報狀態將保持,直到再次測量溫度且未達到警報條件為止.
6. 寫便條本 [4埃希]
這是將資料寫入RAM的指令. 隨後寫入的兩個位元組資料將儲存在位址 2 (警報RAM的TH) 和地址 3 (警報RAM的TL). 寫入過程可以透過重設訊號終止.
7. 閱讀便條本 (從 RAM 讀取數據) [貝赫]
該指令將從 RAM 中讀取數據, 從地址開始 0 直至地址 9, 完成整個RAM資料的讀取. 晶片允許復位訊號終止讀取過程, 那是, 可以忽略後續不必要的位元組以減少讀取時間.
8. 複製便條本 (將 RAM 資料複製到 EEPROM) [48H]
該指令將RAM中的資料儲存到EEPROM中,這樣斷電時資料不會遺失. 由於晶片正忙於 EEPROM 儲存處理, 當控制器發送讀取時隙時, 總線輸出 “0”, 當儲存工作完成時, 總線將輸出 “1”.
寄生工作模式, 該指令發出後必須立即使用強上拉並保持至少10MS以維持晶片運行.
9. 轉換 T (溫度轉換) [44H]
收到此指令後, 晶片將進行溫度轉換並將轉換後的溫度值儲存在RAM的第1和第2位址中. 由於晶片正忙於溫度轉換處理, 當控制器發送讀取時隙時, 總線輸出 “0”, 當儲存工作完成時, 總線將輸出 “1”. 寄生工作模式, 該指令發出後必須立即使用強上拉並保持至少 500MS 以維持晶片運行.
10. 召回EEPROM (將EEPROM中的警報值複製到RAM中) [B8H]
此指令將EEPROM中的警報值複製到RAM中的第3和第4字節. 由於晶片正忙於複製處理, 當控制器發送讀取時隙時, 總線輸出 “0”, 當儲存工作完成時, 總線輸出 “1”. 另外, 指令在晶片上電重置時會自動執行. 這樣, RAM 中的兩個警報位元組位元始終是 EEPROM 中資料的鏡像.
11. 讀取電源 (工作模式切換) [B4H]
此指令發出後, 發出讀取時間間隙, 晶片將返回其電源狀態字. “0” 是寄生功率狀態且 “1” 是外部電源狀態.
2.5 DS18B20時序圖
2.5.1 DS18B20復位與響應關係圖
每次通訊之前必須執行重置. 重置時間, 等待時間, 回應時間應嚴格依照時間安排.
DS18B20讀寫時間間隙: DS18B20資料讀寫是透過時間間隙處理位元和指令字來交換資訊來確認的.
2.5.2 寫入數據 0 和數據 1 至 DS18B20
在寫資料時間間隙的前15uS內, 總線需要被控制器拉低, 然後就是晶片對總線資料的取樣時間. 採樣時間15~60uS. 如果控制器在取樣時間內將匯流排拉高, 這意味著寫作 “1”, 如果控制器將匯流排拉低, 這意味著寫作 “0”.
每一位傳輸應有至少15uS的低電平起始位, 以及後續數據 “0” 或者 “1” 應在45uS內完成.
整個bit的傳輸時間應維持在60~120uS, 否則無法保證正常通訊.
筆記: DS18B20從低位開始讀寫數據.
2.5.3 讀取數據 0 和數據 1 來自 DS18B20
讀取時間間隙期間控制的取樣時間應該更準確. 在讀取時間間隔期間, 主機也必須產生至少1uS的低電位來指示讀取時間的開始. 然後, 總線釋出後15uS內, DS18B20將傳送內部資料位. 此時, 如果控制器發現總線為高電平, 這意味著閱讀 “1”, 如果總線很低, 意思是讀取數據 “0”. 讀取每一位之前, 控制器添加啟動訊號.
筆記: 資料位元必須在讀取間隙開始後 15uS 內讀取,以確保正確通訊.
溝通過程中, 8 的位 “0” 或者 “1” 被用作一個位元組, 而位元組的讀或寫是從低位開始的.
2.5.4 一次讀取溫度順序 (總線上只有一個 DS18B20)
1. 發送復位訊號
2. 偵測響應訊號
3. 發送0xCC
4. 發送0x44
5. 發送復位訊號
6. 偵測響應訊號
7. 寫入0xcc
8. 寫入0xbe
9. 環形 8 讀取溫度低位元組的次數
10. 環形 8 讀取溫度高位元組的次數
11. 合成16位元溫度資料並處理
3. 驅動程式程式碼
3.1 DS18B20.c
#包括 “ds18b20.h”
/*
功能: DS18B20初始化
硬體連接: PB15
*/
無效 DS18B20_Init(空白)
{
RCC->APB2ENR|=1<<3; //PB
GPIOB->CRH&=0x0FFFFFFF;
GPIOB->CRH|=0x30000000;
GPIOB->奧德羅|=1<<15; //引體向上
}
/*
功能: 檢查DS18B20設備是否存在
傳回值: 1 表示設備不存在 0 表示設備正常
*/
u8 DS18B20_CheckDevice(空白) //包含重設脈衝, 檢測脈衝
{
DS18B20_輸出_模式();//初始化為輸出模式
DS18B20_OUT=0; //產生重設脈衝
耽誤我們(750); //產生750us低電平
DS18B20_OUT=1; //發布總線
耽誤我們(15); //等待DS18B20響應
如果(DS18B20_CleckAck())//檢測存在脈衝
{
返回 1;
}
返回 0;
}
/*
功能: 檢測DS18B20器件的存在脈衝
傳回值: 1 表示錯誤 0 表示正常
*/
u8 DS18B20_CleckAck(空白)
{
u8 碳奈米管=0;
DS18B20_輸入模式();//初始化為輸入模式
儘管(DS18B20_IN&&碳奈米管<200) //等待DS18B20響應存在脈衝
{
耽誤我們(1);
cnt++;
}
如果(碳奈米管>=200)返回 1; //錯誤
碳奈米管=0;
儘管((!DS18B20_IN)&&碳奈米管<240) //等待DS18B20釋放總線
{
耽誤我們(1);
cnt++;
}
如果(碳奈米管>=240)返回 1; //錯誤
返回 0;
}
/*
功能: 寫入一個位元組
首先學習如何寫一點.
*/
無效 DS18B20_WriteByte(u8指令)
{
u8我;
DS18B20_輸出_模式(); //初始化為輸出模式
為了(我=0;我<8;我++)
{
DS18B20_OUT=0; //生成寫入時間間隙 (寫開始)
耽誤我們(2);
DS18B20_OUT=cmd&0x01; //傳送實際資料位
耽誤我們(60); //等待寫入完成
DS18B20_OUT=1; //釋放總線並準備下一次傳輸
指令>>=1; //繼續發送下一位數據
}
}
/*
功能: 讀取一個位元組
先學習如何閱讀.
*/
u8 DS18B20_ReadByte(空白)
{
u8我,數據=0;
為了(我=0;我<8;我++)
{
DS18B20_輸出_模式(); //初始化為輸出模式
DS18B20_OUT=0; //產生讀取時間間隙 (讀開始)
耽誤我們(2);
DS18B20_OUT=1; //發布總線
DS18B20_輸入模式(); //初始化為輸入模式
耽誤我們(8); //等待DS18B20數據輸出
數據>>=1; //填滿高位 0, 預設是 0
如果(DS18B20_IN) 數據|=0x80;
耽誤我們(60);
DS18B20_OUT=1; //發布總線, 等待讀取下一位數據
}
傳回數據;
}
/*
功能: 讀取一次DS18B20的溫度數據
傳回值: 讀取的溫度數據
考慮的情況: 總線上只有一個DS18B20
*/
u16 DS18B20_ReadTemp(空白)
{
u16 溫度=0;
u8 溫度_H,溫度_L;
DS18B20_檢查設備(); //發送復位脈衝, 偵測脈搏
DS18B20_WriteByte(0xCC); //跳過 ROM 序列檢測
DS18B20_WriteByte(0x44); //開始溫度轉換
//等待溫度轉換完成
儘管(DS18B20_讀字節()!=0xFF){}
DS18B20_檢查設備(); //發送復位脈衝, 偵測脈搏
DS18B20_WriteByte(0xCC); //跳過 ROM 序列檢測
DS18B20_WriteByte(0乙醚); //讀取溫度
temp_L=DS18B20_ReadByte(); //讀取低溫數據
temp_H=DS18B20_ReadByte(); //讀取高溫數據
溫度=temp_L|(溫度_H<<8); //合成溫度
返回溫度;
}
3.2 DS18B20.h
#ifndef DS18B20_H
#定義DS18B20_H
#包括 “stm32f10x.h”
#包括 “系統檔案h”
#包括 “延遲.h”
#包括 “ds18b20.h”
#包括 “usart.h”
/*封裝介面*/
//將 DS18B20 初始化為輸入模式
#定義DS18B20_INPUT_MODE() {GPIOB->CRH&=0x0FFFFFFF;GPIOB->CRH|=0x80000000;}
//將 DS18B20 初始化為輸出模式
#定義DS18B20_OUTPUT_MODE(){GPIOB->CRH&=0x0FFFFFFF;GPIOB->CRH|=0x30000000;}
//DS18B20 IO口輸出
#定義 DS18B20_OUT PBout(15)
//DS18B20 IO口輸入
#定義 DS18B20_IN PBin(15)
//函數聲明
u8 DS18B20_CleckAck(空白);
u8 DS18B20_CheckDevice(空白);
無效 DS18B20_Init(空白);
u16 DS18B20_ReadTemp(空白);
u8 DS18B20_ReadByte(空白);
無效 DS18B20_WriteByte(u8指令);
#恩迪夫
poYBAGDYdXCAWkKMAAAK8RNs4s030.png
3.3 延時功能
/*
功能: 我們的延誤
*/
無效延遲(國際我們)
{
#ifdef _SYSTICK_IRQ_
整數我,j;
為了(我=0;iVAL=0; //CNT計數器值
系統標記->負載=9*us; //9 表示1us
系統標記->控制鍵|=1<<0; //啟動定時器
做
{
tmp=SysTick->控制鍵; //讀取狀態
}儘管((!(tmp&1<<16))&&(tmp&1<<0));
系統標記->值=0; //CNT計數器值
系統標記->控制鍵&=~(1<<0); //關閉定時器
#恩迪夫
};我++)>
3.4 main.c 呼叫DS18B20讀取溫度並列印到串列埠
#包括 “stm32f10x.h”
#包括 “ds18b20.h”
u8 DS18B20_ROM[8]; //儲存DS18B20的64位元ROM代碼
整數主(空白)
{
u16 溫度;
USARTx_Heat(USART1,72,115200);//字串口初始化 1
DS18B20_熱(); //DS18B20初始化
/*1. 讀取DS18B20的64位元ROM代碼*/
//發送復位脈衝, 檢測存在脈衝
儘管(DS18B20_檢查設備())
{
列印函數(“DS18B20設備不存在!\n”);
延遲時間(500);
}
//發送命令讀取64位元ROM代碼
DS18B20_WriteByte(0x33);
//循環讀取64位元ROM程式碼
為了(我=0;我<8;我++)
{
DS18B20_ROM[我]= DS18B20_ReadByte();
列印函數(“DS18B20_ROM[%d]=0x%X\n”,我,DS18B20_ROM[我]);
}
儘管(1)
{
/*2. 同時操作總線上所有DS18B20開始轉換溫度*/
DS18B20_檢查設備(); //發送復位脈衝, 偵測脈搏
DS18B20_WriteByte(0xCC); //跳過 ROM 序列檢測
DS18B20_WriteByte(0x44); //開始溫度轉換 (讓總線上的所有DS18B20轉換溫度)
延遲時間(500); //等待線上所有DS18B20溫度轉換完成
/*3. 單次定向讀取每個 DS18B20 的溫度*/
DS18B20_檢查設備(); //發送復位脈衝, 偵測脈搏
DS18B20_WriteByte(0x55); //發送命令匹配ROM
為了(我=0;我<8;我++) //傳送 64 位元代碼
{
DS18B20_WriteByte(DS18B20_ROM[我]);
}
DS18B20_WriteByte(0乙醚); //讀取溫度
臨時=DS18B20_ReadByte(); //讀取低階溫度數據
溫度|=DS18B20_ReadByte()<<8; //讀取高階溫度數據
列印函數(“temp1=%d.%d\n”,溫度>>4,溫度&0xF);
列印函數(“temp2=%f\n”,溫度*0.0625);
延遲時間(500);
}
}