单片机——DHT11温湿度传感器

初探

总过程时序图

image.png

检测传感器是否存在

根据时序图中的部分分析如下
温控模块时序图分析.jpg
即 a→b至少18ms;b→c:20μs~40μs,c→d:80μs,则检测传感器是否存在的代码如下:注意,传感器上电后,要等待1s以越过不稳定状态,关键代码如下:

sbit led1=P3^7;
sbit heat=P1^3;
void Temperature_Module_Init()
{
	heat=1;
	heat=0;
	Delay30ms();
	heat=1;
	Delay60us();
	if(heat==0){
		led1=0;
	}
}

void main(){
	led1 = 1;
	Delay1000ms();
	Delay1000ms();
	Temperature_Module_Init();
	while(1);
}

进阶:将数据通过串口显示到PC上

分析时序图(dht代指数据接口)

image.png

  1. 由手册可以知道,单片机只需要发送初始的开始信号,后续单片机就无需发送信号
  2. a->b:此时需要单片机延时18ms
  3. b->c:此时我们将接口直接拉高,然后通过while(dht)等待电平自动降低
  4. c->d:通过while(!dht)将其卡到d点
  5. d->e:通过while(dht)卡到e点
  6. e->f:看下列数字0时序图分析

image.png
我们只需要通过while(!dht),就一定能卡到f点,然后开始接收bit数据

  1. 观察数字0和数字1时序图的不同点

image.png

  1. 很明显,我们可以知道数字1信号的时间比数字0信号的时间长,那么以此为思路,我们延迟30μ秒,再去判断dht的电平,如果依然为1,那么代表为数字信号1,反之为0
  2. 注意:
    1. 如果是数字信号1,此时依然要while(dht),直到其自动变为低电平
    2. 根据手册:每次采集完毕后DHT11会自动转换到低速模式,此时我们需要重新发送开始信号

代码实例

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

sbit led1=P3^7;
sbit dht=P1^3;
sfr AUXR = 0x8E;

char arr[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 Delay30us()		//@11.0592MHz
{
	unsigned char i;

	i = 11;
	while (--i);
}

void UartInit(void)		//9600bps@11.0592MHz
{
	//AUXR避免辐射
	AUXR = 0x01;
	//设置串行口的工作方式
	SCON = 0x40;
	//设置波特率不加倍
	PCON = 0x10;
	
	//设置定时器模式,8位自动重装
	TMOD &= 0x0F;
	TMOD |= 0x20;
	//设置定时器常数
	TH1 = 0xFD;
	TL1 = 0xFD;
	
	//启动定时器
	TR1 = 1;
}
void sendCh(char ch){
	SBUF = ch;
	while(!TI);//防止字符串还没有发送完毕,SBUF就发生了改变
	TI = 0;
}
//发送字符串
void sendString(char* str){
	while(*str != '\0'){
		sendCh(*str);
		str++;
	}
}

void Temperature_Module_Init()
{
	dht=1;
	dht=0;//a点
	Delay30ms();
	dht=1;//b点
	while(dht);//卡c点
	while(!dht);//卡d点
	while(dht);//卡e点
}

//轮询接收数据
void receive_data()
{
	
	int i;//第几轮
	int j;//第几位
	int flag;//判断电平,如果电平在30μ后依然是高电平
		//那么代表这一位是1
	
	Temperature_Module_Init();
	for(i=0; i<5;++i){
		char tmp=0;
		for(j=0; j<8;++j){
			while(!dht);//卡f点
			Delay30us();
			if(dht){
				flag = 1;
				while(dht);//卡f点
			}else {
				flag = 0;
			}
			tmp = tmp<<1;
			tmp |= flag;
		}
		arr[i]=tmp;
	}
}

void main(){
	led1 = 1;
	Delay1000ms();
	UartInit();
	Delay1000ms();
	Delay1000ms();
	while(1){
		Delay1000ms();
		receive_data();
		sendString("H:");
		sendCh(arr[0]/10+0x30);
		sendCh(arr[0]%10+0x30);
		sendString(".");
		sendCh(arr[1]/10+0x30);
		sendCh(arr[1]%10+0x30);
		sendString("\r\n");
		sendString("T:");
		sendCh(arr[2]/10+0x30);
		sendCh(arr[2]%10+0x30);
		sendString(".");
		sendCh(arr[3]/10+0x30);
		sendCh(arr[3]%10+0x30);
		sendString("\r\n");
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值