基于51单片机温湿度控制器

基于51单片机温湿度控制器

(仿真+程序+原理图)

功能介绍

具体功能:

1.使用4个按键设定温湿度阈值上下限;

2.温湿度传感器DHT11测量温湿度;

3.LCD1602实时显示温湿度值;

4.当温度或湿度超限后,对应的继电器吸合、报警信号灯点亮(继电器模拟打开制冷器、加热器、加湿器、抽湿机);

5.当超过阀值的时候,可以手动打开蜂鸣器报警;

6.AT24c02芯片掉电存储设置的上下限;

​演示视频:

基于51单片机温湿度控制器

#include <reg52.h>
#include <intrins.h>
#include <absacc.h>
#include <math.h>
  
#define uchar unsigned char
#define uint unsigned int

//定义四个输出端口
sbit Led_jiashi=P3^4;		//加湿
sbit Led_qushi=P3^3;		//去湿
sbit Led_jiangwen=P3^1;		//降温
sbit Led_shengwen=P3^2;		//升温
//定义三个设置按键
sbit Key_SET = P2^0;
sbit Key_ADD = P2^1;
sbit Key_SUB = P2^2;
sbit Key_OK  = P2^3;
//定义24C02数据口
sbit SCL = P1^0;
sbit SDA = P1^1;
//定义DHT11数据口
sbit DATA = P1^7;
sbit buzz=P3^5;

//定义LCD1602端口
sbit E=P1^3;		//1602使能引脚
//sbit RW=P2^6;		//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,TL,HH,HL;
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 DELAY(unsigned int t)
{
	while(t!=0)
	t--;
}

/******************************
      IIC  DRIVE
******************************/
void IICStart(void)
{
     SCL=0;  
 	 DELAY(1);
     SDA=1; SCL=1; DELAY(1);
     SDA=0; DELAY(1);
     SCL=0; 
}

void IICStop(void)
{
	 SDA=0;SCL=1; DELAY(1);
     SDA=1; DELAY(1);
     SCL=0; 	
}
void SEND0(void)
{
	SDA=0;
	SCL=1;
	DELAY(1);
	SCL=0;
}

void SEND1(void)
{
	SDA=1;
	DELAY(1);
	SCL=1;
	DELAY(1);
	SCL=0;
}

bit Check_Ack(void)
{
	unsigned char errtime=250;
	DELAY(1);
	SCL=1; 
	DELAY(1);
	CY=SDA;
	while(CY)
	{
		errtime--; 
		CY=SDA;
		if (!errtime)
		{
			IICStop();
			return 1;
		}
	}
	DELAY(1);
	SCL=0; 
	return 0;
}

void Write_byte(unsigned char dat) 
{
    unsigned char i;
	for(i=0;i<8;i++)
	{	
		if((dat<<i)&0x80)
		SEND1();
		else
		SEND0();
	}
}

unsigned char Read_byte(void)
{
	unsigned char i,temp=0;     
	for(i=0;i<8;i++)
	{
        SDA=1;
	    SCL=1;
	    DELAY(1);  
		if(SDA==1)
		{
			temp=temp<<1;
			temp=temp|0x01;
		}
		else
		temp=temp<<1;
		 SCL=0;	
	  }
	  return temp;
}

/************************************
      EEPROM  DRIVE
	  Addr:from 0x00-->
*************************************/
unsigned char rdeeprom(unsigned char addr)
{ 
        unsigned char temp=0;
		bit flag=0;
		IICStart();
		Write_byte(0xa0);
        Check_Ack();
		Write_byte(addr);
		Check_Ack();
		IICStart();
		Write_byte(0xa1);
		Check_Ack();
		temp=Read_byte();
		SEND1();
		IICStop();
 	    return temp;   
}  
    
   
void wrteeprom(unsigned char addr,unsigned char dat)
{
       	IICStart();
		Write_byte(0xa0);
		Check_Ack();
		Write_byte(addr);
		Check_Ack();
		Write_byte(dat);
		Check_Ack();
		IICStop();
}


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)
		{
			L1602_string(1,1,"Tem:   C Hum:  %"); 
			L1602_string(2,1,"Smalldi@2017");
			Mode=0;
			wrteeprom(0,TH);
			Delay1(20);
			wrteeprom(1,TL);
			Delay1(20);
			wrteeprom(2,HH);
			Delay1(20);
			wrteeprom(3,HL);
			enable(0x0c);
			while(Key_OK==0);
		}
	}
}

//数据初始化
void Data_Init()
{
   Led_qushi = 1;
   Led_jiashi=1;
   Led_jiangwen = 1;
   Led_shengwen = 1;
}

硬件设计

使用元器件:

单片机:STC89C52;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

9*15万用板;40IC座;

1602液晶;母座*16;

插针*16;103排阻;

30pf电容*2;10uf电容;

12m晶振;24c02;

8脚IC座;DHT11;

圆孔母座*4;10k电阻*5;

1k电阻*4;2.2k电阻*5;

1.5k电阻;9012*5;

继电器*4(黄);蜂鸣器;

风扇;3p排针;按键*3;

4148二极管*4;2p接线端子*4;

小灯*4(红、黄);拨动开关;

自锁开关;DC座;

焊锡若干;导线若干;

usb电源线(电池盒+DC插头);

设计资料

01 仿真图

本设计使用proteus7.8和proteus8.9两个版本设计,向下兼容,无需担心!具体如图!

设置温湿度上下限

湿度过高

湿度过低

温度过高

温度过低

02 原理图

本系统原理图采用Altium Designer19设计,具体如图!

03 程序

本设计使用软件keil4和keil5两个版本编程设计,无需担心!具体如图!

04 设计资料

        资料获取请关注同名公众号,全部资料包括仿真源文件 、程序(含注释)、AD原理图、功能操作说明、仿真视频等。具体内容如下,全网最全! !

资料获取请观看前面演示视频!

点赞分享一起学习成长。

在编写这样的代码时,通常会涉及到用户界面设计以及一些基本的数据处理逻辑。假设我们正在创建一个控制温湿度的小型应用程序,可以采用类似以下的Python示例(基于Tkinter库,用于GUI编程): ```python import tkinter as tk from tkinter import messagebox # 定义初始阈值 temperature_threshold = 25 humidity_threshold = 50 def update_threshold(channel): if channel == 'temperature': new_value = int(entry_temperature.get()) if new_value > 0: temperature_threshold = new_value messagebox.showinfo("更新", f"温度阈值已设置为 {new_value}") elif channel == 'humidity': new_value = int(entry_humidity.get()) if new_value > 0: humidity_threshold = new_value messagebox.showinfo("更新", f"湿度阈值已设置为 {new_value}") root = tk.Tk() tk.Label(root, text="温度阈值").grid(row=0) entry_temperature = tk.Entry(root) entry_temperature.grid(row=0, column=1) button_temperature_increase = tk.Button(root, text="+1", command=lambda: update_threshold('temperature')) button_temperature_increase.grid(row=0, column=2) tk.Label(root, text="湿度阈值").grid(row=1) entry_humidity = tk.Entry(root) entry_humidity.grid(row=1, column=1) button_humidity_increase = tk.Button(root, text="+1", command=lambda: update_threshold('humidity')) button_humidity_increase.grid(row=1, column=2) root.mainloop() ``` 在这个例子中,我们有两个输入框(entry_temperature 和 entry_humidity)让用户输入新的温湿度阈值,以及两个按钮(分别增加温度和湿度阈值)。当用户点击相应按钮时,`update_threshold` 函数会被触发,并根据指定的通道('temperature' 或 'humidity')更新阈值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值