基于单片机的蔬菜大棚温湿度控制系统

1 设计任务

利用AT89C51单片机为核心控制元件,设计一个节日彩灯门,设计的系统实用性强、操作简单,实现了智能化、数字化。

本系统通过SHT11传感器测量出大棚内的温湿度,并将温湿度电信号传至单片机AT89C51,单片机系统通过预先设定温湿度值产生差值从而产生相应的控制信号,控制T75S5D11-5V继电器为主的温湿度控制模块,再分别控制相应的升温、加湿系统对蔬菜大棚进行升温和加湿。

2. 设计要求

2.1 系统方案论证

根据设计任务,分析设计系统的组成,给出实现设计任务的几种方案,分析比较几种设计方案的优略,本着尽量以软件代替硬件,同时力求电路简单,工作可靠的原则,确定总体设计方案。

2.2 系统硬件电路设计

根据系统设计方案进行软、硬件的分配,软、硬件设计分别进行。硬件设计包括单片机最小系统和扩展接口及配置,硬件结构在设计时要选择合适的元器件,硬件电路要简洁、工作可靠,需用Proteus绘制整个系统的电路仿真原理图。

2.3 软件设计

根据该系统要求的功能进行软件设计,简述软件的功能,并根据每个模块的功能绘制软件流程图,根据流程图编写程序并汇编调试通过;列出软件清单,软件清单要求加以注释。

cs 复制代码
#include <reg51.h>	
#include "lcd.h"
#include <intrins.h> 
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define NACK	0
#define ACK		1
#define MEASURE_TEMP	0x03	//000 0001  1
#define MEASURE_HUMI	0x05	//000 0010  1
#define STATUS_REG_W	0x06	//000 0011  0
#define STATUS_REG_R	0x07	//000 0011  1
#define RESET			0x1E	//000 1111  0
ulong volt;//测量的电压值
sbit Data=P2^3;   //定义数据线
sbit led1=P1^0;
sbit Data_P    = P2^4;			// SHT11传感器的数据管脚
sbit Sck_P     = P2^3;			// SHT11传感器的时钟管脚
sbit led =P2^5;
sbit jr=P1^2;
sbit js=P1^1;
sbit key1=P3^0;
sbit key2=P3^1;
sbit key3=P3^2;

uchar tmpe,h;
uchar mode;
uchar temp_max = 40;
uchar temp_min = 10;
uchar humi_max = 40;
uchar humi_min = 10;

unsigned char temp;							// 保存温度
unsigned char humi;				  		// 保存湿度

enum { TEMP,HUMI };
typedef union              		//定义共用同类型
{
	unsigned int i;
	float f;
}value;



int display = 0;
void delay(uchar ms) 
{  // 延时子程序 
uchar i; 
while(ms--) 
{ 
  for(i = 0;i<250;i++);  
} 
}

char ShtWriteByte(unsigned char value)
{
	unsigned char i,error=0;
	for(i=128;i>0;i>>=1)  // 高位为1,循环右移
	{
		if (i&value)
			Data_P=1;       	// 和要发送的数相与,结果为发送的位
		else
			Data_P=0;
		Sck_P=1;
		_nop_();						// 延时3us
		_nop_();
		_nop_();
		Sck_P=0;
	}
	Data_P=1;    					// 释放数据线
	Sck_P=1;
	error=Data_P;  				// 检查应答信号,确认通讯正常
	_nop_();
	_nop_();
	_nop_();
	Sck_P=0;
	Data_P=1;
	return error; 				// error=1 通讯错误
}

char ShtReadByte(unsigned char ack)
{
	unsigned char i,val=0;
	Data_P=1; 						// 释放数据线
	for(i=0x80;i>0;i>>=1)	// 高位为1,循环右移
	{
		Sck_P=1;
		if(Data_P)
			val=(val|i);    	// 读一位数据线的值
		Sck_P=0;
	}
	Data_P=!ack;    			// 如果是校验,读取完后结束通讯
	Sck_P=1;
	_nop_();							// 延时3us
	_nop_();
	_nop_();
	Sck_P=0;
	_nop_();
	_nop_();
	_nop_();
	Data_P=1; 						// 释放数据线
	return val;
}


