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

1设计任务

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

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

2. 设计要求

2.1系统方案论证

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

2.2系统硬件电路设计

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

2.3软件设计

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

#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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

K11mvp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值