一,DHT11(12)傳感器簡介
DHT11 是一款溼溫度一體化的數字傳感器。該傳感器包括一個電阻式測溼元件和一個 NTC 測溫元件,通過單片機等微處理器簡單的電路連接就能夠實時的採集本地溼度和溫度。DHT11 與單片機之間能採用簡單的單總線進行通信,僅僅需要一個I/O 口。傳感器內部溼度和溫度數據 40Bit 的數據一次性傳給單片機,數據採用校驗和方式進行校驗,有效的保證數據傳輸的準確性。DHT11 功耗很低,5V 電源電壓下,工作平均最大電流 0.5mA。
溼度:
溼度,表示大氣乾燥程度的物理量。在一定的溫度下在一定體積的空氣裏含有的水汽越少,則空氣越乾燥;水汽越多,則空氣越潮溼。空氣的乾溼程度叫做“溼度”。在此意義下,常用絕對溼度、相對溼度、比較溼度、混合比、飽和差以及露點等物理量來表示;若表示在溼蒸汽中水蒸氣的重量佔蒸汽總重量(體積)的百分比,則稱之爲蒸汽的溼度。人體感覺舒適的溼度是:相對溼度低於70%(摘自百度)
工作特性:
工作電壓範圍:3.5V-5.5V
工作電流 :平均 0.5mA
溼度測量範圍:20-90%RH
溫度測量範圍:0-50℃
溼度分辨率 :1%RH 8 位
溫度分辨率 :1℃ 8 位
採樣週期 :1S
單總線結構
與 TTL 兼容(5V)
(摘自芯片手冊)
二、引腳定義
三、典型連接電路
DHT11 數字溼溫度傳感器連接方法簡單。第一腳接電源正,第四腳接電源地端。數據端爲第二腳。可直接接主機(單片機)的 I/O 口。爲提高穩定性,通常在數據端和電源正之間接一隻 4.7K左右 的上拉電阻。第三腳爲空腳,此管腳懸空不用。
四、DHT11內部數據結構
DHT11數字溼溫度傳感器採用單總線數據格式。即,單個數據引腳端口完成輸入輸出雙向傳輸。其數據包由5Byte(40Bit)組成。數據分小數部分和整數部分。
一次完整的數據傳輸爲40bit,高位先出
數據格式:
8bit溼度整數數據+8bit溼度小數數據+8bit溫度整數數據+8bit溫度小數數據+8bit校驗和
注:
1,校驗和數據爲前四個字節相加
2,傳感器數據輸出的是未編碼的二進制數據,即數據(溼度、溫度、整數、小數)之間應該分開處理
採集數據後的處理方式舉例:
(設某時刻採集的數據如下:)
byte4 byte3 byte2 byte1 byte0
00101101 00000010 00011100 00000001 01001001 (二進制)
2DH 02H 1CH 01H 49H (十進制)
45 2 28 1 76
整數 小數 整數 小數 校驗和
溼度 溫度 校驗和
由以上數據就可得到溼度和溫度的值,計算方法:
humi (溼度)= byte4 . byte3=45.2 (%RH)
temp (溫度)= byte2 . byte1=28.1 ( ℃)
(校驗和)= byte4+ byte3+ byte2+ byte1=76(=humi+temp)(校驗正確)
注意:DHT11一次通訊時間最大3ms,主機連續採樣間隔建議不小於100ms。
五、DHT11採樣時序
DHT11 開始發送數據流程:
分析:
主機發送開始信號後,延時等待 20us-40us 後讀取 DHT11 的應答信號,讀取總線爲低電平,說明 DHT11 發送響應信號,DHT11 發送響應信號後,再把總線拉高,準備發送數據,每一 bit 數據都以低電平開始,格式見如果讀取響應信號爲高電平,則 DHT11 沒有響應,請檢查線路是否連接正常。
主機復位信號和 DHT11 響應信號
數字‘0’信號表示方法
數字‘1’信號表示方法
六、DHT11程序源碼
程序源碼:
注:使用串口打印採集的溫溼度數據(1秒採集一次數據)
DHT11 h文件
//Author: Liu Xianfei 0810
#ifndef __DHT11_H
#define __DHT11_H
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
typedef struct __DHT11_2
{
u8 temperature[2]; //temperature
u8 humidity[2]; //humidity
u16 checksum; //checksum
}DHT11;
extern DHT11 dht11;
#define DHT11PORT GPIOA
#define DHT11PIN GPIO_Pin_11
#define DHT11CLK RCC_APB2Periph_GPIOA
//IO direction setting
#define DHT11_2_IO_IN() {GPIOA->CRH&=0XFFFF0FFF;GPIOA->CRH|=8<<12;}
#define DHT11_2_IO_OUT() {GPIOA->CRH&=0XFFFF0FFF;GPIOA->CRH|=3<<12;}
//IO operation function
#define DHT11_2_DQ_OUT PAout(11)
#define DHT11_2_DQ_IN PAin(11)
//Function declaration
void DHT11_2_Init(void);
u8 DHT11_2_Read_Data(void);
u8 DHT11_2_Read_Byte(void);
u8 DHT11_2_Read_Bit(void);
u8 DHT11_2_Check(void);
void DHT11_2_Rst(void);
#endif
DHT11 C文件
#include "DHT11.h"
DHT11 dht11={0,0,0,0,0};
/*
* Function name: initialize DHT11
* Parameter: None
* Return value: None
* Author: Liu Xianfei 0810
*/
void DHT11_2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(DHT11CLK,ENABLE);//Turn on the clock
//Initialization pin
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin=DHT11PIN;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(DHT11PORT,&GPIO_InitStruct);
GPIO_SetBits(DHT11PORT,DHT11PIN);//Pull up pin
}
/*
* Function name: reset DHT11
* Parameter: None
* Return value: None
*/
void DHT11_2_Rst(void)
{
DHT11_2_IO_OUT(); //SET OUTPUT
DHT11_2_DQ_OUT=0; //pull downDQ
delay_ms(20); //Pull down for at least 18ms
DHT11_2_DQ_OUT=1; //DQ=1
delay_us(30); //Main engine pull-up 20 ~ 40us
}
/*
* Function name: waiting for DHT11 to respond
* Parameter: None
* Return value: 1: DHT11 not detected 0: DHT11 detected
*/
u8 DHT11_2_Check(void)
{
u8 retry=0;
DHT11_2_IO_IN();//SET INPUT
while (DHT11_2_DQ_IN&&retry<100)//DHT11 will pull down 40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)
return 1;
else
retry=0;
//When DHT11 is pulled down, it will be pulled up again by 40-80us
while (!DHT11_2_DQ_IN&&retry<100)
{
retry++;
delay_us(1);
};
if(retry>=100)
return 1;
return 0;
}
/*
* Function name: read a bit from DHT11
* Parameter: None
* Return value: 1 or 0
*/
static u8 DHT11_2_Read_Bit(void)
{
u8 retry=0;
while(DHT11_2_DQ_IN&&retry<100)//Waiting for low level
{
retry++;
delay_us(1);
}
retry=0;
while(!DHT11_2_DQ_IN&&retry<100)//Waiting for high level
{
retry++;
delay_us(1);
}
delay_us(40);
if(DHT11_2_DQ_IN)
return 1;
else
return 0;
}
/*
* Function name: read a byte from DHT11
* Parameter: None
* Return value: data of 1B
* Author: Liu Xianfei 0810
*/
static u8 DHT11_2_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT11_2_Read_Bit();
}
return dat;
}
/*
* Function name: read data once from DHT11
* Parameter: temp: temperature value (range: 0 ~ 50 °) humi: humidity value (range: 20% ~ 90%)
* Return value: 0, normal; 1, read failed
*/
u8 DHT11_2_Read_Data(void)
{
u8 buf[5];
u8 i;
DHT11_2_Rst();
if(DHT11_2_Check()==0)
{
for(i=0;i<5;i++)//Read 40 bit data
{
buf[i]=DHT11_2_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
//Assignment
dht11.humidity[0]=buf[0];
dht11.humidity[1]=buf[1];
dht11.temperature[0]=buf[2];
dht11.temperature[1]=buf[3];
dht11.checksum=buf[4];
}
}
else
return 1;
return 0;
}
延時函數 h文件
/*
Filename: delay function
Author: Liu Xianfei 0810
Related note: use the system tick counter to realize the delay function
*/
#ifndef _delay_H
#define _delay_H
#include "sys.h"
void delay_init_liuxianfei0810(void);
void delay_ms(u16 nms);
void delay_us(u32 nus);
#endif
延時函數 c文件
#include "delay.h"
static u8 fac_us=0; //us delay multiplier
static u16 fac_ms=0; //ms delay multiplier
/*
Function name: initialization delay function
Author: Liu Xianfei 0810
Description:
Systick clock is fixed to 1/8 of HCLK clock
Sysclk: system clock
*/
void delay_init_liuxianfei0810(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
//Select external clock HCLK/8
fac_us=SystemCoreClock/8000000;
//1/8 of the system clock
fac_ms=(u16)fac_us*1000;
//Represents the number of systick clocks required per ms
}
/*
Function name: delay NUS function
Author: Liu Xianfei 0810
Description:
nus is the number of us to delay MAXnus=2^24(LOAD)/fac_us
=2^24(LOAD)/(SystemCoreClock/8000000)=2^24(LOAD)/9
*/
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //Time loading
SysTick->VAL=0x00; //Clear counter
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //Start countdown
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //Waiting time arrives
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //Turn off counter
SysTick->VAL =0X00; //Clear counter
}
/*
Function name: delay NMS function
Author: Liu Xianfei 0810
Description: Delay nms
Note the range of nms
Systick -> load is a 24 bit register, so the maximum delay is:
nms<=0xffffff*8*1000/SYSCLK
Sysclk in Hz, nms in nms
For 72MHz clock, nms <= 1864
*/
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;
//Time loading (systick ->LOAD is 24bit)
SysTick->VAL =0x00;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16)));
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL =0X00;
}