DHT11温度检测系统

本文详细介绍了DHT11数字温湿度传感器的工作原理、特点,包括其校准、信号传输、通信逻辑和代码示例,展示了如何使用DHT11进行温湿度检测以及与外部设备如LCD1602进行数据交互。
摘要由CSDN通过智能技术生成

DHT11温湿度传感器

  1. 产品概述

    DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,应用领域:暖通空调;汽车;消费品;气象站;湿度调节器;除湿器;家电;医疗;自动控制

    在这里插入图片描述

  2. 特点

    • 相对湿度和温度测量
    • 全部校准,数字输出 长期稳定性
    • 超长的信号传输距离:20米
    • 超低能耗:休眠
    • 4 引脚安装:可以买封装好的
    • 完全互换 : 直接出结果,不用转
  3. 接线

    在这里插入图片描述

  4. 数据传送逻辑

    只有一根数据线DATA,上官一号发送序列指令给DHT11模块,模块一次完整的数据传输为40bit,高位先出。

  5. 数据格式

    8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和通讯过程时序图。

    在这里插入图片描述

检测模块是否存在

根据如下时序图,做通信初始化,并检测模块是否存在,功能是否正常。

在这里插入图片描述

时序逻辑分析:

a : dht = 1
b :dht = 0
延时30ms
c: dht = 160us后读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");
		
	}
}
  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值