目录
1、产品概述
DHT11数字温湿度传感器是一款含有已校准数字信号输出温湿度符合传感器,应用领域:温通空调;汽车;消费品;气象站;湿度调节器;除湿器;家电;医疗;自动控制
2、产品特点
相对湿度和温度的测量
全部校准,数字输出
长期稳定
超长的信号传输距离:20米
超低能耗:休眠
4引脚安装:我们这里用到的是封装好的
完全交换:直接出结果不用转化
3、数据传送逻辑
封装好的一共有3根引脚分别是GND、VCC、DATA,这里只有一根数据线DATA,单片机发送序列指令给DHT11模块,模块一次完整的数据传输为40bit,高位先出
4、数据格式
8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据 +8bit校验
数据通讯过程时序图
主机与模块的通信过程
总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须要大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后DHT11发送80us低电平响应信号,主机发送开始信号结束后,延时等待20-40us后读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可,总线由上拉电阻拉高。
5、检测模块是否存在
用户MCU发送一次开始信号后,DHT11从低功耗模式转换为高功耗模式,等待主机开始信号结束后,DHT11发送响应信号(总线为低电平,说明DHT11发送响应信号)
检测信号代码
sbit Dht11 = P3^3;
//Dht11 Data接线
void DHT11_DSR()
{
Dht11 = 1;
_nop_();
_nop_();//给延时
Dht11 = 0;
Delay30ms();//拉低30ms
Dht11 = 1;
while(Dht11);//DHT响应信号
while(!Dht11);//DHT拉高
while(Dht11);//准备开始发送信号
led1 = 0;//让小灯亮
}
当模块响应时灯会亮
6、数据传输
首先我们要先对传输的信号进行判断
6.1数字0信号的表示方法
6.2数字1信号表示方法
根据两个时序图我们可以发现1和0的区分要根据高电平的持续时间,这里我们可以在总线高电平之后延时40us然后再对电位进行测量如果时高电平则此时传输的数据就是1反之则为0
char Data[5];//对传感器的数据进行存储
void DHT11TransferData()
{
char cmd;
char flag;
int i,j;
DHT11_DSR();//每次数据传输之前都要对模块进行唤醒也就是检测是否存在
for(i = 0;i < 5;i++){//5bit数据
for(j = 0;j < 8;j++){//1bit=8个二进制位
while(!Dht11);//卡总线变为高电平的点
Delay40us();//延时40us进行电位检测
if(Dht11 == 1){
//flag = 1;
cmd <<= 1;//位运算
cmd |= Dht11;
while(Dht11);
}else{
//flag=0;
cmd <<= 1;//位运算
cmd |= Dht11;
}
//cmd <<= 1;//位运算
//cmd |= flag;
}
Data[i] = cmd;
}
led2 = 0;
}
对DHT11的操作就这些了,我们获取了数据但是我们看不到,这里先用串口接收数据在串口上进行显示具体代码
#include "reg52.h"
#include "intrins.h"
sbit led1 = P3^7;//根据原理图(电路图),设备变量led1指向P3组IO口的第7口
sbit led2 = P3^6;//根据原理图(电路图),设备变量led2指向P3组IO口的第6口
sbit Dht11 = P3^3;
sfr AUXR = 0x8e;
char Data[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 Delay40us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 15;
while (--i);
}
void Delay30ms() //@11.0592MHz
{
unsigned char i, j;
i = 54;
j = 199;
do
{
while (--j);
} while (--i);
}
void DHT11_DSR()
{
Dht11 = 1;
_nop_();
_nop_();
Dht11 = 0;
Delay30ms();
Dht11 = 1;
while(Dht11);//DHT响应信号
while(!Dht11);//DHT拉高
while(Dht11);//准备开始发送信号
led1 = 0;
}
void DHT11TransferData()
{
char cmd;
char flag;
int i,j;
DHT11_DSR();
for(i = 0;i < 5;i++){
for(j = 0;j < 8;j++){
while(!Dht11);
Delay40us();
if(Dht11 == 1){
//flag = 1;
cmd <<= 1;//位运算
cmd |= Dht11;
while(Dht11);
}else{
//flag=0;
cmd <<= 1;//位运算
cmd |= Dht11;
}
//cmd <<= 1;//位运算
//cmd |= flag;
}
Data[i] = cmd;
}
led2 = 0;
}
void UART0_Init(){//串口初始化
SCON = 0x50;
PCON &= 0x7F;
AUXR = 0x01;
TMOD &= 0x0F;
TMOD |= 0x20;
TL1 = 0xFD;
TH1 = 0xFD;
TF1 = 0;
TR1 = 1;
}
void TransferChar(char c)
{
SBUF = c;
while(!TI);
TI = 0;
}
void TransferString(char* s)
{
while(*s != '\0'){
TransferChar(*s);
s++;
}
}
void main()
{
Delay1000ms();//上电之后等待1秒让传感器稳定下来
led1 = 1;//上电先让两个灯灭
led2 = 1;
UART0_Init();
while(1){
Delay1000ms();
Delay1000ms();
Delay1000ms();
Delay1000ms();
Delay1000ms();
//延时5秒然后进行测温
DHT11TransferData();
TransferString("H:");
//因为模块传输过来的是数字,我们要把它转变为字符型
TransferChar(Data[0]/10 + 0x30);
TransferChar(Data[0]%10 + 0x30);
TransferChar('.');
TransferChar(Data[1]/10 + 0x30);
TransferChar(Data[1]%10 + 0x30);
TransferString("\r\n");
TransferString("T:");
TransferChar(Data[2]/10 + 0x30);
TransferChar(Data[2]%10 + 0x30);
TransferChar('.');
TransferChar(Data[3]/10 + 0x30);
TransferChar(Data[3]%10 + 0x30);
TransferString("\r\n");
led1 = 1;//根据电路图,低电平点亮led
led2 = 1;
}
}