【开源】基于51单片机的温湿度检测报警系统

项目说明

该设计是一个简易的基于51单片机的温湿度检测报警系统,功能说明:

  1. 使用LCD1602实时显示当前的温湿度。
  2. 读取DHT11的温湿度值,如果温度大于最大设定值,LED1亮,如果温度小于最小设定值,LED2亮。如果湿度大于最大设定值,LED3亮,如果湿度小于最小设定值,LED4亮。
  3. 可以设置温度和湿度的上下限。

设计环境

仿真软件版本:Proteus8.9

下载链接:

链接:https://pan.baidu.com/s/1kkgFmRBlh268m_ESl83weg 提取码:9bde 复制这段内容后打开百度网盘手机App,操作更方便哦

工程下载

代码和仿真放在了CSDN的下载里,并未设置积分,应该可以直接下载。只想加点下载量,好像有下载量才能升级。
下载链接

如果下载开始收积分了,可以关注微信公众号少年潜行 ,回复关键字A002温湿度检测 ,获取网盘链接。不会有付钱解压

📖 欢迎交流 如果代码对你有帮助,希望可以帮我点个赞👍和收藏

硬件设计

硬件设计如图,主要使用的是LED来展示当前值是否超过限制。使用DHT11做温湿度传感器,使用串口端口做一些简单的调试,LCD屏幕可以显示当前的温湿度,也可以显示最大最小的设置限制,通过按键改变目标值。

软件设计

按键的扫描和温湿度的最大最小值比较都在5ms中断中实现,界面显示和DHT11的读取放置在while循环中,使用的晶振是11.0592MHz,注意就是DHT11对时间比较敏感,我的时间us级别的延时都是使用的STCISP生成的,而且在读取值的时候需要把中断全部关闭 ,读取完成后再开启,中断打断也会有影响,如果你没有使用中断就不用管。

页面page变量等于1的时候,写了一个闪烁,其实原理就是使用一个计数器,计数到偶数的时候,使用空白字符将原来的数字覆盖,这样看着就好像是没显示了。

c 复制代码
#include "main.h"
#include "delay.h"
#include "LCD1602.h"
#include "key.h"
#include "dht11.h"
#include "usart.h"
// 变量定义
sbit LED1 = P2^0;      
sbit LED2 = P2^1;    
sbit LED3 = P2^2;    
sbit LED4 = P2^3;    
 
uint8_t  key_value = 0;   // 按键按下的值
uint8_t  hum_high  = 60, hum_low  = 30;//设置的湿度最大值和最小值
uint8_t  temp_high = 40, temp_low = 20;//设置的温度最大值和最小值
uint8_t humidity=0,      temperature=0;//实际的湿度值和温度值
uint8_t ui_page = 0;//实际的湿度值和温度值
uint8_t set_pos = 0;//设置序号 0:设置hum_high 1:设置hum_low 2:设置temp_high 3:设置temp_low
// 函数声明
void Timer0_Init(void);		//5毫秒@11.0592MHz

void main()
{
	uint8_t  ret;
	uint8_t  blink_count = 0;
	LcdInit();
	Timer0_Init();
	UartInit();
	
	EA = 1;                 //打开所有中断
	
	SendBuffLen("hello world\r\n",sizeof("hello world\r\n"));
	
	while(1)
	{	
		EA = 0;
		ret = DHT11_Get_Data(&humidity, &temperature) ;
		EA = 1;
		if(ui_page == 0)
		{
			LcdShowStr(0,0,"  real  data  ");
			LcdShowStr(0,1,"hum:");
			LcdShowNumInt(4,1,humidity,2,1);
			LcdShowStr(6,1,"   ");
			LcdShowStr(9,1,"temp:");
			LcdShowNumInt(14,1,temperature,2,1);
		}else if(ui_page == 1)
		{
			blink_count ++;
			LcdShowStr(0,0,"HumH:");
			LcdShowNumInt(5,0,hum_high,2,1);
			if(set_pos == 0 && (blink_count % 2 == 0) ){
				LcdShowStr(5,0,"  ");
			}
			LcdShowStr(7,0,"  ");
			LcdShowStr(9,0,"HumL:");
			LcdShowNumInt(14,0,hum_low,2,1);
			if(set_pos == 1 && (blink_count % 2 == 0) ){
				LcdShowStr(14,0,"  ");
			}
			LcdShowStr(0,1,"TmpH:");
			LcdShowNumInt(5,1,temp_high,2,1);
			if(set_pos == 2 && (blink_count % 2 == 0) ){
				LcdShowStr(5,1,"  ");
			}
			LcdShowStr(7,1,"  ");
			LcdShowStr(9,1,"TmpL:");
			LcdShowNumInt(14,1,temp_low,2,1);
			if(set_pos == 3 && (blink_count % 2 == 0) ){
				LcdShowStr(14,1,"  ");
			}
		}
		delay_ms(200);
	}
}

