基于51单片机温湿度检测报警系统
(仿真+程序+PCB+原理图+设计报告)
功能介绍
具体功能:
1.温湿度传感器DHT11检测;
2.LCD1602实时显示温湿度值和对应判断的冷热干湿;
3.按键设置温、湿度上下限;
4.当温湿度超过设置范围,产生对应的蜂鸣器+LED声光报警;
演示视频:
基于51单片机温湿度检测报警系统
/*
基于51单片机的温湿度检测报警系统
温湿度检测、温湿度报警
#include <reg52.h>
#include <intrins.h>
#include <absacc.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
//定义四个输出端口
sbit Led1=P3^1; //温度高
sbit Led2=P3^2; //温度低
sbit Led3=P3^3; //湿度高
sbit Led4=P3^4; //湿度低
//定义三个设置按键
sbit Key_SET = P2^2;
sbit Key_ADD = P2^1;
sbit Key_SUB = P2^0;
sbit Key_OK = P2^3;
//定义DHT11数据口
sbit DATA = P1^7;
sbit buzz=P3^5;
//定义LCD1602端口
sbit E=P1^3; //1602使能引脚
sbit RS=P1^2; //1602数据/命令选择引脚
//定义全局变量
uchar U8FLAG,U8temp,U8comdata,U8RH_data_H_temp,U8RH_data_L_temp,U8T_data_H_temp,U8T_data_L_temp,U8checkdata_temp;
uchar U8RH_data_H,U8RH_data_L,U8T_data_H,U8T_data_L,U8checkdata;
uchar Mode,humidity,temperature;
char TH=35;
char TL=15;
char HH=70;
char HL=40;
bit bdata FlagStartRH,hot,cold,humid,dry,BJ;
//定时器0初始化
void Timer0_Init()
{
ET0 = 1; //允许定时器0中断
TMOD = 0x11; //定时器工作方式选择
TL0 = 0xFF;
TH0 = 0x4B; //定时器赋予初值
TR0 = 1; //启动定时器
}
//定时器0中断
void Timer0_ISR (void) interrupt 1 using 0
{
uchar RHCounter;
TL0 = 0xFF;
TH0 = 0x4B; //定时器赋予初值
RHCounter++;
if(RHCounter%10==0&&BJ==1)
buzz=!buzz;
else if(BJ==0)
buzz=1;
//每2秒钟启动一次温湿度转换
if (RHCounter >= 40)
{
FlagStartRH = 1;
RHCounter = 0;
}
}
/*********************************
BASE DRIVE
**********************************/
void Delay1(uint j)
{
uchar i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
void Delay_10us(void)
{
uchar i;
i--;
i--;
i--;
i--;
i--;
i--;
}
void COM(void)
{
uchar i;
for(i=0;i<8;i++)
{
U8FLAG=2;
while((!DATA)&&U8FLAG++);
Delay_10us();
Delay_10us();
Delay_10us();
U8temp=0;
if(DATA)U8temp=1;
U8FLAG=2;
while((DATA)&&U8FLAG++);
//超时则跳出for循环
if(U8FLAG==1)break;
//判断数据位是0还是1
// 如果高电平高过预定0高电平值则数据位为 1
U8comdata<<=1;
U8comdata|=U8temp; //0
}//rof
}
//--------------------------------
//-----温湿度读取子程序 ------------
//--------------------------------
//----以下变量均为全局变量--------
//----温度高8位== U8T_data_H------
//----温度低8位== U8T_data_L------
//----湿度高8位== U8RH_data_H-----
//----湿度低8位== U8RH_data_L-----
//----校验 8位 == U8checkdata-----
//----调用相关子程序如下----------
//---- Delay();, Delay_10us();,COM();
//--------------------------------
uchar RH(void)
{
//主机拉低18ms
DATA=0;
Delay1(180); //原来为5
DATA=1;
//总线由上拉电阻拉高 主机延时20us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
//主机设为输入 判断从机响应信号
DATA=1;
//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(!DATA) //T !
{
U8FLAG=2;
//判断从机是否发出 80us 的低电平响应信号是否结束
while((!DATA)&&U8FLAG++);
U8FLAG=2;
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while((DATA)&&U8FLAG++);
//数据接收状态
COM();
U8RH_data_H_temp=U8comdata;
COM();
U8RH_data_L_temp=U8comdata;
COM();
U8T_data_H_temp=U8comdata;
COM();
U8T_data_L_temp=U8comdata;
COM();
U8checkdata_temp=U8comdata;
DATA=1;
//数据校验
U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
if(U8temp==U8checkdata_temp)
{
U8RH_data_H=U8RH_data_H_temp;
U8RH_data_L=U8RH_data_L_temp;
U8T_data_H=U8T_data_H_temp;
U8T_data_L=U8T_data_L_temp;
U8checkdata=U8checkdata_temp;
}
return 1;
}
else //传感器不响应
{
return 0;
}
}
/********************************************************************
* 文件名 : 液晶1602显示.c
* 描述 : 该程序实现了对液晶1602的控制。
***********************************************************************/
/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间大概为140US。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void delay()
{
int i,j;
for(i=0; i<=10; i++)
for(j=0; j<=2; j++);
}
/********************************************************************
* 名称 : enable(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void enable(uchar del)
{
P0 = del;
RS = 0;
E = 1;
delay();
E = 0;
delay();
}
/********************************************************************
* 名称 : write(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/
void write(uchar del)
{
P0 = del;
RS = 1;
E = 1;
delay();
E = 0;
delay();
}
/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void L1602_init(void)
{
enable(0x38);
enable(0x0c);
enable(0x06);
enable(0x01); //清屏要放在最后
}
/********************************************************************
* 名称 : L1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
L1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
write(sign);
}
/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
while(1)
{
if(*p == '\0') break;
write(*p);
p++;
}
}
//显示整型的温湿度数据用,共占用4位,其中一位符号位
void L1602_int(uchar hang, uchar lie, int num)
{
uint temp;
uint gewei,shiwei,baiwei,sign;
if (num >= 0)
sign = 0;
else
sign = 1;
temp = abs(num);
baiwei = temp / 100;
temp = temp - baiwei*100;
shiwei = temp / 10;
gewei = temp - shiwei*10;
num = abs(num);
if (num>=100)
{
// L1602_char(hang, lie+1, baiwei+48);
L1602_char(hang, lie+2, shiwei+48);
L1602_char(hang, lie+3, gewei+48);
}
else if (num>=10)
{
if (sign == 1)
L1602_char(hang, lie+1, '-');
L1602_char(hang, lie+2, shiwei+48);
L1602_char(hang, lie+3, gewei+48);
}
else
{
if (sign == 1)
L1602_char(hang, lie+2, '-');
else
L1602_char(hang, lie+2, ' ');
L1602_char(hang, lie+3, gewei+48);
}
}
void display()
{
if(Mode==0)
{
L1602_int(1,3,temperature);
L1602_char(1,7,0xdf);
L1602_int(1,12,humidity);
if(hot==1&&cold==0&&humid==0&&dry==0)
{L1602_string(2,1," It's very hot! ");BJ=1;}
else if(hot==1&&cold==0&&humid==1&&dry==0)
{L1602_string(2,1," Hot and humid! ");BJ=1;}
else if(hot==1&&cold==0&&humid==0&&dry==1)
{L1602_string(2,1," Hot and dry! ");BJ=1;}
else if(hot==0&&cold==1&&humid==0&&dry==0)
{L1602_string(2,1," It's very cold!");BJ=1;}
else if(hot==0&&cold==1&&humid==1&&dry==0)
{L1602_string(2,1," Cold and humid!");BJ=1;}
else if(hot==0&&cold==1&&humid==0&&dry==1)
{L1602_string(2,1," Cold and dry! ");BJ=1;}
else if(hot==0&&cold==0&&humid==1&&dry==0)
{L1602_string(2,1,"It's very humid!");BJ=1;}
else if(hot==0&&cold==0&&humid==0&&dry==1)
{L1602_string(2,1," It's very dry! ");BJ=1;}
else if(hot==0&&cold==0&&humid==0&&dry==0)
{L1602_string(2,1,"Good environment");BJ=0;}
}
}
/***按键函数***/
void KEY()
{
if(Key_SET==0)
{
Delay1(200);
if(Key_SET==0)
{
Mode++;
if(Mode==1)
{
L1602_string(1,1," TH: C HH: %");
L1602_char(1,8,0xdf);
L1602_string(2,1," TL: C HL: %");
L1602_char(2,8,0xdf);
L1602_int(1,4,TH);
L1602_int(1,12,HH);
L1602_int(2,4,TL);
L1602_int(2,12,HL);
enable(0x80+6);
enable(0x0f);
}
else if(Mode==2)
{
enable(0x80+0x40+6);
enable(0x0f);
}
else if(Mode==3)
{
enable(0x80+14);
enable(0x0f);
}
else if(Mode==4)
{
enable(0x80+0x40+14);
enable(0x0f);
}
else if(Mode>=5)
{
Mode=1;
enable(0x80+6);
enable(0x0f);
}
while(!Key_SET);
}
}
else if(Key_ADD==0)
{
Delay1(200);
if(Key_ADD==0)
{
if(Mode==1)
{
TH++;
if(TH>=100)
TH=99;
L1602_int(1,4,TH);
enable(0x80+6);
}
else if(Mode==2)
{
TL++;
if(TL>=TH)
TL=TH-1;
L1602_int(2,4,TL);
enable(0x80+0x40+6);
}
else if(Mode==3)
{
HH++;
if(HH>=100)
HH=99;
L1602_int(1,12,HH);
enable(0x80+14);
}
else if(Mode==4)
{
HL++;
if(HL>=HH)
HL=HH-1;
L1602_int(2,12,HL);
enable(0x80+0x40+14);
}
while(!Key_ADD);
}
}
else if(Key_SUB==0)
{
Delay1(200);
if(Key_SUB==0)
{
if(Mode==1)
{
TH--;
if(TH<=TL)
TH=TL+1;
L1602_int(1,4,TH);
enable(0x80+6);
}
else if(Mode==2)
{
TL--;
if(TL<=0)
TL=0;
L1602_int(2,4,TL);
enable(0x80+0x40+6);
}
else if(Mode==3)
{
HH--;
if(HH<=HL)
HH=HL+1;
L1602_int(1,12,HH);
enable(0x80+14);
}
else if(Mode==4)
{
HL--;
if(HL<=0)
HL=0;
L1602_int(2,12,HL);
enable(0x80+0x40+14);
}
while(!Key_SUB);
}
}
if((Key_OK==0)&&(Mode!=0))
{
Delay1(200);
if(Key_OK==0)
{
Mode=0;
enable(0x0C);
L1602_string(1,1,"Tem: C Hum: %");
L1602_string(2,1,"Good environment");
while(!Key_OK);
}
}
}
//数据初始化
void Data_Init()
{
Led3 = 1;
Led4 = 1;
Led1 = 1;
Led2 = 1;
}
硬件设计
使用元器件:
单片机:STC89C52;
(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)
9*15万用板;40IC座;
LCD1602液晶;母座*16;
插针*16;103排阻;
30pf电容*2;10uf电容;
12m晶振;8脚IC座;
DHT11传感器;10k电阻*3;
1k电阻*4;2.2k电阻*1;
1.5k电阻;小灯*4(红、黄);
10K排阻;3p排针;
2p接线端子*4;蜂鸣器;
独立按键*4;自锁开关;
DC座;导线:若干;
流程图:
设计资料
01 仿真图
本设计使用proteus8.9版本设计,资料里有安装教程,无需担心!具体如图!
02 原理图
本系统原理图采用Altium Designer19设计,具体如图!
03 程序
本设计使用软件keil5版本编程设计,资料里有安装教程,无需担心!具体如图!
04 设计报告
七千字设计报告,具体如下!
05 设计资料
资料获取请关注同名公众号,全部资料包括仿真源文件 、程序(含注释)、PCB电路图、AD原理图、设计报告、任务书、元件清单、实物演示视频、流程图、结构框图、视频讲解等。具体内容如下,全网最全! !
资料获取请观看前面演示视频!
点赞分享一起学习成长。