DHT11温湿度传感器
-
产品概述
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,应用领域:暖通空调;汽车;消费品;气象站;湿度调节器;除湿器;家电;医疗;自动控制
-
特点
- 相对湿度和温度测量
- 全部校准,数字输出 长期稳定性
- 超长的信号传输距离:20米
- 超低能耗:休眠
- 4 引脚安装:可以买封装好的
- 完全互换 : 直接出结果,不用转
-
接线
-
数据传送逻辑
只有一根数据线DATA,上官一号发送序列指令给DHT11模块,模块一次完整的数据传输为40bit,高位先出。
-
数据格式
8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和通讯过程时序图。
检测模块是否存在
根据如下时序图,做通信初始化,并检测模块是否存在,功能是否正常。
时序逻辑分析:
a : dht = 1
b :dht = 0
延时30ms
c: dht = 1
在60us后读d点,如果d点是低电平(被模块拉低),说明模块存在!
代码实现
#include "reg52.h"
#include "intrins.h"
sbit led1 = P3^7;
sbit dht = P3^3;//温度传感器
void Delay30ms() //@11.0592MHz
{
unsigned char i, j;
i = 54;
j = 199;
do
{
while (--j);
} while (--i);
}
void Delay60us() //@11.0592MHz
{
unsigned char i;
i = 25;
while (--i);
}
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 check()
{
//a : dht = 1
dht = 1;
//b :dht = 0
dht = 0;
//延时30ms
Delay30ms();
//c: dht = 1
dht = 1;
//在60us后读d点,如果d点是低电平(被模块拉低),说明模块存在!
Delay60us();
if(dht == 0){
led1 = 0;//小灯亮
}
}
void main()
{
led1 = 1;
Delay1000ms();
Delay1000ms();
check();
while(1);
}
DHT11模块检测温湿度
DHT11传输0的时序分析
DHT11传输1的时序分析
代码实现
#include "reg52.h"
#include "intrins.h"
#define BUFF P0
sfr AUXR = 0x8E;
sbit led1 = P3^7;//根据原理图(电路图),设备变量led1指向P3组IO口的第7口
sbit dht = P3^3;//温度传感器
/*
控制线接口:
RS -- P1.0
RW -- P1.1
E -- P1.4
*/
sbit RS = P1^0;
sbit RW = P1^1;
sbit EN = P1^4;
char datas[5] = 0;
void Delay30ms() //@11.0592MHz
{
unsigned char i, j;
i = 54;
j = 199;
do
{
while (--j);
} while (--i);
}
void Delay60us() //@11.0592MHz
{
unsigned char i;
i = 25;
while (--i);
}
void Delay40us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 15;
while (--i);
}
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 Delay15ms() //@11.0592MHz
{
unsigned char i, j;
i = 27;
j = 226;
do
{
while (--j);
} while (--i);
}
void Delay5ms() //@11.0592MHz
{
unsigned char i, j;
i = 9;
j = 244;
do
{
while (--j);
} while (--i);
}
void DHT11_start()//启动DHT11模块开始检测
{
dht = 1;
dht = 0;
//延时30ms
Delay30ms();
dht = 1;
//卡d点;while(dht); 卡e点 while(!dht) 卡f点:while(dht)
while(dht);
while(!dht);
while(dht);
}
void get_Data()
{
int i;
int j;
char tmp;
char flag;
DHT11_start();//每次检测得到40bit数据后都要再启动一次
for(i=0;i<5;i++){
for(j=0;j<8;j++){
//卡g点:while(!dht)
while(!dht);
//有效数据都是高电平,持续时间不一样,40us读,低电平数据为0 高电平数据为1
Delay40us();
if(dht == 1){
flag = 1;
while(dht);
}else{
flag = 0;
}
tmp <<= 1;
tmp |= flag;
}
datas[i] = tmp;
}
}
void UartInit(void) //9600bps@11.0592MHz
{
AUXR = 0x01;//提升系统EMI性能
PCON = 0x00;//SMOD0 = 0时SCON中的SM0,和SM1一起指定串行口的工作方式
SCON = 0x40;//串口工作方式1,且REN=0,禁止串口接收
TMOD &= 0x0F;
TMOD |= 0x20;//定时器1的工作方式8位自动重装
TH1 = 0xFD;
TL1 = 0xFD;//9600bps的TH1初值
TR1 = 1;//启动定时器
}
void send_byte(char data_msg)
{
SBUF = data_msg;
while(!TI);
TI = 0;
}
void send_str(char* data_msg)
{
while(*data_msg != '\0'){
send_byte(*data_msg);
data_msg++;
}
}
void check_busy()//每次写指令,读/写数据操作均需要检测忙信号
{
char tmp = 0x80;
BUFF = 0x80;
while(tmp & 0x80){
RS = 0;
RW = 1;
EN = 0;
_nop_();
EN = 1;
_nop_();
tmp = BUFF;
_nop_();
_nop_();
EN = 0;
_nop_();
}
}
void Write_cmd(char cmd)//写指令
{
check_busy();
RS = 0;
RW = 0;
EN = 0;
_nop_();
BUFF = cmd;
_nop_();
EN = 1;
_nop_();
_nop_();
EN = 0;
_nop_();
}
void Write_data(char _data)//写数据
{
check_busy();
RS = 1;
RW = 0;
EN = 0;
_nop_();
BUFF = _data;
_nop_();
EN = 1;
_nop_();
_nop_();
EN = 0;
_nop_();
}
void LCD1602_init()//模块初始化
{
//(1)延时 15ms
Delay15ms();
//(2)写指令 38H(不检测忙信号)
Write_cmd(0x38);
//(3)延时 5ms
Delay5ms();
//(4)以后每次写指令,读/写数据操作均需要检测忙信号
//(5)写指令 38H:显示模式设置
Write_cmd(0x38);
//(6)写指令 08H:显示关闭
Write_cmd(0x08);
//(7)写指令 01H:显示清屏
Write_cmd(0x01);
//(8)写指令 06H:显示光标移动设置
Write_cmd(0x06);
//(9)写指令 0CH:显示开及光标设置
Write_cmd(0x0c);
}
void LCD1602_print_line(char line,char col,char *string)//写入一行数据
{
switch(line){//switch选择那一行
case 1:
Write_cmd(0x80+col);//col 决定从哪个地方开始
while(*string){
Write_data(*string);
string++;
}
break;
case 2:
Write_cmd(0x80+0x40+col);
while(*string){
Write_data(*string);
string++;
}
break;
}
}
void main()
{
led1 = 1;
UartInit();
Delay1000ms();
Delay1000ms();
while(1){
Delay1000ms();
get_Data();
send_str("Wet:");
//数字加上0x30,装变成对应的字符
send_byte(datas[0]/10 + 0x30);//湿度十位
send_byte(datas[0]%10 + 0x30);//湿度个位
send_byte('.');
send_byte(datas[1]/10 + 0x30);//小数位
send_byte(datas[1]%10 + 0x30);
send_str("\r\n");
send_str("Tem:");
send_byte(datas[2]/10 + 0x30);//温度十位
send_byte(datas[2]%10 + 0x30);//温度个位
send_byte('.');
send_byte(datas[3]/10 + 0x30);//小数位
send_byte(datas[3]%10 + 0x30);
send_str("\r\n");
}
}