DHT11温湿度传感器在51单片机中的应用
一、DHT11 模块参数如下:
1 可以检测周围环境的湿度和温度
2 传感器采用 DHT11
3 湿度测量范围: 20%-95%( 0 度-50 度范围)湿度测量误差: ±5%
4 温度测量范围: 0 度-50 度 温度测量误差: ±2 度
4 工作电压 3.3V-5V
5 输出形式 数字输出
6 设有固定螺栓孔,方便安装
7 小板 PCB 尺寸: 3.2cm * 1.4cm
8 电源指示灯(红色)
二、模块电路图
注意:这是模块的电路图,图中DATA引脚之所以要加上拉电阻,是应为dht11传感器中有如下介绍:
所以我们如果后面开发不买上面成品温湿度模块,我们可以买那种只有三针引脚的温湿度传感器(如下图)自己按照上面的电路图自己焊电路。最后好奇的童鞋会不会问,那为什么要加上拉电阻呢?这些童鞋可以往后看,在后面时序图中我们可以知道DHT会发送高电平信号,这里加入上拉电阻可以实现输出真正意义上的高电平哦。
三、 DHT11 模块接线说明
1 VCC 外接 3.3V-5V
2 GND 外接 GND
3 DATA 小板开关数字量输出接口 接单片机 IO 口
四、 DHT11 测试说明
编译环境: keil4
测试单片机 STC89C52
DHT11 模块与单片机连接: VCC-VCC 、GND-GND、 DATA-P2.0
从DHT11的DATA引脚总共接收 40位数据,具体如下:
温度高 8 位 串口发送的第一个数据
温度低 8 位 串口发送的第二个数据(默认为 00)
湿度高 8 位 串口发送的第三个数据
湿度低 8 位 串口发送的第四个数据(默认为 00)
校验 8 位 串口发送的第五个数据
五、 DHT11 功能函数
DHT11.C文件
sbit thd11=P2^0;//定义DHT11温湿度数据引脚DATA/*------------------------------------------------DHT11延时函数------------------------------------------------*/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--);}/*--------------------------------------------DHT11开始信号------------------------------------------------*/void DHT11_start(){thd11=1;DHT11_delay_us(2);thd11=0;DHT11_delay_ms(20); //延时18ms以上thd11=1;DHT11_delay_us(30);}/*------------------------------------------------接收八位二进制------------------------------------------------*/uchar DHT11_rec_byte()//接收一个字节{unsigned char i,dat=0;for(i=0;i<8;i++) //从高到低依次接收8位数据{while(!thd11); 等待50us低电平过去DHT11_delay_us(8);//延时60us,如果还为高则数据为1,否则为0 dat<<=1; //移位使正确接收8位数据,数据为0时直接移位if(thd11==1) //数据为1时,使dat加1来接收数据1dat+=1;while(thd11); //等待数据线拉低 } return dat;}/*------------------------------------------------接收40bit数据(具体的温湿度)------------------------------------------------*/void DHT11_receive(uchar *rec_dat)//接收40位的数据{uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise; DHT11_start();if(thd11==0){while(thd11==0); //等待拉高DHT11_delay_us(80); //拉高后延时80usR_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]='0'+(TH/10);rec_dat[3]='0'+(TH%10);}}
是不是很多人和我最开始接触单片机一样,不会用模块手册/芯片手册,我在这里还是附上如何看手册编写源程序的方法吧!
单片机时序是指单片机执行指令时发出的控制信号的时间序列。这些信号在时间上的相互关系就是CPU的时序。CPU发出的时序有两类:1. 用于片内各功能部件的控制,它们是芯片设计师关注的问题,对用户没有什么意义2. 用于片外存储器或I/O端口的控制,需要通过器件的控制引脚送到片外,这部分时序对分析硬件电路的原理至关重要,也是软件编程遵循的原则,需要认真掌握。
上图为单片机和DHT11之间通信的时序图。从时序图中可知:
1、主机先拉低总线进行发送开始信号,然后再将总线拉高等待DHT11响应主机。此时DHT11从低功耗模式转换到高速模式,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集。
2、DHT11接收到主机的开始信号后,等待主机开始信号结束,再发送低电平响应信号,然后将总线拉高准备输出。
3、DHT11拉高总线后,就开始给主机传输数据了。
4、DHT11数据传输完后,会将总线拉低50us,通知主机结束(主机将总线拉高)。
1、下面是开始信号的编写方法:
总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。主机发送开始信号结束后,延时等待20-40us后, 开始读取DHT11的响应信号。
/*--------------------------------------------DHT11开始信号------------------------------------------------*/void DHT11_start(){thd11=1;//总线先拉高DHT11_delay_us(2);thd11=0;//总线拉低DHT11_delay_ms(20); //延时18ms以上thd11=1;//总线拉高DHT11_delay_us(30);//延时等待20-40us后}
2、下面是接收数据的编写方法
上图就是DHT11接收到开始信号后,它对总线的时序图。可知:
1、发送80us的低电平响应信号。
2、然后它将总线拉高80us的高电平,为传输数据(温湿度等)做准备。
3、开始在总线上传输数据(此时单片机就可以接收数据了)
作用:所以我们通过上面时序图就可以判断DHT11从什么时候开始响应主机的?而主机也就可以在根据总线的情况,在正确的时间去接收DHT11发送的数据了。
注意:DHT11会一次性发送40位数据,所以主机也要一次性接收40位数据哦。
这个比较简单,就是简单的判断总线电平变化。我这里就不贴代码,最上面有代码,按照时序图一步一步分析就行!
3、接收的数据是0/1的判断方法
从上面的时序图可知,DHT11在发送数据前都会有一个50us低电平的开始时间,然后输出高电平,这才是真正的数据。根据高电平的时间区分是0还是1。
下面为程序中我们如何按照时序图真确接收数据的方法:
/*------------------------------------------------接收八位二进制------------------------------------------------*/uchar DHT11_rec_byte()//接收一个字节{unsigned char i,dat=0;for(i=0;i<8;i++) //从高到低依次接收8位数据{while(!thd11); 等待50us低电平过去DHT11_delay_us(60);//延时60us,如果还为高则数据为1,否则为0 dat<<=1; //移位使正确接收8位数据,数据为0时直接移位if(thd11==1) //数据为1时,使dat加1来接收数据1dat+=1;while(thd11); //如果为数据1,就要等待数据线拉低,让数据1的信号过去 } return dat;}
总结:从手册中我们可知要接收5次,每次8位二进制,分别对应湿度整数、小数…等。
注意:
在单片机中,只用将上述代码封装在一个“.c”文件中,然后在main函数里 做两步:
1、char dht11_data[4]; //定义用于接收DHT11温湿度数据的数组–保存湿度和温度。
2、DHT11_receive(dht11_data);//调用函数获取温湿度值到dht11_datas数组(博主没有保存最后的校验位),因此就可以显示值了
至于想研究文件中uchar DHT11_rec_byte();void DHT11_start();的写作原理,请参考DHT11的说明手册,都是根据手册中的时序图写的。
手册链接: DHT11说明书.
是不是特别简单,好用记得点赞哦🤭
如果觉得《单片机——DHT11 温湿度传感器》对你有帮助,请点赞、收藏,并留下你的观点哦!