51单片机读取DHT11温湿度传感器,在读取第五个字节(校验位)的时候从机io口一直输出高电平,导致程序无法运行
下面是DUT11数据读取的功能模块,本人英语不咋滴,还请各位不要笑话
unsigned char DHT11_Data[5];
unsigned int shidu;
unsigned int wendu;
void Timer0Init(void) //100微秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0; //设置定时初值
TH0 = 0; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 0; //定时器0开始计时
EA=0;
}
unsigned int DHT11_shidu(void)
{
return shidu;
}
unsigned int DHT11_wendu(void)
{
return wendu;
}
void Time_c(unsigned int sam) //定时器值重装
{
TH0 = sam/256; //设置定时器值
TL0 = sam%256; //设置定时器值
}
unsigned int Time_zhi(void) //读取定时器值
{
unsigned int Time;
Time=TH0<<8|TL0;
return Time;
}
void Delay25ms() //25ms延时
{
unsigned char i, j;
i = 49;
j = 160;
do
{
while (--j);
} while (--i);
}
void Delay30us() //30us延时
{
unsigned char i;
_nop_();
i = 12;
while (--i);
}
void Delay55us() //@12.000MHz
{
unsigned char i;
i = 25;
while (--i);
}
/*触发函数*/
void DHT11_chufa(void)
{
DHT11_OUT=1;
DHT11_OUT=0;
Delay25ms(); //拉低25ms
DHT11_OUT=1;
Delay30us(); //拉高30us
}
/*读取响应*/
unsigned char DHT11_xiangying(void)
{
unsigned int time;
unsigned char jici;
while(DHT11_OUT&&jici<100)
{
jici++;
}
if(jici>99)
{
jici=0;
return 1;
}
else
{
jici=0;
TR0=1;
while(DHT11_OUT==0);
while(DHT11_OUT==1);
TR0=0;
time=Time_zhi();
Time_c(0);
if(time>130&&time<170)
{
return 0;
}
else
{
return 1;
}
}
}
/*读取一个字节*/
unsigned char DHT11_du(void)
{
unsigned char i=0,jishu;
unsigned char Value=0X00;
unsigned int Time=0;
for(i=0;i<8;i++)
{
while(!DHT11_OUT);
TR0=1;
while(DHT11_OUT);
TR0=0;
Time=Time_zhi();
if(Time>30)
{
Value|=(0X01<Time_c(0);
}
return Value;
}
/*读取一次数据*/
void DHT11_duqu(void)
{
unsigned char xiangying;
unsigned char j=0;
DHT11_chufa();
xiangying=DHT11_xiangying();
if(xiangying==0)
{
for(j=0;j<5;j++)
{
DHT11_Data[j]=DHT11_du();
}
if(DHT11_Data[0]+DHT11_Data[1]+DHT11_Data[2]+DHT11_Data[3]==DHT11_Data[4])
{
shidu=((DHT11_Data[0]<<8)|DHT11_Data[1]);
wendu=((DHT11_Data[2]<<8)|DHT11_Data[3]);
}
else
{
P1_7=0;
shidu=((DHT11_Data[0]<<8)|DHT11_Data[1]);
wendu=((DHT11_Data[2]<<8)|DHT11_Data[3]);
}
}
}
在读取第五个字节的时候会一直卡在while(DHT11_OUT);
我尝试使用while(DHT11_OUT&&jici<100);这种写法来跳过这个,但是最终在校验时数据是错误的;检验的那个else是因为我在发现错误后为了看读出的数据是多少才那样写的
下面是 51 单片机读取 DHT11 温湿度传感器的代码示例:
#include <reg51.h>
#include <intrins.h>
sbit DHT11_Data = P1^0;
unsigned char DHT11_Rx_Byte()
{
unsigned char i, dat;
dat = 0;
for (i=0; i<8; i++)
{
while(!DHT11_Data);
nop();
nop();
dat <<= 1;
if(DHT11_Data)
{
dat |= 1;
}
while(DHT11_Data);
}
return dat;
}
void main()
{
unsigned char humi_int, humi_deci, temp_int, temp_deci, check;
while(1)
{
DHT11_Data = 1;
nop();
nop();
DHT11_Data = 0;
nop();
nop();
DHT11_Data = 1;
while(!DHT11_Data);
while(DHT11_Data);
humi_int = DHT11_Rx_Byte();
humi_deci = DHT11_Rx_Byte();
temp_int = DHT11_Rx_Byte();
temp_deci = DHT11_Rx_Byte();
check = DHT11_Rx_Byte();
if((humi_int + humi_deci + temp_int + temp_deci) == check)
{
// 数据校验正确,可以使用 humi_int、humi_deci、temp_int 和 temp_deci 变量中的数据
}
else
{
// 数据校验错误,不能使用 humi_int、humi_deci、temp_int 和 temp_deci 变量中的数据
}
}
}
该代码实现了 51 单片机读取 DHT11 温湿度传感器的功能。它首先向 DHT11 发送信号,然后通过调用 DHT11_Rx_Byte 函数接收 DHT11 发送回来的数据。最后,它还进行了数据校验,确保数据的准确性