单片机C51-笔记7-STC89C51RC/RD-DH11模块-温湿度传感器

一、概述

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

接线:

 二、逻辑分析-检测DHT响应信号

 LCD1602和DH11都是非标准协议,也就是,去看时序,按照时序写代码

a :dth = 1

b:dth = 0

b-c = 延时30ms

c:dth = 1

c-e  40us+80us = 120us/2 = 60us 取60us用来检测DHT是否响应信号了

取60us==0?

注意:

DHT1 1的供电电压为 3- 5. 5V。传感器上电后,要等待 1 s 以越过不稳定状态在此 期间无需发送任何指令。

代码如下:

#include "reg52.h"
#include "intrins.h"

sbit D5  = P3^7;
sbit dht = P3^3;

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 43;
	j = 6;
	k = 203;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void Delay30ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 2;
	j = 67;
	k = 183;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void Delay60us()		//@11.0592MHz
{
	unsigned char i, j;

	i = 1;
	j = 162;
	do
	{
		while (--j);
	} while (--i);
}


void check_DHT(){//看时序图写代码
	dht = 1;
	dht = 0;
	Delay30ms();
	dht = 1;
	Delay60us();
	if(dht == 0){//说明模块响应了,点亮D5
		D5 = 0;
	}
}

void main()
{
	D5 = 1;
	Delay1000ms();

	check_DHT();
	while(1);//程序不退出
 } 

三、逻辑分析-得到温湿度的数据

 a : dht = 1

b :dht = 0

延时30ms

c: dht = 1

卡d点;while(dht1);

卡e点 while(!dht)

卡f点:while(dht)

卡g点:while(!dht)

有效数据都是高电平,持续时间不一样,50us读,低电平0 高电平

传输0的时序分析

 

 传输1的时序分析

由上图可知,当检测g点后的大概50us的时候,是高电平还是低电平就知道传输的是1还是0.

#include "reg52.h"
#include "intrins.h"

sbit D5  = P3^7;
sbit dht = P3^3;
char datas[5];

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 43;
	j = 6;
	k = 203;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void Delay30ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 2;
	j = 67;
	k = 183;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void Delay60us()		//@11.0592MHz
{
	unsigned char i, j;

	i = 1;
	j = 162;
	do
	{
		while (--j);
	} while (--i);
}


void DHT11_Start(){//看时序图写代码
	dht = 1;
	dht = 0;
	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++){//五轮

		for(j=0;j<8;j++){//每一轮八次
			while(!dht);//等待卡G点  
			Delay60us();
			if(dht == 1){
				flag = 1;//高电平
				while(dht);
			}else{
				flag = 0;//低电平
			}
			tmp = tmp <<1;//tmp等于tmp左移一位
			tmp |= flag;//把新得到的数放到尾巴,就是逐渐的把得到的数据放到tmp里面
		}
		datas[i] = tmp;//把tmp得到的5个8位的值赋值到datas数组中
	}
}

void main()
{
	D5 = 1;
	Delay1000ms();
	
	while(1){//程序不退出
		Delay1000ms();
		Read_Data_From_DHT();
	}
 } 

四、利用串口显示出温湿度

        首先通过温湿度传感器传出来的数值,在上位机中,是化成了二进制的形式传输的,会看成字符型,比如温度是97,那么传给串口接收到的信息就是二进制的0110 0001,串口会输出数据为a,这样并不方便我们观察,所以,需要把ACILL值换成数字,数字1+48 = 49(字符1),故数字0-9与字符0-9差了48。

        思路:当我们接收到数值之后,比如32,就把3拿出来,变成字符3,再把2拿出来变成字符2,再传给上位机。这样上位机接收到的就是字符型的数据,就可以直接传输。

#include "reg52.h"
#include "intrins.h"

sbit D5  = P3^7;
sbit dht = P3^3;
sfr AUXR = 0X8e;
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 Delay30ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 54;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
void UartInit(void)
{
	AUXR = 0x01;//提升EMI信号
	SCON = 0X40;//1、配置串口工作方式,REN能接收
	TMOD &= 0XF0;
	TMOD |= 0X20;//2、配置定时器1 工作方式:8位自动重载
	
	TH1 = 0XFD;//3、计算9600波特率的初值
	TL1 = 0XFD;
	TR1 = 1;//4、启动定时器
	
}

void sendByte(char data_msg){
	SBUF = data_msg;
	while(!TI);//初值TI=0,置位后TI=1,此时请求中断
	TI =0;//手动置位
}

void sendString(char* str){
	while(*str != '\0')
    {
		sendByte(*str);
		str++;
	}
}


void DHT11_Start(){//看时序图写代码
	dht = 1;
	dht = 0;
	Delay30ms();
	dht = 1;
	while(dht);
	while(!dht);
	while(dht);
	
}

void Delay40us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	i = 15;
	while (--i);
}

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);//等待卡G点  
			D5 = 0;
			Delay40us();
			if(dht == 1){
				flag = 1;//高电平
				while(dht);
			}else{
				flag = 0;//低电平
			}
			tmp = tmp << 1;//tmp等于tmp左移一位
			tmp |= flag;//把新得到的数放到尾巴,就是逐渐的把得到的数据放到tmp里面
		}
		datas[i] = tmp;//把tmp得到的5个8位的值赋值到datas数组中
	}
}

void main()
{
	D5 = 1;
	UartInit();
	Delay1000ms();

	while(1){//程序不退出
		Delay1000ms();
		Read_Data_From_DHT();
		sendString("SD:");
		sendByte(datas[0]/10 + 0x30);//湿度整数位,提出十位
		sendByte(datas[0]%10 + 0x30);//提出个位
		sendByte('.');
		sendByte(datas[1]/10 + 0x30);//湿度的小数位,提出十位
		sendByte(datas[1]%10 + 0x30);//提出个位
		sendString("\r\n");//做个换行
		sendString("WD:");
		sendByte(datas[2]/10 + 0x30);//温度的整数位,提出十位
		sendByte(datas[2]%10 + 0x30);//提出个位
		sendByte('.');
		sendByte(datas[3]/10 + 0x30);//温度的小数位,提出十位
		sendByte(datas[3]%10 + 0x30);//提出个位
		sendString("\r\n");//做个换行
	}
 } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值