一、说明
对各种信号的处理的经验很重要!
DHT11 温湿度取值
每1次数据传送为40bit, 其中8bit的湿度整数,8bit的湿度小数,8bit的温度整数,8bit温度小数和8bit的校验码
二、演示
三、时序和取值
四、代码
/**
* 8051/2 DEMO 4
*
* DHT11 温湿度取值
* 每1次数据传送为40bit, 其中8bit的湿度整数,8bit的湿度小数,8bit的温度整数,8bit温度小数和8bit的校验码
*/
#include "REG52.H"
#include "intrins.h"
typedef unsigned char U8;
sbit DHT = P0^5;
//转换后数据,只保留整数部分: wd_1 为10位, wd_2 为个位, sd_1 为十位, sd_2为个位
U8 wd_1,wd_2,sd_1,sd_2;
//串口初始化 - 为了打印数据用
void uart_init()
{
SCON = 0x50;
TMOD = 0x20; //选择 定时器1
//装在波特率 高8位和低8位,9600
TH1 = 0xFD;
TL1 = 0xFD;
ES = 1; //打开串口中断
TR1 = 1; //打开定时器1
EA = 1; //打开总中断
}
//发送一个字符
void uart_send_char(char str)
{
SBUF = str; //将待发送的字符串放入缓冲器
while(TI==0); //等待完发送
TI=0; // 发送中断标志 清0
}
//发送字符串
void uart_send_string(U8 *buffer)
{
U8 *plter = buffer;
while((*plter)!=0x00){
uart_send_char(*plter);
plter++;
}
}
//串口中断业务处理
void uart_handle() interrupt 4
{
}
void delay1s() //误差 0us
{
unsigned char a,b,c;
for(c=167;c>0;c--)
for(b=171;b>0;b--)
for(a=16;a>0;a--);
_nop_(); //if Keil,require use intrins.h
}
void delay18ms() //误差 -0.86805555556us
{
unsigned char a,b;
for(b=155;b>0;b--)
for(a=52;a>0;a--);
}
void delay40us() //误差 -0.9375us
{
unsigned char a,b;
for(b=3;b>0;b--)
for(a=4;a>0;a--);
}
U8 read_dht_byte()
{ //读取8位数据
U8 i,mdata=0;
for(i=0;i<8;i++){
while(DHT==0);
//拉低后,26~28us 为 0 ,70us为1,我们在40us时候取样DHT
delay40us();
mdata<<=1;
mdata|=DHT;
//拉高
while(DHT==1);
}
return mdata;
}
void read_wsd()
{
U8 wd_01,wd_02,sd_01,sd_02,ck_code;
DHT = 0;
//超过18ms
delay18ms();
//等待拉高
DHT = 1;
//看波形图我们需要等待 1个高,1个低,1个高 后
while(DHT == 1);
while(DHT == 0);
while(DHT == 1);
//读取第1个数据字节,为湿度的整数位
sd_01 = read_dht_byte();
//读取第2个数据字节,为湿度的小数位
sd_02 = read_dht_byte();
//读取第3个数据字节,为温度的整数位
wd_01 = read_dht_byte();
//读取第4个数据字节,为湿度的小数位
wd_02 = read_dht_byte();
//读取第5个数据字节,为校验码
ck_code = read_dht_byte();
//判断校验值,如果正确,则放到变量wd_1中
if(ck_code == (wd_01+wd_02+sd_01+sd_02)){
//数据转换,只保留整数部分 sd_01, 和wd_01
sd_1 = (sd_01/10)+48;
sd_2 = (sd_01%10)+48;
wd_1 = (wd_01/10)+48;
wd_2 = (wd_01%10)+48;
}
}
void main()
{
//初始化数据
DHT = 1;
wd_1 = 0;
wd_2 = 0;
sd_1 = 0;
sd_2 = 0;
uart_init();
delay1s(); //开机1秒后会让传感器保持稳定
while (1)
{
delay1s();
//读取温湿度
read_wsd();
// sd:78.2, wd: 22.3
uart_send_string("sd:");
uart_send_char(sd_1);
uart_send_char(sd_2);
uart_send_string(",wd:");
uart_send_char(wd_1);
uart_send_char(wd_2);
uart_send_string("\r\n");
}
}
感谢您的支持,写的文章如对您有所帮助,开源不易,请您打赏,谢谢啦~