前言
当你点进看这篇博客时,相信对DHT11产品的概述与特性没有任何兴趣,所以跳过那部分,直接上技术活。
1、温湿度如何采集
根据产品说明文档:用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集, 用户可选择读取部分数据.在模式下,DHT11接收到开始信号触发一次温湿度采集, 如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。所以从中我们能提取出三个主要点:
- 主机开始信号结束后,才会有数据发出,并触发一次信号采集。
- 发出的是一次40bit数据:
8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和 - 读取数据。
2、时序分析
- 如何在代码层面表示出开始信号从发出到结束,开始传送数据
如图所示:在a处dht=1,在b处dht=0,根据时序图所示,主机至少拉低18ms,我们可以在这里考虑用个延时,比如延时个30ms。然后到C处,dht=1。接下来就是DHT发送响应信号在D处,那我们如何判断到了D处。很明显,上图并没有给显示时间多久到D处,但有一个点我们可以注意到,D处是低电平0。所以我们可以考虑卡个临界点while(dht);同理如何表明进入E处,卡个临界点while(!dht);进入F处卡个临界点
while(dht);数据开始发送。代码如下:
void DHT11_Start()
{
dht=1;
dht=0;
//延时30ms
Delay30ms();
dht = 1;
while(dht);
while(!dht);
while(dht);
}
- 如何从DHT11读取数据
高电平表示有效数据,而高电平的长短定了数据位是0或1:
DHT发送响应信号后,输出40bit数据,由5部分组成,每一部分为8bit。所以可以从主体上想到用两个for循环。并定义一个临时的tmp变量,用于存储每8bit数据,再将它存入一个数组。
编码如下:
void Read_Data_From_DHT()
{
int i;
int j;
char tmp;
char flag;
DHT11_start();
for(i=0;i<5;i++){
for(j=0;j<8;j++){
while(!dht);//有效数据都是高电平
Delay40us();
if(dht == 1){
flag=1; //数据位是1
while(dht);//数据位是1,持续70us,所以卡个临界点
}else{
flag = 0;//数据位是0
}
tmp = tmp << 1;//左移一位
tmp |= flag; //将一位数据位0或1存入tmp
}
datas[i] = tmp;
}
}
补充说明左移运算符<< 左移会让最高位溢出(也就是把最高位抛弃),向低位补0.
3、代码实现
功能:读取温湿度数据文章来源:https://www.toymoban.com/news/detail-489847.html
#include "reg52.h"
#include "intrins.h"
sbit dht = P1^0;
char datas[5];
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 Delay60us() //@11.0592MHz
{
unsigned char i;
i = 25;
while (--i);
}
void Delay30ms() //@11.0592MHz
{
unsigned char i, j;
i = 54;
j = 199;
do
{
while (--j);
} while (--i);
}
void DHT11_Start()
{
dht=1;
dht=0;
//延时30ms
Delay30ms();
dht = 1;
while(dht);
while(!dht);
while(dht);
}
void Read_Data_From_DHT()
{
int i;
int j;
char tmp;
char flag;
DHT11_Start();
for(i=0;i<5;i++){
//有效数据都是高电平,持续时间不一样,50us读
for(j=0;j<8;j++){
while(!dht);
Delay40us();
if(dht ==1){
flag = 1; //模式0或1
while(dht);
}else{
flag = 0;
}
tmp = tmp <<1;
tmp |= flag;
}
datas[i] = tmp;
}
}
void main()
{
Delay1000ms();
Delay1000ms();
while(1){
Delay1000ms();
Read_Data_From_DHT();
}
}
最后,上述代码运行后,并不会看到结果来验证代码是否正确,可以加上串口代码在电脑端显示,也可以在单片机上加上蓝牙模块或LCD1602模块显示数据。有关方面的代码请参考前面的博客,自行整理一下即可。有问题欢迎留言讨论!文章来源地址https://www.toymoban.com/news/detail-489847.html
到了这里,关于基于C51的DHT11(温湿度传感器)编程(详解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!