加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 01模塊來源
    • 02 規(guī)格參數(shù)
    • 03移植過程
    • ?04移植驗(yàn)證
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

【CW32模塊使用】DS18B20溫度傳感器

10/24 13:01
870
閱讀需 21 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

0?DS18B20數(shù)字溫度傳感器提供9位至12位精度的溫度測量,并具有非易失性用戶可編程上下觸發(fā)點(diǎn)報(bào)警功能。DS18B20通過單總線通信,根據(jù)定義,只需要一條數(shù)據(jù)線(和地線)即可與單片機(jī)通信。此外,DS18B20可以直接從數(shù)據(jù)線獲得電源(“寄生電源”),消除了每個(gè)DS18B20都有一個(gè)唯一的64位串行代碼,這允許多個(gè)DS18B20在同一條總線上工作。因此,使用一個(gè)微處理器來實(shí)現(xiàn)是很簡單的。

控制分布在大面積上的許多ds18b20??梢詮拇斯δ苤惺芤娴膽?yīng)用包括HVAC環(huán)境控制,建筑物,設(shè)備或機(jī)械內(nèi)部的溫度監(jiān)測系統(tǒng)以及過程監(jiān)測和控制系統(tǒng)。

01模塊來源

資料下載鏈接:https://pan.baidu.com/s/1L83uG8So6k1NG_QznraoFQ

02 規(guī)格參數(shù)

工作電壓:3-5.5V

工作電流:750nA~1.5mA

測量分辨率:9位到12位可編程分辨率

溫度量程: -55 ~ +125 ℃

測量精度:±0.5 ℃

通信協(xié)議:單總線

管腳數(shù)量:3 Pin(2.54mm間距排針

以上信息見廠家資料文件

03移植過程

我們的目標(biāo)是將例程移植至CW32F030C8T6開發(fā)板上【實(shí)現(xiàn)讀取溫度的功能】。首先要獲取資料,查看數(shù)據(jù)手冊應(yīng)如何實(shí)現(xiàn)讀取數(shù)據(jù),再移植至我們的工程。

3.1查看資料

時(shí)序說明

初始化:

將總線拉低,保存低電平至少480us。

轉(zhuǎn)為輸入模式,總線被上拉電阻拉高大約15~60us。

如果初始化成功則會(huì)產(chǎn)生一個(gè)由DS18B20所返回的低電平“0”,持續(xù)時(shí)間大約60~240us。

DS18B20釋放總線,將總線拉高。

讀時(shí)序:

將數(shù)據(jù)線拉低至少1us。

將數(shù)據(jù)線轉(zhuǎn)為輸入模式,DS18B20開始采集數(shù)據(jù),大約15us。

18B20要送出0就把總線拉為低電平直到讀周期結(jié)束。若要送出1則釋放總線為高電平。

注意:所有讀時(shí)隙必須至少需要60us,且在兩次獨(dú)立的時(shí)隙之間至少需要1us的恢復(fù)時(shí)間。

寫時(shí)序:

數(shù)據(jù)線先置低電平“0”,延時(shí)15us。

按從低位到高位的順序發(fā)送數(shù)據(jù)(一次只發(fā)送一位)。

延時(shí)60us。

拉高數(shù)據(jù)線“1”。

穿越火線1~4步驟,直到發(fā)送完整的字節(jié)。

拉高數(shù)據(jù)線,釋放總線。

寄存器說明

0xCC

主機(jī)可以使用此命令同時(shí)對總線上的所有設(shè)備進(jìn)行尋址,而無需發(fā)送其他的任何地址。 DS18B20通過發(fā)出0XCC命令,然后是溫度轉(zhuǎn)換命令[44h]來執(zhí)行同步溫度轉(zhuǎn)換。注意,只有在總線上有一個(gè)從設(shè)備時(shí),Read Scratchpad [BEh]命令才能跟隨Skip ROM命令。在這種情況下,通過允許主服務(wù)器從從服務(wù)器讀取而不發(fā)送設(shè)備的64位ROM代碼可以節(jié)省時(shí)間。如果總線上有多個(gè)從設(shè)備,那么Skip ROM命令后跟Read Scratchpad命令將導(dǎo)致數(shù)據(jù)沖突,因?yàn)槎鄠€(gè)設(shè)備將嘗試傳輸數(shù)據(jù)同時(shí)進(jìn)行。

