0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32外接DHT11溫濕度傳感器并通過OLED進(jìn)行數(shù)據(jù)顯示的設(shè)計(jì)電路與程序

碼農(nóng)愛學(xué)習(xí) ? 來源:碼農(nóng)愛學(xué)習(xí) ? 作者:碼農(nóng)愛學(xué)習(xí) ? 2022-06-07 09:09 ? 次閱讀

本篇介紹STM32如何外接溫濕度傳感器實(shí)現(xiàn)當(dāng)前環(huán)境溫濕度的讀取,并顯示到OLED屏幕上。

1 DTH11溫濕度傳感器

DHT11數(shù)字溫濕度傳感器是一款含有已校準(zhǔn)數(shù)字信號(hào)輸出的溫濕度復(fù)合傳感器,包括一個(gè)電阻式感濕元件和一個(gè)NTC測溫元件。

pYYBAGKeI0KAYkwXAABY5VeVh9M655.png

1.1 數(shù)據(jù)讀取協(xié)議

微控制器MCU與 DHT11之間的通訊和同步,采用單總線數(shù)據(jù)格式,一次通訊時(shí)間4ms左右。

用戶MCU發(fā)送一次開始信號(hào)后,DHT11從低功耗模式轉(zhuǎn)換到高速模式,等待主機(jī)開始信號(hào)結(jié)束后,DHT11發(fā)送響應(yīng)信號(hào),送出40bit的數(shù)據(jù),并觸發(fā)一次信號(hào)采集,用戶可選擇讀取部分?jǐn)?shù)據(jù)。

從模式下,DHT11接收到開始信號(hào)觸發(fā)一次溫濕度采集,如果沒有接收到主機(jī)發(fā)送開始信號(hào),DHT11不會(huì)主動(dòng)進(jìn)行溫濕度采集。采集數(shù)據(jù)后轉(zhuǎn)換到低速模式。

1.1.1 起始信號(hào)

總線空閑狀態(tài)為高電平,MCU把總線拉低等待DHT11響應(yīng),MCU把總線拉低必須大于18毫秒,保證DHT11能檢測到起始信號(hào)。

DHT11接收到主機(jī)的開始信號(hào)后,等待MCU的開始信號(hào)結(jié)束,然后發(fā)送80us低電平響應(yīng)信號(hào)。

MCU發(fā)送開始信號(hào)結(jié)束后,延時(shí)等待20-40us后,讀取DHT11的響應(yīng)信號(hào),MCU發(fā)送開始信號(hào)后,可以切換到輸入模式,或者輸出高電平均可,總線由上拉電阻拉高。

poYBAGKeI0qACqJrAACYOJAsx1w271.png

1.1.2 數(shù)據(jù)數(shù)字信號(hào)

總線為低電平,說明DHT11發(fā)送響應(yīng)信號(hào),DHT11發(fā)送響應(yīng)信號(hào)后,再把總線拉高80us,準(zhǔn)備發(fā)送數(shù)據(jù),每一bit數(shù)據(jù)都以50us低電平時(shí)隙開始,高電平的長短定了數(shù)據(jù)位是0還是1。

數(shù)字0和數(shù)字1的表示,如下面圖示:

數(shù)字0:50us低電平開始后,26-28us的高電平表示0

數(shù)字1:50us低電平開始后,70us的高電平表示1

如果讀取響應(yīng)信號(hào)為高電平,則DHT11沒有響應(yīng),需要檢查線路是否連接正常。

pYYBAGKeI1GAJ_FXAAFhGv-1YVM724.png

當(dāng)最后一bit數(shù)據(jù)傳送完畢后,DHT11拉低總線50us,隨后總線由上拉電阻拉高進(jìn)入空閑狀態(tài)。

1.1.3 溫濕度數(shù)據(jù)格式

一次完整的數(shù)據(jù)傳輸為40bit,高位先出。數(shù)據(jù)分小數(shù)部分和整數(shù)部分,數(shù)據(jù)格式:

8bit濕度整數(shù)數(shù)據(jù)

8bit濕度小數(shù)數(shù)據(jù)

8bit溫度整數(shù)數(shù)據(jù)

8bit溫度小數(shù)數(shù)據(jù)

8bit校驗(yàn)和

數(shù)據(jù)傳送正確時(shí)校驗(yàn)和數(shù)據(jù)等于“ 8bit 濕度整數(shù)數(shù)據(jù) +8bit 濕度小數(shù)數(shù)據(jù)+8bit溫度整數(shù)數(shù)據(jù) +8bit 溫度小數(shù)數(shù)據(jù) ”所得結(jié)果的末8位。