// 检查当前温湿度的状态
// 如果温度大于设定值,LED1亮,如果温度小于设定值,LED2亮。
// 如果湿度大于设定值,LED3亮,如果湿度小于设定值,LED4亮。
void CheckLimits()
{
	if(temperature > temp_high)
	{
		LED1 = 0;LED2 = 1;
	}else if(temperature < temp_low)
	{
		LED1 = 1;LED2 = 0;
	}else  
	{
		LED1 = 1;LED2 = 1;
	}
	
	if(humidity > hum_high)
	{
		LED3 = 0;LED4 = 1;
	}else if(humidity < hum_low)
	{
		LED3 = 1;LED4 = 0;
	}else  
	{
		LED3 = 1;LED4 = 1;
	}
}

// 5ms定时器中断,5MS执行一次
void Timer0Routine(void) interrupt 1
{
//	static int count = 0;
	// 5ms 定时值重置
	TL0 = 0x00;				//设置定时初始值
	TH0 = 0xEE;				//设置定时初始值
	
	// 按键扫描并获得值
	key_value = KeyScan();
	// 按键0按下 
	if(key_value == KEY0_PRES)
	{
		if(ui_page == 1)
		{
			if(set_pos == 0) hum_high++;
			else if(set_pos == 1) hum_low++;
			else if(set_pos == 2) temp_high++;
			else if(set_pos == 3) temp_low++;
		}
	}
	// 按键1按下 
	else if(key_value == KEY1_PRES)
	{
		if(ui_page == 1)
		{
			if(set_pos == 0) hum_high--;
			else if(set_pos == 1) hum_low--;
			else if(set_pos == 2) temp_high--;
			else if(set_pos == 3) temp_low--;
		}
	}// 按键2按下 
	else if(key_value == KEY2_PRES)
	{
		if(ui_page == 0)
			ui_page = 1;
		else if(ui_page == 1)
			ui_page = 0;
	}// 按键3按下 
	else if(key_value == KEY3_PRES)
	{
		if(ui_page == 1)
		{
			set_pos ++;
			if(set_pos > 3)
				set_pos = 0;
		}
	}
	
	CheckLimits();
}


void Timer0_Init(void)		//5毫秒@11.0592MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x00;				//设置定时初始值
	TH0 = 0xEE;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;                //打开定时器中断
}

调试效果

1、显示当前的温度和湿度值

2、点击KEY2后,显示设定值,在显示过程中,对应可修改位的数字会闪烁,但是是因为是仿真,就闪的比较慢。点击KEY3,会修改当前的想要修改的数字位,比如原来在改湿度最大值HumH,按下KEY3后,增加减少按键就会改HumL,再按又换一个。改完后点击设置又返回主界面。

相关推荐
小智学长 | 嵌入式3 小时前
单片机-STM32部分:17、数码管
stm32·单片机·嵌入式硬件
百里东风4 小时前
STM32外设DA实战-DAC + DMA 输出正弦波
stm32·单片机·嵌入式硬件
赵谨言7 小时前
基于单片机的防盗报警器设计与实现
经验分享·单片机·毕业设计
aloneboyooo7 小时前
STM32H7时钟树
stm32·单片机·嵌入式硬件
技术流浪者7 小时前
PCB设计(十九)PCB设计中NPN/PNP选型策略
单片机·嵌入式硬件·硬件工程·pcb工艺
长流小哥8 小时前
STM32实战指南:SG90舵机控制原理与代码详解
stm32·单片机·嵌入式硬件·keil5
xduryan11 小时前
16.1 - VDMA视频转发实验之TPG
嵌入式硬件
gantengsheng11 小时前
基于51单片机和8X8点阵屏、矩阵按键的记忆类小游戏
51单片机·小游戏·矩阵按键·普中开发板·stc89c52rc·记忆类·8x8点阵屏
小辉懂编程12 小时前
C语言:51单片机实现数码管依次循环显示【1~F】课堂练习
c语言·开发语言·51单片机
逼子格15 小时前
硬件工程师笔记——二极管Multisim电路仿真实验汇总
笔记·嵌入式硬件·硬件工程师·multisim·硬件工程师学习·电子器件·电路图