基于Mega128的DHT11溫濕度傳感器
還有,DHT11的數(shù)據(jù)口最好要接一個上拉電阻,或者單片機(jī)內(nèi)部上拉也可以。
DHT11的數(shù)據(jù)手冊網(wǎng)上有,上面有時序操作的詳細(xì)介紹。個人建議寫這個程序的時候要一邊寫一邊檢測(比如寫完復(fù)位子程序之后就在主函數(shù)中調(diào)用它一次,看它是否執(zhí)行成功。。。),不然很可能到最后找不到錯誤出在哪里,本人就是一直寫完然后不好使,最后又重寫的!
閑話不說了,下面幫助大家分析一下DHT11的時序圖(數(shù)據(jù)手冊上有),因為DHT11對時序的要求很高,所以很可能寫完程序不好使。本人建議:延時子函數(shù)最好自己用示波器檢測一下,自己算出來的在10us下誤差會很大的。
進(jìn)入正題:下面我說的話可以參照下面的程序看。
數(shù)據(jù)手冊前面的一些內(nèi)容自己了解就可以了,先看數(shù)據(jù)手冊上主機(jī)復(fù)位信號和DHT11相應(yīng)信號那部分。
主機(jī)先控制總線,拉低至少18ms,然后再拉高20~40us,(這時如果硬件沒有問題的話DHT11會有響應(yīng)的)所以現(xiàn)在主機(jī)釋放總線(把DDRXN 寄存器清零),等待DHT11的響應(yīng),如果成功DHT11會產(chǎn)生40~50us的低電平,和40~50us的高電平。這里可以由程序完成檢測。
接下來在一次采集中,把總線一直交給DHT11,它會給主機(jī)傳送一個40位的二進(jìn)制數(shù),前0~7位是濕度的整數(shù)部分,8~15位是濕度的小數(shù)部分;16~23位是溫度的整數(shù)部分,24~31位是溫度的小數(shù)部分;最后八位是校驗位。這些數(shù)據(jù)要通過程序進(jìn)行處理,轉(zhuǎn)換成溫濕度的實際值,并由顯示部分顯示出來。(本人用的是數(shù)碼管,建議用1602顯示會更方便一些)。
后面的處理部分我就不一一講解了,我在程序中是有注釋的,自己把程序加入到工程中看效果會好很多的,也可以用專門的閱讀軟件來看(source insignte),不然字體都一個顏色非常亂。
如果有不懂的地方或者程序有什么不足之處給我留言就好了,我會及時幫助大家解決的^_^!!!
程序代碼的完整版本下載地址是:http://www.51hei.com/f/dht11.rar
程序代碼的完整版本下載地址是:http://www.51hei.com/f/dht11.rar
================================================//這里是delay.h /*************我開發(fā)板的晶振是16M的,具體的延時子函數(shù)要自己仔細(xì)寫*************/#ifndef __DELAY_H#define __DELAY_Hvoid delay_us(unsigned int xus);void delay_ms(unsigned int xms);#endif================================================//這里是delay.c#include"delay.h"#include//延時微妙子函數(shù)void delay_us(unsigned int xus){unsigned int i,j;for(i=0;i #endif#ifndef __MACROS_H#include #endif#define DDR_1 DDRC|=BIT(PC0)#define DDR_0 DDRC&=~BIT(PC0)#define PORTC_1 PORTC|=BIT(PC0)#define PORTC_0 PORTC&=~BIT(PC0)#define DQ (PINC&0x01)void caiji(void);long int dht(void);void init_dht11(void);//void ceshi(void);#endif================================================//這里是dht11.c#include"dht11.h"unsigned char dht_data[5],a,b;unsigned int s1,s0,t1,t0,sd,wd,wsd;void caiji(void){unsigned char i,j;//delay_ms(900);for(i=0;i<5;i++){dht_data[i]=0x00; //數(shù)組清零for(j=0;j<8;j++){while(!DQ); //判斷是否為高電平//延時50us若為高電平則為一,否則為零delay_us(50);if(DQ){dht_data[i]|=BIT(7-j); //保存數(shù)據(jù)while(DQ);//低電平檢測}}}}void init_dht11(void){DDR_1; //設(shè)置主機(jī)輸出PORTC_0; //總線拉低至少18msdelay_ms(20);PORTC_1; //總線由主機(jī)拉高大約30usdelay_us(30);DDR_0; //主機(jī)設(shè)置為輸入,檢測從機(jī)信號while(DQ);}long int dht(void){init_dht11();if(!DQ){while(!DQ);while(DQ); //經(jīng)以上兩句后開始接收信號caiji();DDR_1;PORTC_1;//校驗a=(dht_data[0]+dht_data[1]+dht_data[2]+dht_data[3]);if(a==dht_data[4]){s1=dht_data[0];s0=dht_data[1];t1=dht_data[2];t0=dht_data[3];}//s為濕度,t為溫度sd=s1;sd<<=8;sd|=s0;wd=t1;wd<<=8;wd|=t0;wsd=sd<<16;wsd|=wd;} return wsd;}
評論