一.DHT11介紹
型號(hào) | 測(cè)量范圍 | 測(cè)濕精度 | 測(cè)溫精度 |
DHT11 | 20-90%RH? 0-50攝氏度°C | 士5%RH? | ?士2℃ |
二.DHT11接口說(shuō)明
1.建議連接線(xiàn)長(zhǎng)度短于20米時(shí)用5K上拉電阻,大于20米時(shí)根據(jù)實(shí)際情況使用合適的上拉電阻。
2.VCC接單片機(jī)的5v,GND接GND,DAT接單片機(jī)的IO口。
三.電源引腳
DHT11的供電電壓為3-5.5V。傳感器上電后,要等待1s以越過(guò)不穩(wěn)定狀態(tài)在此期間無(wú)需發(fā)送任何指令。電源引腳(VDD,GND)之間可增加一個(gè)100nF的電容,用以去耦濾波。
四.DHT11時(shí)序圖
DHT11初始化從圖2開(kāi)始,一開(kāi)始先給高電平,然后在給低電平(至少18ms),之后高電平持續(xù)20-40us,不確定是多少u(mài)s,可以用while卡著,定義DAT為dht,dht此時(shí)是1,則卡著while(dht),直到跳過(guò)while循環(huán)以后,DHT11開(kāi)始響應(yīng),此時(shí)dht為0,我們也可以卡著,while(!dht),之后過(guò)了while循環(huán)以后,變成了高電平1,dht=1,此時(shí)接著卡,while(dht),當(dāng)卡過(guò)以后開(kāi)始傳輸數(shù)據(jù)(紅線(xiàn)部分),如果傳的是1則是圖4,如果是0則圖5,此時(shí)只要等待紅線(xiàn)部分過(guò)去就有數(shù)據(jù),此時(shí)接著卡,while(!dht),之后給40us延遲,如果40us延遲以后還是高電平則是數(shù)據(jù)1,數(shù)據(jù)1一共要維持70us高電平,此時(shí)才維持40us,我們要卡著高電平等待過(guò)去到下一bit開(kāi)始,所以while(dht),如果是低電平則數(shù)據(jù)0,此時(shí)不需要卡著,已經(jīng)來(lái)到了下一bit開(kāi)始的位置。
五.傳輸數(shù)據(jù)
一次完整的數(shù)據(jù)傳輸為40bit,高位先出。
數(shù)據(jù)格式:8bit濕度整數(shù)數(shù)據(jù)+8 bit濕度小數(shù)數(shù)據(jù)+8bi溫度整數(shù)數(shù)據(jù)+8 bit溫度小數(shù)數(shù)據(jù)+8bit校驗(yàn)和
數(shù)據(jù)傳送正確時(shí)校驗(yàn)和數(shù)據(jù)=“8bit濕度整數(shù)數(shù)據(jù)+8bit濕度小數(shù)數(shù)據(jù)+8bi溫度整數(shù)數(shù)據(jù)+8bit溫度小數(shù)數(shù)據(jù)”所得結(jié)果的末8位。
六.DHT11測(cè)溫濕度發(fā)送到串口助手的代碼
補(bǔ)充知識(shí):下面代碼的value=value<<1,value |= flag;在是因?yàn)镈HT11傳的數(shù)據(jù)高位先出,,要循環(huán)8次,所以最后一開(kāi)始的第一位就到了二級(jí)制的最高位。
#include <REGX52.H>
#include <intrins.h>
sbit led4 = P2^3; //led小燈用來(lái)判斷模塊是否測(cè)量
sbit dht = P1^0; //溫濕度傳感器信號(hào)線(xiàn)
sbit AUXR=0x8E;
char datas[5]; //數(shù)組分別代表,濕度,濕度小數(shù),溫度,溫度小數(shù),校驗(yàn)
void Delay20ms() //@11.0592MHz
{
unsigned char i, j;
i = 36;
j = 217;
do
{
while (--j);
} while (--i);
}
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay40us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 15;
while (--i);
}
void Uart_Init()
{
AUXR = 0x01;
SCON = 0x40;
PCON &= 0x7F;
TMOD &= 0x0F; //清除定時(shí)器1模式位
TMOD |= 0x20; //設(shè)定定時(shí)器1為8位自動(dòng)重裝方式
TL1 = 0xFD; //設(shè)定定時(shí)初值
TH1 = 0xFD; //設(shè)定定時(shí)器重裝值
ET1 = 0; //禁止定時(shí)器1中斷
TR1 = 1; //啟動(dòng)定時(shí)器1
}
void Uart_Sendchar(char Char)
{
SBUF=Char;
while(TI==0);
TI=0;
}
void Uart_Sendstring(char*string)
{
while(*string!='\0')
{
Uart_Sendchar(*string);
string++;
}
}
//初始化模塊(檢測(cè)模塊是否存在)每次傳輸數(shù)據(jù)都要初始化
void DHT_Start()
{
//根據(jù)時(shí)序進(jìn)行高低電平變化
led4 = 1;
dht = 1; //對(duì)應(yīng)初始化時(shí)序start
dht = 0;
Delay20ms();
dht=1;
while(dht);
while(!dht);
while(dht);
led4 = 0;
}
void DHT11_Read()
{
char value = 0;
char flag;
char i = 0;
char j = 0;
DHT_Start();
for(j = 0;j<5;j++)//分別讀取五組數(shù)據(jù)
{
for(i=0;i<8;i++)//每組八位分別處理
{
while(!dht); //高電平開(kāi)始計(jì)時(shí)
Delay40us();
if(dht == 1) //如果還為高則是“1”
{
flag = 1;
while(dht);
}
else //否則“0”
{
flag = 0;
}
value = value << 1; //移位
value |= flag; //賦值
}
datas[j] = value; //賦值
}
}
void main()
{
Delay1000ms();Delay1000ms();
Uart_Init();
while(1)
{
Delay1000ms();
DHT11_Read();
Uart_Sendstring("H:");//濕度整數(shù)
Uart_Sendchar(datas[0]/10+0x30);//十位
Uart_Sendchar(datas[0]%10+0x30);//個(gè)位
Uart_Sendchar('.');//濕度小數(shù)
Uart_Sendchar(datas[1]/10+0x30);
Uart_Sendchar(datas[1]%10+0x30);
Uart_Sendstring("\r\n");
Uart_Sendstring("T:");//溫度整數(shù)
Uart_Sendchar(datas[2]/10+0x30);
Uart_Sendchar(datas[2]%10+0x30);
Uart_Sendchar('.');//溫度小數(shù)
Uart_Sendchar(datas[3]/10+0x30);
Uart_Sendchar(datas[3]%10+0x30);
Uart_Sendstring("\r\n");
}
}
七.DHT11測(cè)溫濕度發(fā)送到LCD1602上的代碼
#include <REGX52.H>
#include <intrins.h>
#define LCE_Dataport P0
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
sbit led4 = P2^3; //led小燈用來(lái)方便判斷DHT11有沒(méi)有在測(cè)量
sbit dht = P1^0; //溫濕度傳感器信號(hào)線(xiàn)
sbit AUXR=0x8E;
char datas[5]; //數(shù)組分別代表,濕度,濕度小數(shù),溫度,溫度小數(shù),校驗(yàn)
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
void Delay20ms() //@11.0592MHz
{
unsigned char i, j;
i = 36;
j = 217;
do
{
while (--j);
} while (--i);
}
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay40us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 15;
while (--i);
}
void LCD_WriteCommand(unsigned char Command)//寫(xiě)指令
{
LCD_RS=0;
LCD_RW=0;
LCE_Dataport=Command;
LCD_EN=1;
Delay1ms();
LCD_EN=0;
Delay1ms();
}
void LCD_WriteData(unsigned char Data)//寫(xiě)數(shù)據(jù)
{
LCD_RS=1;
LCD_RW=0;
LCE_Dataport=Data;
LCD_EN=1;
Delay1ms();
LCD_EN=0;
Delay1ms();
}
void LCD_Init()//初始化
{
LCD_WriteCommand(0x38);
LCD_WriteCommand(0x0C);
LCD_WriteCommand(0x06);
LCD_WriteCommand(0x01);
}
void LCD_Setcursor(unsigned char line,unsigned char column)
{
if(line==1)//設(shè)置光標(biāo)位置
{
//第一列是數(shù)字1,但是位置是0x00,要把數(shù)字1轉(zhuǎn)換0x00,就把數(shù)字1-1就0,所以轉(zhuǎn)十六進(jìn)制就是0x00
LCD_WriteCommand(0x80|(column-1));
}
else
{
//第二行的第一列是從0x40開(kāi)始,第二列是0x41,相當(dāng)于0x40+0x01,0x01就是與上面一致
LCD_WriteCommand(0x80|(column-1)+0x40);
}
}
void LCD_Showchar(unsigned char line,unsigned char column,unsigned char Char)//line行,column列,Char字符
{//顯示一個(gè)字符
LCD_Setcursor(line,column);
LCD_WriteData(Char);
}
void LCD_Showstring(unsigned char line,unsigned char column,unsigned char *string)//line行,column列,string字符串
{//顯示字符串,字符串直接等于指針,不用數(shù)組形式等于字符串,在等于指針形式,那傳給指針的就是字符串的第一個(gè)字符的地址,然后string【i】一直往下就可以知道字符串,數(shù)組是連續(xù)的,如果baby的b在第一行第一列,那a就會(huì)在第一行,第二列。
unsigned char i;
LCD_Setcursor(line,column);
for(i=0;string[i]!='\0';i++)
{
LCD_WriteData(string[i]);//字符串本身就是地址,所以傳進(jìn)來(lái)的字符串用指針string來(lái)接
}
}
//初始化模塊(檢測(cè)模塊是否存在)每次傳輸數(shù)據(jù)都要初始化
void DHT_Start()
{
//根據(jù)時(shí)序進(jìn)行高低電平變化
led4 = 1;
dht = 1; //對(duì)應(yīng)初始化時(shí)序start
dht = 0;
Delay20ms();
dht=1;
while(dht);
while(!dht);
while(dht);
led4=0;
}
void DHT11_Read()
{
char value = 0;
char flag;
char i = 0;
char j = 0;
DHT_Start();
for(j = 0;j<5;j++)//分別讀取五組數(shù)據(jù)
{
for(i=0;i<8;i++)//每組八位分別處理
{
while(!dht); //高電平開(kāi)始計(jì)時(shí)
Delay40us();
if(dht == 1) //如果還為高則是“1”
{
flag = 1;
while(dht);
}
else //否則“0”
{
flag = 0;
}
value = value << 1; //移位
value |= flag; //賦值
}
datas[j] = value; //賦值
}
}
void main()
{
Delay1000ms();Delay1000ms();
LCD_Init();
while(1)
{
Delay1000ms();
DHT11_Read();
LCD_Showstring(1,1,"H:");//濕度整數(shù)
LCD_Showchar(1,3,datas[0]/10+0x30);//十位
LCD_Showchar(1,4,datas[0]%10+0x30);//個(gè)位
LCD_Showchar(1,5,'.');//濕度小數(shù)
LCD_Showchar(1,6,datas[1]/10+0x30);
LCD_Showchar(1,7,datas[1]%10+0x30);
LCD_Showstring(2,1,"T:");//溫度整數(shù)
LCD_Showchar(2,3,datas[2]/10+0x30);
LCD_Showchar(2,4,datas[2]%10+0x30);
LCD_Showchar(2,5,'.');//溫度小數(shù)
LCD_Showchar(2,6,datas[3]/10+0x30);
LCD_Showchar(2,7,datas[3]%10+0x30);
}
}
八.現(xiàn)象
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-633813.html
DHT11模塊不要碰底下,不然會(huì)卡住不測(cè)量了,led4用來(lái)判斷有沒(méi)有一直在測(cè)量,閃一次就代表正測(cè)量一次?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-633813.html
到了這里,關(guān)于51單片機(jī)——DHT11溫濕度模塊的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!