51单片机 DHT11温湿度传感器LCD显示+串口打印+Proteus仿真

51单片机 DHT11温湿度传感器LCD显示+串口打印+Proteus仿真


  • Proteus仿真效果
    在这里插入图片描述

调试了好久,总是读不到数据,显示00,估计像我这样的人,应该不在少数,这个DHT时序图,看,大家应该都看得懂,主要在于,这个延时时间需要精准掌控好,不然很难在DHT和单片机之间建立有效的通讯连接,也就不能正确的读到数据了,失败是成功之母,只有不断的去尝试和实验,验证。看懂了时序图,到最后的延时时间还是慢慢的测出来的。后面学习的人,就不需要像我一样继续采坑了,经验都是前面的人总结出来的。

  • 仿真当中应用了虚拟串口,这个需要自己安装了虚拟串口工具,并且添加了虚拟串口才能进行这样的仿真,不然,串口仿真输出是没有的。

主程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 实验名 :温度显示实验
\* 使用的IO :
\* 实验效果 :1602显示温度
\* 注意 :
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/

#include<reg51.h>
#include"lcd.h"
#include<intrins.h>
#include<stdio.h>

sbit Temp_data=P3^6;
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 函数名 : main
\* 函数功能 : 主函数
\* 输入 : 无
\* 输出 : 无
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
unsigned int rec_dat[4];

unsigned char rec_dat_lcd0[6];
unsigned char rec_dat_lcd1[6];
unsigned char rec_dat_lcd2[6];
unsigned char rec_dat_lcd3[6];

//定义
void DHT11\_delay\_us(unsigned char n);
void DHT11\_delay\_ms(unsigned int z);
void DHT11\_start();
unsigned char DHT11\_rec\_byte();
void DHT11\_receive();
void InitUART(void);


//主函数
void main()
{
InitUART();
P1=0xf0;
InitLcd1602();
LcdShowStr(0,0,"Humi:");
LcdShowStr(0,1,"Temp:");
EA = 1; //开总中断
while(1)
{
DHT11\_delay\_ms(150);
DHT11\_receive();
sprintf(rec_dat_lcd0,"%d",rec_dat[0]);
sprintf(rec_dat_lcd1,"%d",rec_dat[1]);
sprintf(rec_dat_lcd2,"%d",rec_dat[2]);
sprintf(rec_dat_lcd3,"%d",rec_dat[3]);
DHT11\_delay\_ms(100);

//湿度
LcdShowStr(6,0,rec_dat_lcd0);
LcdShowStr(8,0,".");
LcdShowStr(9,0,rec_dat_lcd1);
LcdShowStr(10,0," %");

//温度
LcdShowStr(6,1,rec_dat_lcd2);
LcdShowStr(8,1,".");
LcdShowStr(9,1,rec_dat_lcd3);
LcdShowStr(10,1,"\*C");

//下面通过串口助手打印温度
printf("Humi:%d.%d %%\n",rec_dat[0],rec_dat[1]);
printf("Temp:%d.%d ℃\n",rec_dat[2],rec_dat[3]);
DHT11\_delay\_ms(3000);
}
}



//DHT11起始信号

void DHT11\_start()
{
Temp_data=1;

DHT11\_delay\_us(10);

Temp_data=0;

DHT11\_delay\_ms(50);//这个延时不能过短,18ms以上,实际在仿真当中要想读到数据延时要在延时参数要在40以上才能出数据

Temp_data=1;

DHT11\_delay\_us(30);//这个延时不能过短


}

//接收一个字节


unsigned char DHT11\_rec\_byte()
{
unsigned char i,dat=0;
for(i=0; i<8; i++)
{
while(!Temp_data);
DHT11\_delay\_us(8);
dat <<=1;
if(Temp_data==1)
{
dat +=1;
}
while(Temp_data);
}
return dat;
}


//接收温湿度数据
void DHT11\_receive()
{
unsigned int R_H,R_L,T_H,T_L;
unsigned char RH,RL,TH,TL,revise;

DHT11\_start();
Temp_data=1;
if(Temp_data==0)
{
while(Temp_data==0); //等待拉高
DHT11\_delay\_us(40); //拉高后延时80us

R_H=DHT11\_rec\_byte(); //接收湿度高八位
R_L=DHT11\_rec\_byte(); //接收湿度低八位
T_H=DHT11\_rec\_byte(); //接收温度高八位
T_L=DHT11\_rec\_byte(); //接收温度低八位
revise=DHT11\_rec\_byte(); //接收校正位

DHT11\_delay\_us(25); //结束

if((R_H+R_L+T_H+T_L)==revise) //校正
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;

}
/\*数据处理,方便显示\*/
rec_dat[0]=RH;
rec_dat[1]=RL;
rec_dat[2]=TH;
rec_dat[3]=TL;

}

}

//延时us --2\*n+5us
void DHT11\_delay\_us(unsigned char n)
{
while(--n);
}

//延时ms
void DHT11\_delay\_ms(unsigned int z)
{
unsigned int i,j;
for(i=z; i>0; i--)
for(j=110; j>0; j--);
}


void InitUART(void)//使用定时器1作为串口波特率发生器
{

SCON=0x40; //串口通信工作方式1
REN=1; //允许接收
TMOD=0x20; //定时器1的工作方式2
TH1=0xF3,TL1=0xF3;
TI=1; //这里一定要注意
TR1=1;

}


程序源码和仿真资源

1
2
3
链接:https://pan.baidu.com/s/1ISpJnaqlnxcIQ0kO4ZJjaw 
提取码:ay0h