DHT11简易温湿度检测系统
时间:2022-11-29 15:30:00
DHT11温湿度检测系统
主控:
STC89C52RC
所需模块:
DHT11温湿度传感器,蓝牙模块,LCD1602显示屏、继电器、电池、直流电机 风扇
接线:
因为LCD1602需要更多的引脚,手是开发板,卡槽直接插入,所以引脚没有画
模块编程:
由于实现功能多,现有功能多DHT11温湿度检测、串口、LCD1602显示,所以分模块编程会让代码的整体思路非常清晰,每个模块的分工都很清晰,只需要main在函数中调用相应的功能函数是一个很好的编程习惯
DHT11温湿度传感器
首先把DHT11的起始信号按顺序要求编写,然后读取温度和湿度,存储在数组中,判断获得的温度值是否超过阈值。如果超过,继电器信号脚将低电平,继电器吸合,打开风扇
在串口发送函数中,将8位数据转换为字符,然后再发送。您可以在计算机串口助手中看到当前的温度和湿度
在LCD在1602显示的函数中,温湿度数组数据转换为字符,然后存储在各自的数组中LCD1602显示字符串函数,第一行显示湿度,第二行显示温度
DHT11.c:
#include #include "Delay.h" #include "Uart.h" #include "LCD1602.h" sbit DATA = P1^0; //DTH11模块数据线 char rec[5]; //接收40bit温湿度数据 char hum[8]; //湿度 char tem[8]; //温度 sbit relay = P1^4; //继电器 /** * @brief 检测DHT11模块是否响应 * @param 无 * @retval无 */ void DHT11_Start() {
DATA = 1; DATA = 0; Delay1ms(30); DATA = 1; while(DATA); while(!DATA); Delay80us(); } /** * @brief DHT11读取温湿度 * @param 无 * @retval无 */ void DHT11_ReadByte() {
unsigned int i,j
;
unsigned
char temp
=
0x00
;
unsigned
char flag
;
DHT11_Start
(
)
;
//最后时序电平为高
while
(DATA
)
;
for
(i
=
0
; i
<
5
; i
++
)
//读5轮,共读40bit
{
for
(j
=
0
; j
<
8
; j
++
)
//读温湿度整数或小数值,每次读8bit
{
while
(
!DATA
)
;
Delay50us
(
)
;
//延时50us后再去读DATA的电平
if
(DATA
==
1
)
{
flag
=
1
;
}
else
{
flag
=
0
;
} temp
<<=
1
;
//每次循环左移一位,让出低位接收数据 temp
|= flag
;
//如果flag是1则temp的最低位置1,是0则最低位置0
} rec
[i
]
= temp
;
//每获得8bit数据后放入rec数据中
}
if
(rec
[
2
]
>=
25
)
//如果温度超过h25,则吸合继电器,风扇开启
{
relay
=
0
;
}
else
{
relay
=
1
;
//温度低于26,断开继电器,风扇关闭
}
}
/** * @brief 温湿度数据处理以及通过串口显示 * @param 无 * @retval无 */
void
Data_SerialShow
(
)
{
unsigned
char i
;
DHT11_ReadByte
(
)
;
//每次显示温湿度都要先读取数据
Delay1ms
(
1000
)
;
for
(i
=
0
; i
<
4
; i
++
)
{
if
(i
==
0
)
{
Uart_SendString
(
"湿度:"
)
;
}
if
(i
==
2
)
{
Uart_SendString
(
"温度:"
)
;
}
Uart_SendChar
(rec
[i
]
/
10
+
0x30
)
;
//加0x30是为了转为char类型,因为字符0的ASCII码是0x30
Uart_SendChar
(rec
[i
]
%
10
+
0x30
)
;
if
(i
==
0
|| i
==
2
)
{
Uart_SendChar
(
'.'
)
;
}
}
Uart_SendString
(
"\r\n"
)
;
}
/** * @brief 温湿度数据处理及通过LCD1602显示 * @param 无 * @retval无 */
void
DTH11_LCDShow
(
)
{
hum
[
0
]
=
'H'
; hum
[
1
]
=
':'
; hum
[
2
]
= rec
[
0
]
/
10
+
0x30
;
//湿度整数 hum
[
3
]
= rec
[
0
]
%
10
+
0x30
; hum
[
4
]
=
'.'
; hum
[
5
]
= rec
[
1
]
/
10
+
0x30
;
//湿度小数 hum
[
6
]
= rec
[
1
]
%
10
+
0x30
; hum
[
7
]
=
'\0'
; tem
[
0
]
=
'T'
; tem
[
1
]
=
':'
; tem
[
2
]
= rec
[
2
]
/
10
+
0x30
;
//温度整数 tem
[
3
]
= rec
[
2
]
%
10
+
0x30
; tem
[
4
]
=
'.'
; tem
[
5
]
= rec
[
3
]
/
10
+
0x30
;
//温度小数 tem
[
6
]
= rec
[
3
]
%
10
+
0x30
; tem
[
7
]
=
'\0'
;
LCD_ShowString
(
1
,
2
,hum
)
;
//通过LCD1602显示湿度
LCD_ShowString
(
2
,
2
,tem
)
;
//通过LCD1602显示温度
}
蓝牙模块:
使用串口1将温湿度数据发送到串口助手上显示,同时蓝牙模块接到开发板TX、RX上后,用HC蓝牙助手连接上蓝牙模块,就可通过手机发送“open”,“close”指令控制风扇开启或关闭
Usart.c 中断处理函数(接收蓝牙信息):
/** * @brief 串口中断处理函数,接收蓝牙信号 * @param 无 * @retval无 */
void Uart_Rountine() interrupt 4
{
static unsigned int i = 0;
char temp;
if(RI)
{
RI = 0;
temp = SBUF;
if(temp == 'o' || temp == 'c')
{
i = 0;
}
Bule_Rec[i++] = temp;
if(Bule_Rec[0] == 'o' && Bule_Rec[1] == 'p') //如果RX接收到信息有“op”字符,则吸合继电器开启风扇
{
relay = 0;
Delay1ms(2000);
memset(Bule_Rec,'\0',SIZE);
}
if(Bule_Rec[0] == 'c' && Bule_Rec[1] == 'l' ) //如果RX接收到信息有“cl”字符,则断开继电器关闭风扇
{
relay = 1;
Delay1ms(2000);
memset(Bule_Rec,'\0',SIZE);
}
if(i == SIZE){
i = 0;}
}
}
如果使用蓝牙控制继电器,发送“open”吸合继电器时,因为此时温度检测没超过阈值,就会立马断开继电器,所以串口中吸合继电器加了两秒的延时,吸合继电器两秒后断开,可以看到手机蓝牙控制的现象;“close”指令同理,温度超过阈值吸合继电器时,串口收到指令断开继电器两秒后,温度超过阈值会再次吸合