1.2 硬件接線

DHT11的數(shù)據(jù)讀取只需要一根線,我使用的是PB8,另外,OLED用來顯示溫濕度的值,使用IIC通信,使用的是PB6和PB7。

pYYBAGKeI1mASyrHAAELN-XAScw161.png

2 程序編寫

根據(jù)DHT11的數(shù)據(jù)讀取協(xié)議,編寫對應(yīng)的數(shù)據(jù)讀取函數(shù)。

2.1 DHT11復(fù)位和檢測響應(yīng)函數(shù)

首先是MCU向DHT11發(fā)送的起始信號(hào),拉低20ms,再拉高30us。

u8 DHT11RstAndCheck(void)
{
    u8 timer = 0;

    __set_PRIMASK(1);          //關(guān)總中斷
    DHT11_OUT = 0; 	           //輸出低電平
    delay_ms(20);    	       //拉低至少18ms
    DHT11_OUT = 1; 	           //輸出高電平
    delay_us(30);     	       //拉高20~40us
    while (!DHT11_IN)          //等待總線拉低,DHT11會(huì)拉低40~80us作為響應(yīng)信號(hào)
    {
        timer++;               //總線拉低時(shí)計(jì)數(shù)
        delay_us(1);
    }
    if (timer>100 || timer<20) //判斷響應(yīng)時(shí)間
    {
        __set_PRIMASK(0);      //開總中斷
        return 0;
    }
	
    timer = 0;
    while (DHT11_IN)           //等待DHT11釋放總線,持續(xù)時(shí)間40~80us
    {
        timer++;               //總線拉高時(shí)計(jì)數(shù)
        delay_us(1);
    }
    __set_PRIMASK(0);          //開總中斷
    if (timer>100 || timer<20) //檢測響應(yīng)信號(hào)之后的高電平
    {
        return 0;
    }
	
    return 1;
}

2.2 數(shù)據(jù)讀取

MCU向DHT11發(fā)送起始信號(hào)后,就可以接收DHT11的數(shù)據(jù)返回了,一次讀取濕度和溫度即可。

/*讀取一字節(jié)數(shù)據(jù),返回值-讀到的數(shù)據(jù)*/
u8 DHT11ReadByte(void)
{
    u8 i;
    u8 byt = 0;

    __set_PRIMASK(1);      //關(guān)總中斷
    for (i=0; i<8; i++)
    {
        while (DHT11_IN);  //等待低電平,數(shù)據(jù)位前都有50us低電平時(shí)隙
		
        while (!DHT11_IN); //等待高電平,開始傳輸數(shù)據(jù)位
		
        delay_us(40);
        byt <<= 1;         //因高位在前,所以左移byt,最低位補(bǔ)0
        if (DHT11_IN)      //將總線電平值讀取到byt最低位中
        {
            byt |= 0x01;
        }
    }
    __set_PRIMASK(0);      //開總中斷

    return byt;
}

/*讀取一次數(shù)據(jù),返回參數(shù):Humi-濕度,Temp-溫度;返回值: 0-成功,1-失敗*/
u8 DHT11ReadData(float *Humi, float *Temp)
{
    s8 sta = 0;
    u8 i;
    u8 buf[5];

    if (DHT11RstAndCheck())         //檢測響應(yīng)信號(hào)
    {
        for(i=0;i<5;i++)            //讀取40位數(shù)據(jù)
        {
            buf[i]=DHT11ReadByte(); //讀取1字節(jié)數(shù)據(jù)
        }
        if(buf[0]+buf[1]+buf[2]+buf[3] == buf[4]) //校驗(yàn)成功
        {
            u8 H_inte = buf[0]; //濕度整數(shù)部分?jǐn)?shù)據(jù)
			u8 H_frac = buf[1]; //濕度小數(shù)部分?jǐn)?shù)據(jù)
            u8 T_inte = buf[2]; //溫度整數(shù)部分?jǐn)?shù)據(jù)
			u8 T_frac = buf[3]; //溫度小數(shù)部分?jǐn)?shù)據(jù)
			
			char tmp1[8], tmp2[8];
			sprintf(tmp1, "%d.%d",H_inte,H_frac);
			sscanf(tmp1, "%f", Humi);
			sprintf(tmp2, "%d.%d",T_inte,T_frac);
			sscanf(tmp2, "%f", Temp);
        }
        sta = 0;
    }
    else //響應(yīng)失敗返回-1
    {
        *Humi = 88; //響應(yīng)失敗返回-1
        *Temp = 88; //響應(yīng)失敗返回-1
        sta = 1;
    }
    
    return sta;    
}

