📄 dht11.c
字号:
//STC89C52单片机的时钟频率是11.0592M
#include "DHT11.h"
#include <reg52.h>
/*读一个字节的数据*/
static uchar ReadValue(void)
{
uchar count, value = 0, i;
status = OK; //设置标志位为正常状态
for(i = 8; i > 0; i--)
{
value <<= 1; //高位在先,将得到的数据依次左移,最后得到1字节的数据
count = 0;
//每一位数据前都有50us的低电平等待时间.等待50us时间结束
while(dht11 == 0 && count++ < NUMBER);
if(count >= NUMBER)
{
status = ERROR;//设定错误标志
return 0;//函数执行过程发生错误就退出函数
}
//26-28us的高电平表示该位为0, 70us的高电平表示该位为1
Delay_10us();
Delay_10us();
Delay_10us();
//延时30us后检测数据线是否为高电平
if(dht11 != 0)
{
//进入这里表明该位为1
value++;
//等待剩下的40us高电平结束
while(dht11 != 0 && count++ < NUMBER)
{
dht11 = 1;
}
if(count >= NUMBER)
{
status = ERROR;//设定错误标志
return 0;
}
}
}
return (value);
}
//读一次数据,共5个字节
uchar ReadTempAndHumi(void)
{
uchar i = 0, check_value = 0,count = 0;
EA = 0;
dht11 = 0; //先拉低数据线至少18ms,发送开始信号
Delay_1ms(20); //延时大于18ms
dht11 = 1; //释放数据线,用于检测低电平响应信号
//等待20-40us,检测响应信号,响应信号为从机拉低数据线80us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
if(dht11 != 0) //检测响应信号是否存在,响应信号为低电平
{
//响应信号不存在
EA = 1;
return ERROR;
}
else
{
//有响应信号
while(dht11 == 0 && count++ < NUMBER); //等待响应信号结束
if(count >= NUMBER) //检测计数器是否超出了设定范围
{
dht11 = 1;
EA = 1;
return ERROR;//读数据出错,退出函数
}
count = 0;
dht11 = 1;//释放数据线
//应答信号后有80us的等待时间,等待高电平结束
while(dht11 != 0 && count++ < NUMBER);
if(count >= NUMBER)
{
dht11 = 1;
EA = 1;
return ERROR;//计数器超出检测范围,退出函数
}
//读出温湿度值
for(i = 0; i < SIZE; i++)
{
value_array[i] = ReadValue(); //调用ReadValue()读数据
if(status == ERROR)//若读数据出错,则退出函数
{
dht11 = 1;
EA = 1;
return ERROR;
}
//若读到的数据是校验值,则不需要加上去
if(i != SIZE -1)
{
//若读到的数据中前4字节数据的和等于第5字节字节,则表示成功
check_value += value_array[i];
}
}//end for
//检验读到的数据是否正确
if(check_value == value_array[SIZE - 1])
{
//将温湿度值扩大十倍,以方便读出其中的每一位
humi_value = (value_array[0]+value_array[1]) * 10; //前2bit数据为湿度值
temp_value = (value_array[2]+value_array[3]) * 10; //后2bit为温度值
dht11 = 1;
EA = 1;
return OK;//正确地读出dht11输出的数据
}
else
{
//校验数据出错
EA = 1;
return ERROR;
}
}
}
//LCD显示函数
void SMG_Display(uint value)
{
uchar ge, bai, shi;
ge = value%10+0x30; //必须加上0x30,否则显示乱码
shi = value%100/10+0x30;
bai = value/100+0x30;
lcd_write_data(bai);
lcd_write_data(shi);
lcd_write_data('.');
lcd_write_data(ge);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -