初探
总过程时序图
检测传感器是否存在
根据时序图中的部分分析如下
即 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代指数据接口)
- 由手册可以知道,单片机只需要发送初始的开始信号,后续单片机就无需发送信号
a->b
:此时需要单片机延时18msb->c
:此时我们将接口直接拉高,然后通过while(dht)
等待电平自动降低c->d
:通过while(!dht)
将其卡到d点d->e
:通过while(dht)
卡到e点e->f
:看下列数字0时序图分析
我们只需要通过while(!dht)
,就一定能卡到f点
,然后开始接收bit
数据
- 观察数字0和数字1时序图的不同点
- 很明显,我们可以知道
数字1信号
的时间比数字0信号
的时间长,那么以此为思路,我们延迟30μ秒
,再去判断dht
的电平,如果依然为1
,那么代表为数字信号1
,反之为0
。 - 注意:
- 如果是
数字信号1
,此时依然要while(dht)
,直到其自动变为低电平
- 根据手册:每次采集完毕后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");
}
}