0x44

該命令為啟動(dòng)單次溫度轉(zhuǎn)換。轉(zhuǎn)換后,產(chǎn)生的溫度數(shù)據(jù)存儲(chǔ)在地址為【BEh】的2字節(jié)溫度寄存器中。

0xBE

該命令允許主機(jī)讀取溫度寄存器上的內(nèi)容。數(shù)據(jù)傳輸從低位開始,直到讀取第9個(gè)字節(jié)(bit8=CRC)。如果只需要溫度數(shù)據(jù),主機(jī)可以在任何時(shí)候發(fā)出復(fù)位以終止讀取。

溫度換算

溫度傳感器的分辨率我們可配置為9、10、11或12位,分別對應(yīng)于0.5°C、0.25°C、 0.125°C和0.0625°C的增量。開機(jī)時(shí)的默認(rèn)分辨率是12位。我們不進(jìn)行修改,因?yàn)榉直媛试礁呔驮骄珳?zhǔn)。

例如數(shù)據(jù)手冊中的示例,如當(dāng)前當(dāng)前的溫度是+25.0625℃,寄存器讀出的高8位數(shù)據(jù)為0000 0001,低8位數(shù)據(jù)為1001 0001。將其整合得到16位數(shù)據(jù):0000 0001 1001 0001。再轉(zhuǎn)換為10進(jìn)制數(shù)據(jù)為401。將讀取到的數(shù)據(jù)乘以分辨率即可得到實(shí)際溫度。

401 * 0.0625 = 25.0625℃

2、引腳選擇

3.2引腳選擇

該模塊有3個(gè)引腳,具體引腳連接見各引腳連接。

模塊接線圖

3.3移植至工程

工程模板參考入門手冊的工程模板

移植步驟中的導(dǎo)入.c和.h文件與【CW32模塊使用】DHT11溫濕度傳感器相同,只是將.c和.h文件更改為bsp_ds18b20.c與bsp_ds18b20.h。這里不再過多講述,移植完成后面修改相關(guān)代碼。

在文件bsp_ds18b20.c中,編寫如下代碼。

/* * Change Logs: * Date           Author       Notes * 2024-06-20     LCKFB-LP    first version */
#include "bsp_ds18b20.h"#include "stdio.h"
/****************************************************************** * 函 數(shù) 名 稱:bsp_ds18b20_GPIO_Init * 函 數(shù) 說 明:MLX90614的引腳初始化 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:1未檢測到器件   0檢測到器件 * 作       者:LC * 備       注:無******************************************************************/char DS18B20_GPIO_Init(void){    unsigned char ret = 255;
    GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化結(jié)構(gòu)體
    RCC_DQ_ENABLE();        // 使能GPIO時(shí)鐘
    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;}


