C51+DHT11单总线通信协议的温湿度测量小项目的终结

我的风格就是先上代码!

main函数段:

#include <REGX52.h>
#include <INTRINS.h>
#include <delay_500ms.h>
#include <usart.h>
#include <dht11.h>

extern unsigned char TH;
extern unsigned char TL;
extern unsigned char HH;
extern unsigned char HL;

void main()
{ 
	UartInit();
	while(1)

{	
  DHT11_Receive_40bit();
	sendbyte(TH);
	Delay500ms();
	sendbyte(HH);
	Delay500ms();
}
}
QQ:1504012979    name:Vincent njw     glut

DHT11驱动函数段:

#include <REGX52.H>
#include "dht11.h"
#include "delay_500ms.h"

sbit DATE=P2^0;

unsigned char TH;
unsigned char TL;
unsigned char HH;
unsigned char HL;
unsigned char CHECK;


//起始信号
void DHT_start()
{ Delay500ms();//每一次卡开始都要等待一秒左右,让DHT11越过不稳定状态
	Delay500ms();
	DATE=1;
	delay30us();
	DATE=0;
	delay20ms();//低电平延时>18ms
	DATE=1;
	delay30us();
	DATE=1;
}

//接收一个字节
unsigned char DHT11_Receive_Byte()
{
	unsigned char i,b=0;//b表示接收到的一个字节数据
	for(i=0;i<8;i++)
{
	while(!DATE);
	delay30us();
	b<<=1;
	if(DATE==1)
	b|=0x01;
	while(DATE);
}
  return b;
}

//接收40bit
void DHT11_Receive_40bit()
{
	DHT_start();
	if(DATE==0)
{
	while(!DATE);
	while(DATE);
	TH=DHT11_Receive_Byte();
	TL=DHT11_Receive_Byte();
	HH=DHT11_Receive_Byte();
	HL=DHT11_Receive_Byte();
	CHECK=DHT11_Receive_Byte();//最后的检验是TH+TL+HH+HL=CHECK,但是我觉得没有必要
	DATE=0;
	delay55us();
	DATE=1;
}
}

	
	
	

	
	
	

效果图片:

          这里说明一下,我代码给大家展示的是通过串口接收的温湿度数据,而图片是用LCD1602直接显示温湿度。对于我本人而言,我觉得LCD的可用性不大,占用mcu引脚太多,但是对于学习通信协议的时序来说,它也是一个不错的入门项目。(这里指的是,不是直接用现成的驱动库,而是自己写库,熟悉每个通信协议的时序。)

硬件部分:

C51,DHT11,CH340这些硬件都很简单,我就不做过多的介绍。

软件部分:

          首先对于一个通信协议来说,最重要的也是它的灵魂就是时序图。大家可以对照我的代码,一行一行一步一步的对照时序图看 。

1:起始信号

起始信号是主机也就是mcu发出的。以下是DHT11的数据手册对于起始信号的说明:

意思就是说拉低18ms以上之后然后拉高等待20-40us。对应的是这一段:

2:等待DHT11响应

以下是DHT11数据手册对于响应信号的说明

意思就是DHT11会发送一个80us的低电平信号,然后又拉高80us,这时候我们需要用软件检测和耗尽这两段时间,可以用while(!date);和while(date);来耗尽和检测这些时间。

对应的是以下这段:

 3:对于数据的读取

DHT11采取的是单总线通信协议,01的判决和其他的通信方式有很大的区别。以下是01信号的时序图。

我们可以对比一下01信号的时序,可以发现,它们两个的起始低电平的持续时间是一样的,都是50us,我们可以用延时50us或者用while(!date);来耗尽这些低电平信号的时间。然后延时28-70us之间的任意一个时间,检测延时过后的高低电平,如果是高电平,按位和0x01或运算,如果是低电平,直接把数据整体左移(因为DHT11先发的是高位)。

我们需要接受5个8位二进制数,说明如下:

最后一位是校验位,我个人觉得校不校验没啥影响,当然你也可以不接受这个校验位,用延时让这个校验位走完。最后拉低延时然后在拉高就可以进行下一次的数据读取了。

需要注意的是:

1:对于通信协议来说,时序就是灵魂,对于延时时间的精确度要有一定的要求,建议大家选择自己相信的延时函数,要不然很难受。

2:每一次DHT11的数据读取都需要等待1s左右的时间等待它越过不稳定状态。

希望大家看完文章之后多思考,多终结。

                                                         Vincent   想让学习变得简单!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值