DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,小数部分用于以后扩展,现读出为零。
数据格式:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验和。
(1)工作总时序
(2) 数据通信开始时序
解读:总线空闲状态为高电平,总线拉低必须大于18毫秒,发出开始的信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可。总线拉高,主机等待DHT11响应DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号,主机发送开始信号结束后,延时等待20-40us后,读取DHT11的响应信号。
(3)数据0信号时序
(4)数据1信号时序
解读: 总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短判断数据位是0还是1。最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。 二、硬件原理图三、软件代码
#include四、效果#include #include typedef unsigned char uint8_t; typedef unsigned int uint32_t; typedef unsigned long uint32; int pinNumber = 29; void pi_sendstartsingnal(void) { pinMode(pinNumber,OUTPUT); digitalWrite(pinNumber, 1); delayMicroseconds(10); digitalWrite(pinNumber, 0); delay(30); digitalWrite(pinNumber, 1); delayMicroseconds(30); pinMode(pinNumber, INPUT); pullUpDnControl(pinNumber,PUD_UP); } int32_t dht11_read_data(uint8_t *pdht11_data) { uint8_t data=0; uint8_t *p = pdht11_data; int32_t i=0,j=0; uint32_t check_sum=0; int32_t dht11_level_cnt=0;//超时计数器 pi_sendstartsingnal(); //1.等待Pin9的电平变为低电平 dht11_level_cnt=0; while(digitalRead(pinNumber))//添加超时处理 { dht11_level_cnt++; delayMicroseconds(1); if(dht11_level_cnt >= 4000) { return -1; } } //2.测量Pin9引脚低电平持续的时间 dht11_level_cnt=0; while(!digitalRead(pinNumber))//超时判断电平的合法性 { dht11_level_cnt++; delayMicroseconds(1); if(dht11_level_cnt >= 100) { return -2; } } //3.测量Pin9引脚高电平持续的时间 dht11_level_cnt=0; while(digitalRead(pinNumber))//超时判断电平的合法性 { dht11_level_cnt++; delayMicroseconds(1); if(dht11_level_cnt >= 100) { return -3; } } //循环接收5个字节 for(j=0;j<5; j++) { //进行正常一个字节接收 for(data=0,i=7; i>=0; i--) { //1.判断每个数据0/数据1 dht11_level_cnt=0; while(digitalRead(pinNumber)==0) { dht11_level_cnt++; delayMicroseconds(1); if(dht11_level_cnt >= 100) { return -4; } } //2.延时40us左右(50us+40us=90us)数据0与数据1的划分时间:78us delayMicroseconds(30); //3.判断当前引脚的电平 if(digitalRead(pinNumber)) { data|=1<= 50) { return -5; } } } } p[j]=data; } //数据结束可以忽略,延时100us delayMicroseconds(100); //4.进行校验和 check_sum=(p[0]+p[1]+p[2]+p[3])&0xFF; if(check_sum != p[4]) return -6; return 0; } int main(void) { uint8_t buf[4]={0}; int32_t rt=0; if(wiringPiSetup()==-1) { return 1; } pinMode(pinNumber,OUTPUT); digitalWrite(pinNumber, 1); while(1) { rt = dht11_read_data(buf); if(!rt) { printf("OK!n"); printf("RH:%d.%dCn",buf[2],buf[3]); printf("TMP:%d.%dn",buf[0],buf[1]); } else { printf("dht11 read error,code = %drn",rt); } //两次测量间隔要设置合理时间ms delay(3000); } return 0; }