void ShtTransStart(void)
{
	Data_P=1;
	Sck_P=0;
	_nop_();
	Sck_P=1;
	_nop_();
	Data_P=0;
	_nop_();
	Sck_P=0;
	_nop_();
	_nop_();
	_nop_();
	Sck_P=1;
	_nop_();
	Data_P=1;
	_nop_();
	Sck_P=0;
}

void ShtConnectReset(void)
{
	unsigned char i;
	Data_P=1; 		   		//准备
	Sck_P=0;
	for(i=0;i<9;i++)  	//DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位
	{
		Sck_P=1;
		Sck_P=0;
	}
	ShtTransStart();   	//启动传输
}

char ShtMeasure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
{
	unsigned error=0;
	unsigned int i;
	ShtTransStart();  		// 启动传输
	switch(mode)       		// 选择发送命令
	{
		case 1 :   					// 测量温度
			error+=ShtWriteByte(0x03);
			break;
		case 2 :   					// 测量湿度
			error+=ShtWriteByte(0x05);
			break;
		default:
			break;
	}
	for(i=0;i<65535;i++)
		if(Data_P==0)
			break;  					// 等待测量结束
		if(Data_P)
			error+=1;   			// 如果长时间数据线没有拉低,说明测量错误
	*(p_value) =ShtReadByte(1);  		// 读第一个字节,高字节 (MSB)
	*(p_value+1)=ShtReadByte(1); 		// 读第二个字节,低字节 (LSB)
	*p_checksum =ShtReadByte(0);  	// read CRC校验码
	return error;  									// error=1 通讯错误
}

void CalcSHT11(float *p_humidity ,float *p_temperature)
{
	const float C1=-4.0;	 			// 12位湿度精度 修正公式
	const float C2=+0.0405;			// 12位湿度精度 修正公式
	const float C3=-0.0000028;	// 12位湿度精度 修正公式
	const float T1=+0.01;	 			// 14位温度精度 5V条件 修正公式
	const float T2=+0.00008;	 	// 14位温度精度 5V条件 修正公式
	float rh=*p_humidity;	 			// rh: 12位 湿度
	float t=*p_temperature;			// t:  14位 温度
	float rh_lin;								// rh_lin: 湿度 linear值
	float rh_true;							// rh_true: 湿度 ture值
	float t_C;	 								// t_C : 温度 ℃
	t_C=t*0.01 - 40;	 					//补偿温度
	rh_lin=C3*rh*rh + C2*rh + C1;					//相对湿度非线性补偿
	rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;		//相对湿度对于温度依赖性补偿
	*p_temperature=t_C;	 				//返回温度结果
	*p_humidity=rh_true;	 			//返回湿度结果
}

unsigned char TempCorrect(int temp)
{
	if(temp<0)	temp=0;
	if(temp>970)  temp=970;
	if(temp>235)  temp=temp+10;
	if(temp>555)  temp=temp+10;
	if(temp>875)  temp=temp+10;
	temp=(temp%1000)/10;
	return temp;
}

unsigned char HumiCorrect(unsigned int humi)
{
	if(humi>999)  humi=999;
	if((humi>490)&&(humi<951))  humi=humi-10;
	humi=(humi%1000)/10;
	return humi+4;
}

void ReadShtData()
{
	value humi_val,temp_val;  	// 定义两个共同体,一个用于湿度,一个用于温度
	unsigned char error;  							// 用于检验是否出现错误
	unsigned char checksum;  						// CRC
	unsigned int temp1,humi1;						// 临时读取到的温湿度数据

	error=0; 										//初始化error=0,即没有错误
	error+=ShtMeasure((unsigned char*)&temp_val.i,&checksum,1); 	//温度测量
	error+=ShtMeasure((unsigned char*)&humi_val.i,&checksum,2); 	//湿度测量

	if(error!=0) 		  					//如果发生错误,系统复位
		ShtConnectReset();
	else
	{
		humi_val.f=(float)humi_val.i; 				//转换为浮点数
		temp_val.f=(float)temp_val.i;  				//转换为浮点数
		CalcSHT11(&humi_val.f,&temp_val.f);  	//修正相对湿度及温度
		temp1=temp_val.f*10;
		temp=TempCorrect(temp1);
		humi1=humi_val.f*10-50;
		humi=HumiCorrect(humi1);
		humi1=humi1-1;
	}

}

