一、DHT11簡介
DHT11是一款有已校準(zhǔn)數(shù)字信號輸出的溫濕度傳感器。 其精度濕度±5%RH, 溫度±2℃,量程濕度5~95%RH, 溫度-20~+60℃。
——來自百度百科
測量范圍:濕度 5~95%RH, 溫度 -20~+60℃
測量精度:濕度 ±5%RH, 溫度 ±2℃
供電電壓:3.3~5.5V DC
輸 出:單總線數(shù)字信號
分辨率:濕度1%RH, 溫度0.1℃
關(guān)于單總線協(xié)議可以查看這篇文章:【STM32】stm32f407 + DS18B20 碰出不一樣的火花
二、編程思路
溫濕度傳感器 DHT11 和 溫度傳感器 DS18B20 均采用 單總線協(xié)議,因此兩者的編程思路很相似,不過 DHT11 增加了濕度的測量。
說明:在移植代碼時,注意引腳的變換,選擇合適的引腳,本程序中使用 PB5 作為單總線通訊的引腳。如要修改引腳,只需修改頭文件中引腳的相關(guān)宏定義。
DHT11.h
// =============================================
# @Time : 2021-08-08
# @Author : AXYZdong
# @CSDN : https://axyzdong.blog.csdn.net/
# @FileName: DHT11.h
# @Software: keil5 MDK
// =============================================
#ifndef __DTH11_H
#define __DTH11_H
#include "stm32f4xx.h"
/************************** DS18B20 連接引腳定義********************************/
#define RCC_DHT11 RCC_AHB1Periph_GPIOB
#define DHT11_DQ_GPIO_PORT GPIOB
#define DHT11_DQ_GPIO_PIN GPIO_Pin_5
/************************** DS18B20 函數(shù)宏定義********************************/
#define DHT11_DQ_L GPIO_ResetBits ( DHT11_DQ_GPIO_PORT, DHT11_DQ_GPIO_PIN )
#define DHT11_DQ_H GPIO_SetBits ( DHT11_DQ_GPIO_PORT, DHT11_DQ_GPIO_PIN )
/************************** DS18B20 函數(shù)聲明 ********************************/
void DHT11_Init(void);
u8 DHT11_Read_Data(u8 *temp,u8 *humi);
#endif /* __DS18B20_H */
DHT11.c
// =============================================
# @Time : 2021-08-08
# @Author : AXYZdong
# @CSDN : https://blog.csdn.net/qq_43328313
# @FileName: DHT11.c
# @Software: keil5 MDK
// =============================================
#include "stm32f4xx.h"
#include "dth11.h"
#include "delay.h"
/*******************************************************************************
* 函數(shù)名:DHT11_GPIO_Config
* 描述 :配置DHT11用到的I/O口
* 輸入 :無
* 輸出 :無
*******************************************************************************/
void DHT11_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_DHT11, ENABLE); /*開啟DS18B20對應(yīng)的GPIO的外設(shè)時鐘*/
GPIO_InitStructure.GPIO_Pin = DHT11_DQ_GPIO_PIN; /*選擇要控制的DS18B20引腳*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; /*設(shè)置引腳模式輸出模式*/
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /*設(shè)置引腳的輸出類型為推挽輸出*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*設(shè)置引腳速率為50MHz */
GPIO_Init(DHT11_DQ_GPIO_PORT, &GPIO_InitStructure); /*調(diào)用庫函數(shù),初始化相應(yīng)GPIO*/
}
/*******************************************************************************
* 函數(shù)名:DHT11_Mode_Out
* 描述 :使DHT11-DATA引腳變?yōu)檩敵瞿J?p> * 輸入 :無
* 輸出 :無
*******************************************************************************/
static void DHT11_Mode_Out(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*選擇要控制的DHT11_DQ_GPIO_PORT引腳*/
GPIO_InitStructure.GPIO_Pin = DHT11_DQ_GPIO_PIN;
/*設(shè)置引腳模式輸出模式*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
/*設(shè)置引腳的輸出類型為推挽輸出*/
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
/*設(shè)置引腳速率為50MHz */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*調(diào)用庫函數(shù),初始化DHT11_DQ_GPIO_PORT*/
GPIO_Init(DHT11_DQ_GPIO_PORT, &GPIO_InitStructure);
}
/*******************************************************************************
* 函數(shù)名:DHT11_Mode_IN
* 描述 :使DHT11-DATA引腳變?yōu)檩斎肽J?p> * 輸入 :無
* 輸出 :無
*******************************************************************************/
static void DHT11_Mode_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*選擇要控制的DS18B20_DQ_GPIO_PORT引腳*/
GPIO_InitStructure.GPIO_Pin = DHT11_DQ_GPIO_PIN;
/*設(shè)置引腳模式為浮空輸入模式*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
/*調(diào)用庫函數(shù),初始化DS18B20_DQ_GPIO_PORT*/
GPIO_Init(DHT11_DQ_GPIO_PORT, &GPIO_InitStructure);
}
/*******************************************************************************
* 函數(shù)名:DHT11_Reset
* 描述 :初始化DHT11
* 輸入 :無
* 輸出 :無
* 返回值:初始化成功為0,不成功為1
*******************************************************************************/
void DHT11_Reset()
{
DHT11_Mode_Out(); //SET OUTPUT
DHT11_DQ_L; //DQ=0
delay_ms(20); //拉低至少18ms
DHT11_DQ_H; //DQ=1
delay_us(30); //主機(jī)拉高20~40us
}
u8 DHT11_Check(void)
{
u8 retry=0;//定義臨時變量
DHT11_Mode_IN();//SET INPUT
while ((GPIO_ReadInputDataBit(DHT11_DQ_GPIO_PORT,DHT11_DQ_GPIO_PIN)==1)&&retry<100)//DHT11會拉低40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
else retry=0;
while ((GPIO_ReadInputDataBit(DHT11_DQ_GPIO_PORT,DHT11_DQ_GPIO_PIN)==0)&&retry<100)//DHT11拉低后會再次拉高40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
return 0;
}
//從DHT11讀取一個位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{
u8 retry=0;
while((GPIO_ReadInputDataBit(DHT11_DQ_GPIO_PORT,DHT11_DQ_GPIO_PIN)==1)&&retry<100)//等待變?yōu)榈碗娖?p> {
retry++;
delay_us(1);
}
retry=0;
while((GPIO_ReadInputDataBit(DHT11_DQ_GPIO_PORT,DHT11_DQ_GPIO_PIN)==0)&&retry<100)//等待變高電平
{
retry++;
delay_us(1);
}
delay_us(40);//等待40us
if(GPIO_ReadInputDataBit(DHT11_DQ_GPIO_PORT,DHT11_DQ_GPIO_PIN)==1)
return 1;
else
return 0;
}
//從DHT11讀取一個字節(jié)
//返回值:讀到的數(shù)據(jù)
u8 DHT11_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT11_Read_Bit();
}
return dat;
}
//從DHT11讀取一次數(shù)據(jù)
//temp:溫度值(范圍:0~50°)
//humi:濕度值(范圍:20%~90%)
//返回值:0,正常;1,讀取失敗
u8 DHT11_Read_Data(u8 *temp,u8 *humi)
{
u8 buf[5];
u8 i;
DHT11_Reset();
if(DHT11_Check()==0)
{
for(i=0;i<5;i++)//讀取40位數(shù)據(jù)
{
buf[i]=DHT11_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humi=buf[0];
*temp=buf[2];
}
}
else return 1;
return 0;
}
//初始化DHT11的IO口 DQ 同時檢測DHT11的存在
//返回1:不存在
//返回0:存在
void DHT11_Init(void)
{
DHT11_GPIO_Config();
DHT11_Reset(); //復(fù)位DHT11
DHT11_Check();//等待DHT11的回應(yīng)
}
main.c
// =============================================
# @Time : 2021-08-08
# @Author : AXYZdong
# @CSDN : https://axyzdong.blog.csdn.net/
# @FileName: main.c
# @Software: keil5 MDK
// =============================================
#include "stm32f4xx.h"
#include "delay.h"
#include "QDTFT_demo.h"
#include "Lcd_Driver.h"
#include "GUI.h"
#include "dth11.h"
#include "usart.h"
#include "bsp_key.h"
#include "time.h"
u8 wd=0, sd=0;
u8 tab_wd[5],tab_sd[5];
char set_date=28;
char Set_date[5];
int main(void)
{
SystemInit(); //System init.
delay_init(168);//Delay init.
Lcd_Init();
Lcd_Clear(WHITE);
DHT11_Init();
Debug_USART_Config();
QDTFT_Test_Demo(); //See the test details in QDTFT_Demo.c
while(1)
{
DHT11_Read_Data(&wd,&sd);
tab_wd[0] = wd/10 + 0x30;
tab_wd[1] = wd%10 + 0x30;
tab_wd[2] = 'C';
tab_sd[0] = sd/10 + 0x30;
tab_sd[1] = sd%10 + 0x30;
tab_sd[2] = '%';
Set_date[0] = set_date/10 + 0x30;
Set_date[1] = set_date%10 + 0x30;
Set_date[2] = 'C';
Gui_DrawFont_GBK16(15,30,RED,WHITE,(u8 *)tab_wd);
Gui_DrawFont_GBK16(15,70,RED,WHITE,(u8 *)tab_sd);
Gui_DrawFont_GBK16(87,90,RED,WHITE,(u8 *)Set_date);
}
}
現(xiàn)象:TFT屏幕上顯示當(dāng)前的溫度值和濕度值。
三、總結(jié)
DHT11 驅(qū)動函數(shù)的編寫;
將溫濕度數(shù)據(jù)存儲在數(shù)組中,利用相關(guān)顯示函數(shù)將溫濕度顯示在屏幕上;
關(guān)于溫濕度數(shù)據(jù)的讀取,由于環(huán)境中溫濕度變化不是很快,可以放在定時器里面讀取。(本程序是放在了主函數(shù)中讀取)
上一篇:【STM32】EXTI---外部中斷/事件控制器
下一篇:【STM32】PWM 輸出 (標(biāo)準(zhǔn)庫)
推薦閱讀
史海拾趣
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- Microchip 升級數(shù)字信號控制器(DSC)產(chǎn)品線 推出PWM 分辨率和 ADC 速度業(yè)界領(lǐng)先的新器件
- 意法半導(dǎo)體STM32MP23x:突破成本限制的工業(yè)AI應(yīng)用核心
- 意法半導(dǎo)體推出用于匹配遠(yuǎn)距離無線微控制器STM32WL33的集成的匹配濾波芯片
- ESP32開發(fā)板連接TFT顯示屏ST7789跳坑記
- 如何讓ESP32支持analogWrite函數(shù)
- LGVL配合FreeType為可變字體設(shè)置字重-ESP32篇
- 使用樹莓派進(jìn)行 ESP32 Jtag 調(diào)試
- ESP32怎么在SPIFFS里面存儲html,css,js文件,以及網(wǎng)頁和arduino的通訊
- ESP32 freeRTOS使用測試
- BOE(京東方)聯(lián)合榮耀打造榮耀Magic V5 以領(lǐng)先LTPO技術(shù)打造行業(yè)新標(biāo)桿
- 華為ADS 4發(fā)布:多傳感器融合,提升自動駕駛安全性
- 曉鶯說:線控制動變革風(fēng)云
- 大眾商用車推出AirConsole 將其信息娛樂系統(tǒng)擴(kuò)展為游戲機(jī)
- 福州大學(xué)發(fā)明新機(jī)器視覺傳感器 可使機(jī)器人對極端光照做出超快反應(yīng)
- 蘋果獲沉浸式虛擬顯示器相關(guān)的專利
- 英特爾汽車“折戟”,十年布局一夜歸零
- 寶馬自動充電機(jī)器人概念驗證成功,引領(lǐng)無人充電新時代
- 智駕模式下LQR最優(yōu)算法在EPS中的應(yīng)用研究
- 6月超17款人形機(jī)器人新品推出
- 富士康積極布局移動機(jī)器人,比亞迪也不甘落后
- 移動機(jī)器人和仿生軟手結(jié)合實現(xiàn)完整的氣動機(jī)器人系統(tǒng)
- 工業(yè)機(jī)器人發(fā)展前景一片藍(lán)海,國內(nèi)市場面臨創(chuàng)新挑戰(zhàn)
- 利亞德:正努力尋求與蘋果在Mini LED背光方面合作
- 廣東駿亞預(yù)計上半年凈利潤1.14億元到1.21億元
- OLED屏竟然可以“印刷”出來 液晶表示高度恐慌
- 頻頻為我們帶來各種黑科技的索尼 2019年或發(fā)布17款新品電視
- 2018空凈市場趨冷 創(chuàng)新是挑戰(zhàn)亦是轉(zhuǎn)機(jī)
- 5G來了 家電業(yè)要有什么變化
- 提升物聯(lián)網(wǎng)能力,安富利將收購Softweb Solutions