DS18B20數字溫度傳感器提供9位至12位精度的溫度測量,并具有非易失性用戶可編程上下觸發點報警功能。DS18B20通過單總線通信,根據定義,只需要一條數據線(和地線)即可與單片機通信。此外,DS18B20可以直接從數據線獲得電源(“寄生電源”),消除了每個DS18B20都有一個唯一的64位串行代碼,這允許多個DS18B20在同一條總線上工作。因此,使用一個微處理器來實現是很簡單的。
控制分布在大面積上的許多ds18b20。可以從此功能中受益的應用包括HVAC環境控制,建筑物,設備或機械內部的溫度監測系統以及過程監測和控制系統。
1、模塊來源
模塊實物展示:
資料下載鏈接:
https://pan.baidu.com/s/1L83uG8So6k1NG_QznraoFQ
工作電壓:3-5.5V
工作電流:750nA~1.5mA
測量分辨率:9位到12位可編程分辨率
溫度量程: -55 ~ +125 ℃
測量精度:±0.5 ℃
通信協議:單總線
以上信息見廠家資料文件
3、移植過程
我們的目標是將例程移植至CW32F030C8T6開發板上【實現讀取溫度的功能】。首先要獲取資料,查看數據手冊應如何實現讀取數據,再移植至我們的工程。
3.1查看資料
時序說明
初始化:
將總線拉低,保存低電平至少480us。
轉為輸入模式,總線被上拉電阻拉高大約15~60us。
如果初始化成功則會產生一個由DS18B20所返回的低電平“0”,持續時間大約60~240us。
DS18B20釋放總線,將總線拉高。
讀時序:
將數據線拉低至少1us。
將數據線轉為輸入模式,DS18B20開始采集數據,大約15us。
18B20要送出0就把總線拉為低電平直到讀周期結束。若要送出1則釋放總線為高電平。
注意:所有讀時隙必須至少需要60us,且在兩次獨立的時隙之間至少需要1us的恢復時間。
寫時序:
數據線先置低電平“0”,延時15us。
按從低位到高位的順序發送數據(一次只發送一位)。
延時60us。
拉高數據線“1”。
穿越火線1~4步驟,直到發送完整的字節。
拉高數據線,釋放總線。
寄存器說明
0xCC
主機可以使用此命令同時對總線上的所有設備進行尋址,而無需發送其他的任何地址。 DS18B20通過發出0XCC命令,然后是溫度轉換命令[44h]來執行同步溫度轉換。注意,只有在總線上有一個從設備時,Read Scratchpad [BEh]命令才能跟隨Skip ROM命令。在這種情況下,通過允許主服務器從從服務器讀取而不發送設備的64位ROM代碼可以節省時間。如果總線上有多個從設備,那么Skip ROM命令后跟Read Scratchpad命令將導致數據沖突,因為多個設備將嘗試傳輸數據同時進行。
0x44
該命令為啟動單次溫度轉換。轉換后,產生的溫度數據存儲在地址為【BEh】的2字節溫度寄存器中。
0xBE
該命令允許主機讀取溫度寄存器上的內容。數據傳輸從低位開始,直到讀取第9個字節(bit8=CRC)。如果只需要溫度數據,主機可以在任何時候發出復位以終止讀取。
溫度換算
溫度傳感器的分辨率我們可配置為9、10、11或12位,分別對應于0.5°C、0.25°C、 0.125°C和0.0625°C的增量。開機時的默認分辨率是12位。我們不進行修改,因為分辨率越高就越精準。
例如數據手冊中的示例,如當前當前的溫度是+25.0625℃,寄存器讀出的高8位數據為0000 0001,低8位數據為1001 0001。將其整合得到16位數據:0000 0001 1001 0001。再轉換為10進制數據為401。將讀取到的數據乘以分辨率即可得到實際溫度。
401 * 0.0625 = 25.0625℃
3.2引腳選擇
該模塊有3個引腳,具體引腳連接見各引腳連接。
模塊接線圖
3.3移植至工程
工程模板參考入門手冊的工程模板
移植步驟中的導入.c和.h文件與【CW32模塊使用】DHT11溫濕度傳感器相同,只是將.c和.h文件更改為bsp_ds18b20.c與bsp_ds18b20.h。這里不再過多講述,移植完成后面修改相關代碼。
在文件bsp_ds18b20.c中,編寫如下代碼。
/* * Change Logs: * Date Author Notes * 2024-06-20 LCKFB-LP first version */ #include "bsp_ds18b20.h" #include "stdio.h" /****************************************************************** * 函 數 名 稱:bsp_ds18b20_GPIO_Init * 函 數 說 明:MLX90614的引腳初始化 * 函 數 形 參:無 * 函 數 返 回:1未檢測到器件 0檢測到器件 * 作 者:LC * 備 注:無 ******************************************************************/ char DS18B20_GPIO_Init(void) { unsigned char ret = 255; GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化結構體 RCC_DQ_ENABLE(); // 使能GPIO時鐘 GPIO_InitStruct.Pins = GPIO_DQ; // GPIO引腳 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽輸出 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 輸出速度高 GPIO_Init(PORT_DQ, &GPIO_InitStruct); // 初始化 ret = DS18B20_Check();//檢測器件是否存在 return ret; } /****************************************************************** * 函 數 名 稱:DS18B20_Read_Byte * 函 數 說 明:從DS18B20讀取一個字節 * 函 數 形 參:無 * 函 數 返 回:讀取到的字節數據 * 作 者:LC * 備 注:無 ******************************************************************/ uint8_t DS18B20_Read_Byte(void) { uint8_t i=0,dat=0; for (i=0;i8;i++) { DQ_OUT();//設置為輸入模式 DQ(0); //拉低 delay_us(2); DQ(1); //釋放總線 DQ_IN();//設置為輸入模式 delay_us(12); dat?>>=1; if( DQ_GET() ) { dat=dat|0x80; } delay_us(50); } return dat; } /****************************************************************** * 函 數 名 稱:DS18B20_Write_Byte * 函 數 說 明:寫一個字節到DS18B20 * 函 數 形 參:dat:要寫入的字節 * 函 數 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void DS18B20_Write_Byte(uint8_t dat) { uint8_t i; DQ_OUT();//設置輸出模式 for (i=0;i8;i++) { if ( (dat&0x01) ) //寫1 { DQ(0); delay_us(2); DQ(1); delay_us(60); } else //寫0 { DQ(0);//拉低60us delay_us(60); DQ(1);//釋放總線 delay_us(2); } dat=dat?>>1;//傳輸下一位 } } /****************************************************************** * 函 數 名 稱:DS18B20_Check * 函 數 說 明:檢測DS18B20是否存在 * 函 數 形 參:無 * 函 數 返 回:1:未檢測到DS18B20的存在 0:存在 * 作 者:LC * 備 注:無 ******************************************************************/ uint8_t DS18B20_Check(void) { uint8_t timeout=0; //復位DS18B20 DQ_OUT(); //設置為輸出模式 DQ(0); //拉低DQ delay_us(750); //拉低750us DQ(1); //拉高DQ delay_us(15); //15us //設置為輸入模式 DQ_IN(); //等待拉低,拉低說明有應答 while ( DQ_GET() &&timeout200) { timeout++;//超時判斷 delay_us(1); }; //設備未應答 if(timeout?>=200) return 1; else timeout=0; //等待18B20釋放總線 while ( !DQ_GET() &&timeout240) { timeout++;//超時判斷 delay_us(1); }; //釋放總線失敗 if(timeout?>=240) return 1; return 0; } /****************************************************************** * 函 數 名 稱:DS18B20_Start * 函 數 說 明:DS18B20開始溫度轉換 * 函 數 形 參:無 * 函 數 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void DS18B20_Start(void) { DS18B20_Check(); //查詢是否有設備應答 DS18B20_Write_Byte(0xcc); //對總線上所有設備進行尋址 DS18B20_Write_Byte(0x44); //啟動溫度轉換 } /****************************************************************** * 函 數 名 稱:DS18B20_GetTemperture * 函 數 說 明:從ds18b20得到溫度值 * 函 數 形 參:無 * 函 數 返 回:溫度數據 * 作 者:LC * 備 注:無 ******************************************************************/ float DS18B20_GetTemperture(void) { uint16_t temp; uint8_t dataL=0,dataH=0; float value; DS18B20_Start(); DS18B20_Check(); DS18B20_Write_Byte(0xcc);//對總線上所有設備進行尋址 DS18B20_Write_Byte(0xbe);// 讀取數據命令 dataL=DS18B20_Read_Byte(); //LSB dataH=DS18B20_Read_Byte(); //MSB temp=(dataH<8)+dataL;//整合數據 if(dataH&0X80)//高位為1,說明是負溫度 { temp=(~temp)+1; value=temp*(-0.0625); } else { value=temp*0.0625; } return value; }
在文件bsp_ds18b20.h中,編寫如下代碼。
/* * Change Logs: * Date Author Notes * 2024-06-20 LCKFB-LP first version */ #ifndef _BSP_DS18B20_H_ #define _BSP_DS18B20_H_ #include "board.h" //端口移植 #define RCC_DQ_ENABLE() __RCC_GPIOB_CLK_ENABLE() #define PORT_DQ CW_GPIOB #define GPIO_DQ GPIO_PIN_0 //設置DQ輸出模式 #define DQ_OUT() { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pins = GPIO_DQ; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_Init(PORT_DQ, &GPIO_InitStruct); } //設置DQ輸入模式 #define DQ_IN() { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pins = GPIO_DQ; GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_Init(PORT_DQ, &GPIO_InitStruct); } //獲取DQ引腳的電平變化 #define DQ_GET() GPIO_ReadPin(PORT_DQ, GPIO_DQ) //DQ輸出 #define DQ(x) GPIO_WritePin(PORT_DQ, GPIO_DQ, (x?GPIO_Pin_SET:GPIO_Pin_RESET)) void DS18B20_Reset(void); uint8_t DS18B20_Check(void); char DS18B20_GPIO_Init(void); void DS18B20_Start(void); float DS18B20_GetTemperture(void); #endif
4、移植驗證
在自己工程中的main主函數中,編寫如下。
/* * Change Logs: * Date Author Notes * 2024-06-20 LCKFB-LP first version */ #include "board.h" #include "stdio.h" #include "bsp_uart.h" #include "bsp_ds18b20.h" int32_t main(void) { board_init(); // 開發板初始化 uart1_init(115200); // 串口1波特率115200 DS18B20_GPIO_Init(); while(1) { printf("溫度 = %.2frnn", DS18B20_GetTemperture() ); delay_ms(1000); } }
上電現象(手心溫度36度、37度左右):
模塊移植成功案例代碼:
鏈接:https://pan.baidu.com/s/1FHARC1eodVU-O3N6vxbfAw?pwd=LCKF
提取碼:LCKF
審核編輯 黃宇
-
溫度傳感器
+關注
關注
48文章
2917瀏覽量
155889 -
CW32
+關注
關注
1文章
187瀏覽量
590
發布評論請先 登錄
相關推薦
評論