温湿度检测和液位测量

51单片机温湿度检测和液位测量

实现思路:

DHT11温湿度传感器和超声波传感器测量数据, 通过at89c51单片机数据处理, 最后将数据显示在液晶显示屏1602上

逻辑图

image-20230407225313188

传感器特点

DHT11 温湿度传感器

简介

DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度±5%RH, 温度±2℃,量程湿度595%RH, 温度-20+60℃。 DHT11 数字温湿度传感器 是一款含有已校准数字信号输出的温湿度复合传感器 ,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。

Hc_Sr04 超声波传感器

简介

HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器和控制电路。其基本工作原理采用IO口TRIG触发测距,给至少10us的高电平信号;模块自动发送8个40khz的方波,自动检测是否有信号返回;有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。

设计原理图

image-20230407225950760

实物展示

image-20230407230014336

程序代码

1. 液晶显示屏1602

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
#include "reg51.h"
#include "string.h"
#include "stdio.h"
#include "dht11.h"
#include "delayms.h"
#include "CSBofCM.h"

#define uint unsigned int
#define uchar unsigned char

sbit scr_E = P0^1;
sbit scr_RW = P0^2;
sbit src_RS = P0^3;

uchar index;

int pre_temp, temp_suf, pre_humi, humi_suf;


// 定义温湿度显示数组
uchar temp[14] = "temp: ";
uchar humi[9] = "humi: ";


void write_address(uchar address)
{
src_RS = 0;
P1 = address;
delayms(5);
scr_E = 1;
delayms(5);
scr_E = 0;
}

void write_data(uchar data_)
{
src_RS = 1;
P1 = data_;
delayms(5);
scr_E = 1;
delayms(5);
scr_E = 0;
}

void lcd_init()
{
scr_E = 0;
scr_RW = 0;
write_address(0x38);
write_address(0x0c);
delayms(50);
write_address(0x06);
delayms(50);
write_address(0x01);
delayms(50);
}

void display()
{
pre_temp = high_temp / 10;
temp_suf = high_temp % 10;
temp[6] = '0' + pre_temp;
temp[7] = '0' + temp_suf;
temp[8] = 'C';
temp[9] = ' ';
temp[9] = 'j';
temp[10] = 'u';
temp[11] = '0' + f1;
temp[12] = '0' + f2;
temp[13] = '0' + f3;

// 在第一行写入温度
write_address(0x80);
for(index = 0;index < 14;index++)
{
write_data(temp[index]);
delayms(5);
}

pre_humi = high_humi / 10;
humi_suf = high_humi % 10;
humi[6] = '0' + pre_humi;
humi[7] = '0' + humi_suf;
humi[8] = 'h';

// 在第二行写入湿度
write_address(0x80+0x40);
for(index = 0;index < 9;index++)
{
write_data(humi[index]);
delayms(5);
}
}

2. 超声波传感器Hc_Sr04

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
#include<reg51.h>
#include "intrins.h"


typedef unsigned int uint;
typedef unsigned char uchar;

sbit Echo=P0^6; //接受端
sbit Trig=P0^7; //控制端
uchar flag; //中断溢出标志


void CSB_Time0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
{
flag=1;
}

void Delay20us()
{
unsigned char i;
_nop_();
i = 7;
while (--i);
}

void CSB_Rstart() //启动模块
{
Trig = 1;
Delay20us();
Trig = 0;
return;
}

void CSB_Init() // 初始化
{
TMOD = 0x01;
TH0 = 0;
TL0 = 0;
EA = 1;
ET0 = 1;
}

uchar f1, f2, f3;
uint time;
float distance;
void CSB_GetOnce() //得到一次超声波测距模块的距离
{
CSB_Rstart();
while(!Echo); //当Echo为零时等待
TR0 = 1; //开启计数
while(Echo); //当Echo为1计数并等待
TR0 = 0; //关闭计数
time = TH0*256+TL0; //得到总时间,单位us
distance = (float)(time*0.017);
TH0 = 0;
TL0 = 0; //清空定时器
if((distance >=300)||flag==1) //超出测量范围显示 " X "
{
flag=0; //清空中断溢出标志
f1 = 'X';
f2 = ' ';
f3 = ' ';
}
else
{
f1 = (uint)distance/100; //百位
f2 = (uint)distance/10%10; //十位
f3 = (uint)distance%10; //个位
}
}

3. 温度传感器 DHT11

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
#include "reg51.h"  
#include "intrins.h"

typedef unsigned char uchar;
typedef unsigned int uint;


//定义信号端口
sbit sign = P0^0;

void delay_us(char n)
{
while(--n);
}

void delay_ms(int z)
{
uchar x, y;

while(z>=0)
{
_nop_(); //产生一条NOP指令 (起延时作用)
x = 2;
y = 199;
do
{
while (--y);
} while (--x);
z--;
}
}

void start()
{
sign = 1;
delay_us(2);
sign = 0;
delay_ms(20);
sign = 1;
delay_us(30);
}

uchar rec_one_byte() //接收一个字节数据
{
uchar i,dat = 0;
for(i = 0;i < 8;i++)
{
while(!sign);

delay_us(8);
dat <<= 1; // 移位
if(sign == 1)
dat += 1;
while(sign);
}
return dat;
}

uchar high_temp, low_temp, high_humi, low_humi, correct;

void receive_all_data() //接收40位的数据
{
start();
if(sign == 0)
{
while(sign == 0);
delay_us(40);
high_humi = rec_one_byte();
low_humi = rec_one_byte();
high_temp = rec_one_byte();
low_temp = rec_one_byte();
correct = rec_one_byte();

delay_us(25);
}
}

4. 主函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "reg51.h"
#include "1602.h"
#include "dht11.h"
#include "CSBofCM.h"

void main()
{
lcd_init();
CSB_Init();
while(1)
{
receive_all_data();
CSB_GetOnce();
display();
}
}