简单通俗易懂的DHT11传感器51单片机控制

2025-03-12 03:54:26
推荐回答(1个)
回答1:

#include
#include

typedef unsigned char unint8;
typedef unsigned char unint16;

unsigned char str1[]={" "};
unsigned char str2[]={" "};
unsigned char code dis1[] = {"TRH RH: "};
unsigned char code dis2[] = {"TRH T: "};
char code led[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
sbit TRH = P2^7;//温湿度传感器DHT11数据接入
sbit ST = P2^6;//状态显示,是为了方便调试,具体使用的时候可以不要
sbit led1= P2^0;
sbit led2= P2^1;
sbit led3= P2^2;
sbit led4= P2^3;
sbit sw = P2^4;

unint8 TH_data,TL_data,RH_data,RL_data,CK_data;
unint8 TH_temp,TL_temp,RH_temp,RL_temp,CK_temp;
unint8 com_data,untemp,temp;
unint8 respond;

/*********************************************************************************/
void delayNOP()
{
int i;

for(i=0;i<7;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}

}
/*********************************************************************************/

/*********************************************************************************/
// 毫秒级延时子程序
/*********************************************************************************/
void delay_ms(unsigned char ms)
{
unsigned char i,j;
while(ms--)
{
for(i = 0; i< 115; i++);

}
}
/*********************************************************************************/

/*********************************************************************************/
//5us级延时程序
/*********************************************************************************/
void delay_us()
{ char i,j;
for(j=0;j<7;j++)
{

i--;
i--;
i--;
i--;
i--;
i--;}
}
/********************************************************************************/

/*****************************************************************************/

/****************************************************************************/

/****************************************************************************/
//收发信号检测,数据读取
/****************************************************************************/
char receive()
{
unint8 i;
ST=0;
com_data=0;
for(i=0;i<=7;i++)
{
respond=2;
while((!TRH)&&respond++);
delay_us();
delay_us();
delay_us();
if(TRH)
{
temp=1;
respond=2;
while((TRH)&&respond++);
}
else
temp=0;
com_data<<=1;
com_data|=temp;
}
return(com_data);
}
/****************************************************************************/

/****************************************************************************/
//湿度读取子程序
//温度高8位== TL_data
//温度低8位== TH_data
//湿度高8位== RH_data
//湿度低8位== RH_data
//校验 8位 == CK_data
//调用的程序有 delay();, Delay_5us();,RECEIVE();
/***************************************************************************/

void read_TRH()
{
//主机拉低18ms
TRH=0;
delay_ms(18);
TRH=1;
//DATA总线由上拉电阻拉高 主机延时20us
delay_us();
delay_us();
delay_us();
delay_us();
//delay_us();
//delay_us();delay_us();delay_us();delay_us();
//主机设为输入 判断从机响应信号
TRH=1;
//判断DHT11是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(!TRH)
{
respond=2;
//判断DHT11发出 80us 的低电平响应信号是否结束
while((!TRH)&& respond++);
respond=2;
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while(TRH && respond++);
//数据接收状态
RH_temp = receive();
RL_temp = receive();
TH_temp = receive();
TL_temp = receive();
CK_temp = receive();
TRH=1;ST=1;
//数据校验
untemp=(RH_temp+RL_temp+TH_temp+TL_temp);
if(untemp==CK_temp)
{
RH_data = RH_temp;
RL_data = RL_temp;
TH_data = TH_temp;
TL_data = TL_temp;
CK_data = CK_temp;
}
}
//湿度整数部分
str1[0] = (char)(0X30+RH_data/10);
str1[1] = (char)(0X30+RH_data%10);
str1[2] = 0x2e; //小数点
//湿度小数部分
str1[3] = (char)(0X30+RL_data/10);
str1[5] = 0X25; //"%"
str1[6] = 0X52; //"R"
str1[7] = 0X48; //"H"
//温度整数部分
str2[0] = (char)(0X30+TH_data/10);
str2[1] = (char)(0X30+TH_data%10);
str2[2] = 0x2e; //小数点
//温度小数部分
str2[3] = (char)(0X30+TL_data/10);
str2[5] = 0X27; //"'"
str2[6] = 0X43; //"C"
}
void disp(num)

{
int i=1000;
unsigned char a,b,c;
while(i>0)
{
i--;
a=b=c=0;
a = num/100;
b = (num%100)/10;
c = (num%100)%10;
led1 = 1;
led2 = 0;
led3 = 0;
P1 = led[a];
delay_ms(10);
led1 = 0;
led2 = 1;
led3 = 0;
P1 = led[b];
delay_ms(10);
led1 = 0;
led2 = 0;
led3 = 1;
P1 = led[c];
delay_ms(10);
}
}
/****************************************************************************/
//主函数
//TH,TL,RH,RL分别代表温湿度的整数和小数部分
/****************************************************************************/
void main()
{
unsigned char i,m;
while(1)
{
read_TRH();

if (RH_data>30)
{
sw = 1;
}
else
{
sw = 0;
}
disp(RH_data);

}
}