2.3 初始化

使用DHT11之前,進(jìn)行引腳的初始化和器件的初始化。

/*DHT11初始化函數(shù)*/
u8 DHT11Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能GPIOC端口時(shí)鐘
    GPIO_SetBits(GPIOB,GPIO_Pin_8);                     //設(shè)置PC13輸出高電平,(先設(shè)置引腳電平可以避免IO初始化過程中可能產(chǎn)生的毛刺)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;	        //設(shè)置DHT11數(shù)據(jù)引腳->PC13
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;    //設(shè)置為開漏輸出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //設(shè)置輸出速率為50MHz
    GPIO_Init(GPIOB, &GPIO_InitStructure);	            //初始化GPIOC端口

    return DHT11RstAndCheck();                          //返回DHT11狀態(tài)
}

3 測試

在移植過U8g2庫的hello_world例程上進(jìn)行修改,在屏幕上顯示溫濕度。注意攝氏度單位的小圓圈,不知道怎么直接以符號(hào)的形式顯示出來,我這里是單獨(dú)畫了一個(gè)小空心圓。

int main(void)
{	
	delay_init();	    //延時(shí)函數(shù)初始化	  
	LED_Init();		  	//初始化與LED連接的硬件接口
	IIC_Init();
	 
	u8g2_t u8g2;
	u8g2Init(&u8g2);
	u8g2_SetFontMode(&u8g2, 1);
	u8g2_SetFont(&u8g2, u8g2_font_unifont_t_symbols);
	
	DHT11Init();
	float Temp = 0;
	float Humi = 0;
	char strTemp[32];
	char strHumi[32];
	while(1)
	{
		u8g2_FirstPage(&u8g2);
		do
		{
			//draw(&u8g2);
			DHT11ReadData(&Humi, &Temp);
			sprintf(strTemp, "Temp: %.1f C", Temp);
			sprintf(strHumi, "Humi: %.1f %%", Humi);
			
			u8g2_ClearBuffer(&u8g2);
			u8g2_DrawStr(&u8g2, 0, 30, strTemp);
			u8g2_DrawCircle(&u8g2, 84, 22, 2, U8G2_DRAW_ALL);
		    u8g2_DrawStr(&u8g2, 0, 60, strHumi);
			u8g2_SendBuffer(&u8g2);			
			delay_ms(3000);
		} while (u8g2_NextPage(&u8g2));
    }
}

測試效果如下:

poYBAGKeI2SAB1d2AAHnclpA9_s846.png

4 總結(jié)

本篇介紹了如何在STM32上外接溫濕度DHT11實(shí)現(xiàn)溫濕度數(shù)據(jù)的讀取,并通過OLED進(jìn)行數(shù)據(jù)顯示。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6030

    文章

    44491

    瀏覽量

    632029
  • 嵌入式
    +關(guān)注

    關(guān)注

    5060

    文章

    18975

    瀏覽量

    302094
  • STM32
    +關(guān)注

    關(guān)注

    2264

    文章

    10854

    瀏覽量

    354318
  • DHT11
    +關(guān)注

    關(guān)注

    19

    文章

    276

    瀏覽量

    57517