void key()
{
	if(key1==0)
	{
		delay(1);
		if(key1==0)
		{
			mode++;
			while(!key1);
		}
	}
		if(mode==1)
			{
				if(key2==0)
				{
					temp_max++;
				}
				if(key3==0)
				{
					temp_max--;
				}
			}
		if(mode==2)
			{
				if(key2==0)
				{
					temp_min++;
				}
				if(key3==0)
				{
					temp_min--;
				}
			}
		if(mode==3)
			{
				if(key2==0)
				{
					humi_max++;
				}
				if(key3==0)
				{
					humi_max--;
				}
			}
		if(mode==4)
			{
				if(key2==0)
				{
					humi_min++;
				}
				if(key3==0)
				{
					humi_min--;
				}
			}				
		if(mode==5){mode=0;}
}



void main(void)
{
	LcdInit();
		ShtConnectReset();
	DisplayListChar(0,0,"tmpe:");
	DisplayListChar(8,0,"HR:");
	DisplayListChar(0,1,"tmpe:");
	DisplayListChar(9,1,"HR:");
  jr=0;js=0;
	while(1)
	{ 
	  ReadShtData();
		key();
		DisplayOneChar(11,0,(char)(humi/10+'0'));
		DisplayOneChar(12,0,(char)(humi%10+'0'));
		DisplayOneChar(5,0,(char)(temp/10+'0'));
		DisplayOneChar(6,0,(char)(temp%10+'0'));
		DisplayOneChar(14,0,(char)(mode%10+'0'));
		DisplayOneChar(6,1,(char)(temp_min/10+'0'));
		DisplayOneChar(7,1,(char)(temp_min%10+'0'));
		DisplayOneChar(3,1,(char)(temp_max/10+'0'));
		DisplayOneChar(4,1,(char)(temp_max%10+'0'));
		DisplayOneChar(14,1,(char)(humi_min/10+'0'));
		DisplayOneChar(15,1,(char)(humi_min%10+'0'));
		DisplayOneChar(11,1,(char)(humi_max/10+'0'));
		DisplayOneChar(12,1,(char)(humi_max%10+'0'));

		if(temp>temp_max)
		{
				led=0;
				delay(20000);
				led=1;
        jr=0;		
		}
				if(temp<temp_min)
		{
			  jr=1;
				led=0;
				delay(10000);
				led=1;
        
				
       	
		}
				if(humi>humi_max)
		{
				led=0;
				delay(5000);
				led=1;
			  js=0;
		}
				if(humi<humi_min)
		{
			  js=1;
				led=0;
				delay(1000);
				led=1;
			
      		
		}
        else{jr=0;js=0;}
	}				
}

完整代码点开链接私信 免费 获取。

【iBot机器人工作室的个人空间-哔哩哔哩】 https://b23.tv/ryUWVKa

相关推荐
清风6666665 小时前
基于单片机的螺旋藻生长大棚PH智能控制设计
单片机·嵌入式硬件·毕业设计·课程设计
ting_zh6 小时前
微控制器(Micro Controller Unit, MCU)基础整理
单片机·嵌入式硬件
清风6666667 小时前
基于单片机的图书馆智能座位管理平台
数据库·单片机·嵌入式硬件·毕业设计·课程设计
得单片机的运8 小时前
STM32的以太网的搭建
stm32·单片机·嵌入式硬件·物联网·以太网·iot·w5500
酷飞飞9 小时前
RTC和看门狗基于GD32F407VE的天空星的配置
stm32·单片机·嵌入式硬件·mcu
WD1372980155710 小时前
WD5030A,24V降5V,15A 大电流,应用于手机、平板、笔记本充电器
stm32·单片机·嵌入式硬件·智能手机·汽车·电脑·51单片机
日更嵌入式的打工仔10 小时前
GPIO 中断通用配置指南
stm32·单片机·嵌入式硬件
平凡灵感码头10 小时前
基于 STM32 的智能门锁系统,系统界面设计
stm32·单片机·嵌入式硬件
Truffle7电子12 小时前
STM32理论 —— 存储、中断
stm32·嵌入式硬件·嵌入式·存储·中断
报错小能手12 小时前
linux学习笔记(32)网络编程——UDP
单片机·嵌入式硬件