DHT11是一款有已校準數字信號輸出的溫溼度傳感器。 精度溼度+-5%RH, 溫度+-2℃,量程溼度20-90%RH, 溫度0~50℃。
一.電路連接分析
1.引腳圖
2.接線圖
DHT11 器件採用簡化的單總線通信。單總線即只有一根數據線,系統中的數據交換、控制均由單總線完成。單總線通常要求外接一個約 5.1kΩ 的上拉電阻,這樣,當總線閒置時,其狀態為高電平。由於它們是主從結極,只有主機呼叫從機時,從機才能應答,因此主機訪問器件都必須嚴格遵循單總線序列,如果出現序列混亂,器件將不響應主機。
二.數據採集分析
1.數據總時序
用戶主機(MCU)發送一次開始信號後,DHT11 從低功耗模式轉換到高速模式,待主機開始信號結束後,DHT11 發送響應信號,送出 40bit 的數據,幵觸發一次信採集
2.主機發送起始信號
單片機連接DHT11的DATA引腳的I/O口輸出低電平,且低電平保持時間不能小於 18ms,然後等待 DHT11 作出應答信號。
3.檢測從機應答信號
DHT11 的 DATA 引腳檢測到外部信號有低電平時, 等待外部信號低電平結束, 延遲後 DHT11 的 DATA引腳處於輸出狀態,輸出 80 微秒的低電平作為應答信號,緊接著輸出 80 微秒的高電平通知外設準備接收數據。
4.接收數據
(1)數據判定規則
位數據“0”的格式為: 50 微秒的低電平和 26-28 微秒的高電平,位數據“1”的格式為: 50 微秒的低電平加 70微秒的高電平。
接收數據時可以先等待低電平過去,即等待數據線拉高,再延時60us,因為60us大於28us且小於70us,再檢測此時數據線是否為高,如果為高,則數據判定為1,否則為0。
(2)數據格式
一次傳送 40 位數據,高位先出
8bit 溼度整數數據 + 8bit 溼度小數數據+8bit 溫度整數數據 + 8bit 溫度小數數據+8bit 校驗位。
(3)數據校正
判斷“8bit 溼度整數數據 + 8bit 溼度小數數據+8bit 溫度整數數據 + 8bit 溫度小數數據”的結果是否等於8bit 校驗位。如果等於則數據接收正確,否則應該放棄這一次的數據,重新接收。
三.驅動程序
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit Data=P3^6; //定義數據線
uchar rec_dat[9]; //用於顯示的接收數據數組
void DHT11_delay_us(uchar n)
{
while(--n);
}
void DHT11_delay_ms(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void DHT11_start()
{
Data=1;
DHT11_delay_us(2);
Data=0;
DHT11_delay_ms(20); //延時18ms以上
Data=1;
DHT11_delay_us(30);
}
uchar DHT11_rec_byte() //接收一個字節
{
uchar i,dat=0;
for(i=0;i<8;i++) //從高到低依次接收8位數據
{
while(!Data); ////等待50us低電平過去
DHT11_delay_us(8); //延時60us,如果還為高則數據為1,否則為0
dat<<=1; //移位使正確接收8位數據,數據為0時直接移位
if(Data==1) //數據為1時,使dat加1來接收數據1
dat+=1;
while(Data); //等待數據線拉低
}
return dat;
}
void DHT11_receive() //接收40位的數據
{
uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
DHT11_start();
if(Data==0)
{
while(Data==0); //等待拉高
DHT11_delay_us(40); //拉高後延時80us
R_H=DHT11_rec_byte(); //接收溼度高八位
R_L=DHT11_rec_byte(); //接收溼度低八位
T_H=DHT11_rec_byte(); //接收溫度高八位
T_L=DHT11_rec_byte(); //接收溫度低八位
revise=DHT11_rec_byte(); //接收校正位
DHT11_delay_us(25); //結束
if((R_H+R_L+T_H+T_L)==revise) //校正
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;
}
/*數據處理,方便顯示*/
rec_dat[0]='0'+(RH/10);
rec_dat[1]='0'+(RH%10);
rec_dat[2]='R';
rec_dat[3]='H';
rec_dat[4]=' ';
rec_dat[5]=' ';
rec_dat[6]='0'+(TH/10);
rec_dat[7]='0'+(TH%10);
rec_dat[8]='C';
}
}
/*這裡使用lcd1602來顯示採集到的數據*/
void main()
{
uchar i;
lcd_init(); //lcd1602初始化
while(1)
{
DHT11_delay_ms(1500); //DHT11上電後要等待1S以越過不穩定狀態在此期間不能發送任何指令
DHT11_receive();
lcd_write_command(0x80); //從lcd1602第一行第一個位置開始顯示
for(i=0;i<9;i++)
lcd_write_data(rec_dat[i]); //顯示數據
}
}
四、實證照片
閱讀更多 趣味硬件 的文章