收藏 人收藏

    評論

    相關(guān)推薦

    基于arduino的dht11溫濕度傳感器的使用

    本文介紹了DHT11溫濕度傳感器電氣特性、DHT11封裝形式及接口說明與典型應(yīng)用電路,其次介紹了DHT1
    發(fā)表于 01-22 15:50 ?4.5w次閱讀
    基于arduino的<b class='flag-5'>dht11</b><b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b>的使用

    DHT11溫濕度傳感器介紹

    DHT11溫濕度傳感器介紹,1.實(shí)物原理圖2.模塊說明2.1 DHT11產(chǎn)品概述DHT11數(shù)字溫濕度
    發(fā)表于 07-21 09:04

    使用DHT11溫濕度傳感器

    STM32F407ZGT6開發(fā)板進(jìn)行項(xiàng)目開發(fā),選用的傳感器為常見通用的DHT11溫濕度傳感器
    發(fā)表于 08-10 06:14

    DHT11溫濕度傳感器

    一、實(shí)驗(yàn)?zāi)康牟捎肁RM結(jié)構(gòu)中最為代表的Cortex-M4系列的芯片,選用STM32F407ZGT6開發(fā)板進(jìn)行項(xiàng)目開發(fā),選用的傳感器為常見通用的DHT11
    發(fā)表于 08-10 07:36

    基于STM32開發(fā)板實(shí)現(xiàn)傳感數(shù)據(jù)采集-DHT11溫濕度采集

    STM32F407ZGT6開發(fā)板進(jìn)行項(xiàng)目開發(fā),選用的傳感器為常見通用的DHT11溫濕度傳感器。
    發(fā)表于 08-10 07:41

    使用STM32來讀取DHT11數(shù)字溫濕度傳感器

    基于STM32 -DHT11 數(shù)字溫濕度傳感器實(shí)驗(yàn)實(shí)驗(yàn)?zāi)康模哼@個(gè)實(shí)驗(yàn)的目的使用 STM32來讀取DHT1
    發(fā)表于 11-10 08:58

    如何通過NodeMCU和DHT11收集溫濕度

    使用 NodeMCU 和 DHT11 傳感器通過 MQTT 上傳溫濕度數(shù)據(jù)簡介本示例將演示如何通過 NodeMCU,
    發(fā)表于 11-24 08:08

    如何使用STM32 HAL庫進(jìn)行開發(fā)驅(qū)動(dòng)DHT11溫濕度傳感器

    DHT11是什么?如何使用STM32 HAL庫進(jìn)行開發(fā)驅(qū)動(dòng)DHT11溫濕度
    發(fā)表于 12-01 06:33

    DHT11溫濕度傳感器簡介

    DHT11溫濕度傳感器1、DHT11簡介DHT11數(shù)字溫濕度
    發(fā)表于 02-16 06:55

    DHT11溫濕度傳感器程序下載

    DHT11溫濕度傳感器程序下載
    發(fā)表于 11-28 16:17 ?32次下載

    使用51單片機(jī)應(yīng)用DHT11溫濕度傳感器通過1602顯示程序免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用51單片機(jī)應(yīng)用DHT11溫濕度傳感器通過1602顯示程序免費(fèi)下
    發(fā)表于 11-14 08:00 ?147次下載
    使用51單片機(jī)應(yīng)用<b class='flag-5'>DHT11</b><b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b><b class='flag-5'>通過</b>1602<b class='flag-5'>顯示</b>的<b class='flag-5'>程序</b>免費(fèi)下載

    使用 NodeMCU 和 DHT11 傳感器通過 MQTT 上傳溫濕度數(shù)據(jù)

    使用 NodeMCU 和 DHT11 傳感器通過 MQTT 上傳溫濕度數(shù)據(jù)簡介本示例將演示如何通過 NodeMCU,
    發(fā)表于 11-16 10:06 ?29次下載
    使用 NodeMCU 和 <b class='flag-5'>DHT11</b> <b class='flag-5'>傳感器</b><b class='flag-5'>通過</b> MQTT 上傳<b class='flag-5'>溫濕度數(shù)據(jù)</b>

    溫濕度傳感器DHT11STM32驅(qū)動(dòng)實(shí)現(xiàn)

    溫濕度傳感器DHT11STM32驅(qū)動(dòng)實(shí)現(xiàn)
    發(fā)表于 11-25 20:36 ?76次下載
    <b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b><b class='flag-5'>DHT11</b>的<b class='flag-5'>STM32</b>驅(qū)動(dòng)實(shí)現(xiàn)

    DHT11溫濕度+OLED顯示

    DHT11溫濕度傳感器1、DHT11簡介DHT11數(shù)字溫濕度
    發(fā)表于 12-17 18:24 ?54次下載
    <b class='flag-5'>DHT11</b><b class='flag-5'>溫濕度</b>+<b class='flag-5'>OLED</b><b class='flag-5'>顯示</b>

    使用ESP8266驅(qū)動(dòng)DHT11溫濕度傳感器

    DHT11數(shù)字溫濕度傳感器是一款含有已校準(zhǔn)數(shù)字信號(hào)輸出的溫濕度綜合傳感器,在Arduino提高篇中已對其
    的頭像 發(fā)表于 05-19 14:20 ?6190次閱讀
    使用ESP8266驅(qū)動(dòng)<b class='flag-5'>DHT11</b><b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b>