前言
DHT11數(shù)字溫濕度傳感器是一種數(shù)字信號輸出的溫濕度傳感器,具有高可靠性和長期穩(wěn)定性。它采用專用的數(shù)字模塊和溫濕度傳感技術(shù),提供準(zhǔn)確的溫濕度數(shù)據(jù)。傳感器內(nèi)部包含感濕元件和測溫元件,并與高性能單片機(jī)連接。因此,該傳感器具有優(yōu)異的品質(zhì)、快速響應(yīng)、抗干擾能力強(qiáng)和性價比高等特點(diǎn)。每個傳感器都在濕度校準(zhǔn)室中進(jìn)行精確校準(zhǔn),校準(zhǔn)系數(shù)以程序方式存儲在內(nèi)存中,用于信號處理過程。它采用單線制串行接口,方便系統(tǒng)集成。此外,它體積小、功耗低,信號傳輸距離可達(dá)20米以上,適用于各種應(yīng)用場合。
一、接口說明
建議連接線長度短于20米時用5K上拉電阻,大于20米時根據(jù)實(shí)際情況使用合適的上拉電阻。
1 接線圖
2 電源引腳
DHT11的供電電壓為3~5.5 V。傳感器上電后,要等待 1s 以越過不穩(wěn)定狀態(tài),在此期間無需發(fā)送任何指令。電源引腳(VDD,GND)之間可增加一個100nF 的電容,用以去耦濾波。
三、測量分辨率與電氣特性
測量分辨率分別為 8bit(溫度)、8bit(濕度)。
VDD=5V,T = 25℃,除非特殊標(biāo)注
四、使用注意事項
- 如果工作條件超出建議范圍,可能會導(dǎo)致臨時性漂移信號和傳感器老化?;謴?fù)處理可以加速恢復(fù)過程。
- 化學(xué)物質(zhì)會干擾傳感器的感應(yīng)層,導(dǎo)致測量值漂移和靈敏度下降。高濃度的化學(xué)污染可能會損壞感應(yīng)層。
- 恢復(fù)處理程序可以將傳感器恢復(fù)到校準(zhǔn)狀態(tài),通過在特定濕度和溫度條件下保持一段時間實(shí)現(xiàn)。
- 溫度會影響濕度傳感器的測量結(jié)果,所以應(yīng)盡量保持傳感器在相同溫度下工作,避免與釋放熱量的電子元件靠近。
- 長時間暴露在太陽光或紫外線下,會降低傳感器性能。
- DATA信號線的質(zhì)量會影響通訊距離和質(zhì)量,建議使用高質(zhì)量的屏蔽線。
五、DHT11驅(qū)動程序
1 DHT11.c
1.1 配置輸入輸出GPIO
1.2 復(fù)位DHT11
復(fù)位DHT11就是發(fā)送DHT11起始信號,告訴傳感器通訊開始。
1.3 檢查DHT11是否正常
檢查DHT11是否正常,正常的話會在單片機(jī)發(fā)送起始信號完成后,傳感器返回80us低電平,然后發(fā)送80us高電平。即證明DHT11工作正常,該函數(shù)工作正常返回0,否則返回1,該函數(shù)中利用了while循環(huán)檢測在一定時間內(nèi)的電平變化,此類用法在后面也會經(jīng)常用到。
1.4 DHT11初始化
在上電后,對IO端口初始化,和檢查DHT11狀態(tài)。需要特別指出的是,在上電后到對DHT11初始化前應(yīng)有1s的穩(wěn)定期,等待傳感器穩(wěn)定。可以在單片機(jī)上電后采用1s延時處理。
1.5 讀取一位數(shù)據(jù)(返回值0/1)
該函數(shù)采用兩個while循環(huán)是等待每個周期的電平變化,先等待低電平到來,后等待高電平到來,延時40us后判斷引腳電平,來判斷該位數(shù)據(jù)為1或0。之所以是40微秒是因?yàn)閭鞲衅鲾?shù)字0的信號持續(xù)時間為26-28us,數(shù)字1的信號持續(xù)時間為70us,選擇一個中值來區(qū)分兩種信號,當(dāng)然也可以選擇其他值,但最好在40us附近,在while循環(huán)中選擇循環(huán)100次也就是100us,是因?yàn)榉乐巩?dāng)單片機(jī)由于某些原因遲遲收不到傳感器電平信號,造成死機(jī)。
1.6 讀取一個字節(jié)(返回值:讀到的數(shù)據(jù))
循環(huán)讀入一個字節(jié)的數(shù)據(jù),并將每一步新加入的數(shù)據(jù)放置在最低位。
1.7 讀取DHT11數(shù)據(jù)(讀取成功返回0,失敗返回1)
讀取數(shù)據(jù)將數(shù)據(jù)存入數(shù)組,這里僅保留了溫度數(shù)據(jù)的整數(shù)位,注意數(shù)據(jù)較驗(yàn)方法,校驗(yàn)和數(shù)據(jù)等于“8bit濕度整數(shù)數(shù)據(jù)+8bit濕度小數(shù)數(shù)據(jù) +8bi溫度整數(shù)數(shù)據(jù)+8bit溫度小數(shù)數(shù)據(jù)”所得結(jié)果的末8位。文章來源:http://www.zghlxwxcb.cn/news/detail-844480.html
1.8 完成版.c文件文章來源地址http://www.zghlxwxcb.cn/news/detail-844480.html
#include "stm32f10x.h" // Device header
#include "DHT11.h"
#include "Delay.h"
void DHT11_IO_OUT (void){ //溫濕度模塊輸出函數(shù)
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DHT11_IO; //選擇端口號(0~15或all)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //設(shè)置IO接口速度(2/10/50MHz)
GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}
void DHT11_IO_IN (void){ //溫濕度模塊輸入函數(shù)
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DHT11_IO; //選擇端口號(0~15或all)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入
GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}
void DHT11_RST (void){ //DHT11端口復(fù)位,發(fā)出起始信號(IO發(fā)送)
DHT11_IO_OUT(); //端口為輸出
GPIO_ResetBits(DHT11_PORT,DHT11_IO); //使總線為低電平
Delay_ms(20); //拉低至少18ms
GPIO_SetBits(DHT11_PORT,DHT11_IO); //使總線為高電平
Delay_us(30); //主機(jī)拉高20~40us
}
u8 DHT11_Check(void){ //等待DHT11回應(yīng),返回1:未檢測到DHT11,返回0:成功(IO接收)
u8 retry=0; //定義臨時變量
DHT11_IO_IN(); //IO到輸入狀態(tài)
//GPIO端口輸入時,配置為上拉輸入或者浮空輸入,因?yàn)橥饨由侠娮瑁阅J(rèn)為高電平
//如果DHT11的數(shù)據(jù)線輸入為高電平,且 retry 小于100,則將 retry 加1,并延時1微秒,重復(fù)這個過程直到 retry 大于等于100 或者DHT11的數(shù)據(jù)線輸入變成低電平。如果 retry 大于等于100,表示檢測失敗,返回1;否則,將 retry 重置為0。
while ((GPIO_ReadInputDataBit(DHT11_PORT,DHT11_IO) == 1) && retry<100) //DHT11會拉低40~80us
{
retry++;
Delay_us(1);
}
if(retry>=100)return 1;
else retry=0;
//如果DHT11的數(shù)據(jù)線輸入為低電平,且 retry 小于100,則將 retry 加1,并延時1微秒,重復(fù)這個過程直到 retry 大于等于100 或者DHT11的數(shù)據(jù)線輸入變成高電平。如果 retry 大于等于100,表示檢測失敗,返回1;否則,返回0,表示檢測成功。
while ((GPIO_ReadInputDataBit(DHT11_PORT,DHT11_IO) == 0) && retry<100) //DHT11拉低后會再次拉高40~80us
{
retry++;
Delay_us(1);
}
if(retry>=100)return 1;
return 0;
}
u8 DHT11_Init (void){ //DHT11初始化
RCC_APB2PeriphClockCmd(DHT11_RCC,ENABLE); //開始DHT11的時鐘
DHT11_RST(); //DHT11端口復(fù)位,發(fā)出起始信號
return DHT11_Check(); //等待DHT11回應(yīng)
}
//從DHT11讀取一個位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{
u8 retry = 0;
while((GPIO_ReadInputDataBit(DHT11_PORT,DHT11_IO) == 1) && retry < 100) //等待變?yōu)榈碗娖?/span>
{
retry++;
Delay_us(1);
}
retry = 0;
while((GPIO_ReadInputDataBit(DHT11_PORT,DHT11_IO) == 0) && retry < 100) //等待變高電平
{
retry++;
Delay_us(1);
}
Delay_us(40);//等待40us
if(GPIO_ReadInputDataBit(DHT11_PORT,DHT11_IO) == 1) //用于判斷高低電平,即數(shù)據(jù)1或0
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; //左移運(yùn)算符,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_RST(); //DHT11端口復(fù)位,發(fā)出起始信號
if(DHT11_Check() == 0) //等待DHT11回應(yīng),0為成功回應(yīng)
{
for(i = 0; i < 5; i++) //讀取40位數(shù)據(jù)
{
buf[i] = DHT11_Read_Byte(); //讀出數(shù)據(jù)
}
if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) //數(shù)據(jù)校驗(yàn)
{
*humi = buf[0]; //將濕度值放入指針humi
*temp = buf[2]; //將溫度值放入指針temp
}
}
else return 1;
return 0;
}
到了這里,關(guān)于STM32+DHT11溫濕度傳感器(含完整代碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!