/****************************************************************** * 函 數(shù) 名 稱:DS18B20_Read_Byte * 函 數(shù) 說 明:從DS18B20讀取一個(gè)字節(jié) * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:讀取到的字節(jié)數(shù)據(jù) * 作       者:LC * 備       注:無******************************************************************/uint8_t DS18B20_Read_Byte(void){        uint8_t i=0,dat=0;
        for (i=0;i<8;i++)        {        DQ_OUT();//設(shè)置為輸入模式        DQ(0); //拉低        delay_us(2);        DQ(1); //釋放總線        DQ_IN();//設(shè)置為輸入模式        delay_us(12);        dat>>=1;        if( DQ_GET() )        {            dat=dat|0x80;        }        delay_us(50);     }        return dat;}
/****************************************************************** * 函 數(shù) 名 稱:DS18B20_Write_Byte * 函 數(shù) 說 明:寫一個(gè)字節(jié)到DS18B20 * 函 數(shù) 形 參:dat:要寫入的字節(jié) * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:無******************************************************************/void DS18B20_Write_Byte(uint8_t dat){        uint8_t i;        DQ_OUT();//設(shè)置輸出模式        for (i=0;i<8;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;//傳輸下一位        }}


/****************************************************************** * 函 數(shù) 名 稱:DS18B20_Check * 函 數(shù) 說 明:檢測DS18B20是否存在 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:1:未檢測到DS18B20的存在  0:存在 * 作       者:LC * 備       注:無******************************************************************/uint8_t DS18B20_Check(void){        uint8_t timeout=0;    //復(fù)位DS18B20        DQ_OUT(); //設(shè)置為輸出模式        DQ(0); //拉低DQ        delay_us(750); //拉低750us        DQ(1); //拉高DQ        delay_us(15);  //15us
    //設(shè)置為輸入模式        DQ_IN();    //等待拉低,拉低說明有應(yīng)答        while ( DQ_GET() &&timeout<200)        {                timeout++;//超時(shí)判斷                delay_us(1);        };        //設(shè)備未應(yīng)答        if(timeout>=200)                return 1;        else                timeout=0;
        //等待18B20釋放總線        while ( !DQ_GET() &&timeout<240)        {                timeout++;//超時(shí)判斷                delay_us(1);        };    //釋放總線失敗        if(timeout>=240)                return 1;
        return 0;}
/****************************************************************** * 函 數(shù) 名 稱:DS18B20_Start * 函 數(shù) 說 明:DS18B20開始溫度轉(zhuǎn)換 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:無******************************************************************/void DS18B20_Start(void){        DS18B20_Check();                //查詢是否有設(shè)備應(yīng)答        DS18B20_Write_Byte(0xcc);   //對總線上所有設(shè)備進(jìn)行尋址        DS18B20_Write_Byte(0x44);   //啟動(dòng)溫度轉(zhuǎn)換}
/****************************************************************** * 函 數(shù) 名 稱:DS18B20_GetTemperture * 函 數(shù) 說 明:從ds18b20得到溫度值 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:溫度數(shù)據(jù) * 作       者:LC * 備       注:無******************************************************************/float DS18B20_GetTemperture(void){        uint16_t temp;        uint8_t dataL=0,dataH=0;        float value;
        DS18B20_Start();        DS18B20_Check();        DS18B20_Write_Byte(0xcc);//對總線上所有設(shè)備進(jìn)行尋址        DS18B20_Write_Byte(0xbe);// 讀取數(shù)據(jù)命令        dataL=DS18B20_Read_Byte(); //LSB        dataH=DS18B20_Read_Byte(); //MSB        temp=(dataH<<8)+dataL;//整合數(shù)據(jù)

        if(dataH&0X80)//高位為1,說明是負(fù)溫度        {                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

//設(shè)置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);                         }//設(shè)置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

?04移植驗(yàn)證

在自己工程中的main主函數(shù)中,編寫如下。

/* * 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();        // 開發(fā)板初始化
    uart1_init(115200);        // 串口1波特率115200
    DS18B20_GPIO_Init();    while(1)    {        printf("溫度 = %.2frnn", DS18B20_GetTemperture() );        delay_ms(1000);    }}

上電現(xiàn)象(手心溫度36度、37度左右):

模塊移植成功案例代碼:

鏈接:https://pan.baidu.com/s/1FHARC1eodVU-O3N6vxbfAw?pwd=LCKF

提取碼:LCKF

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

以開放、共享、互助為理念,致力于構(gòu)建武漢芯源半導(dǎo)體CW32系列MCU生態(tài)社區(qū)。無論是嵌入式MCU小自還是想要攻破技術(shù)難題的工程師,亦或是需求解決方案的產(chǎn)品經(jīng)理都可在CW32生態(tài)社區(qū)汲取營養(yǎng)、共同成長。

B站