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

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

相关推荐
冲,干,闯42 分钟前
单片机里不想阻塞系统的延时
单片机·嵌入式硬件
小菜鸟学代码··1 小时前
STM32中断详解
stm32·单片机·嵌入式硬件
芒果de香蕉皮2 小时前
mavlink移植到单片机stm32f103c8t6,实现接收和发送数据
stm32·单片机·嵌入式硬件·算法·无人机
Yyq130208696822 小时前
MS41908M网络摄像机·监控摄像机用镜头驱动芯片(内置光圈控制
嵌入式硬件
musir13 小时前
stm32四联七段数码管,LED8*8点阵
stm32·单片机·嵌入式硬件
m0_748250033 小时前
【STM32】F103ZET6开发板----笔记01
笔记·stm32·嵌入式硬件
1101 11014 小时前
STM32-笔记16-定时器中断点灯
笔记·stm32·单片机
weixin_438150994 小时前
广州大彩串口屏安卓/linux触摸屏四路CVBS输入实现同时显示!
android·单片机
搬砖的小码农_Sky4 小时前
硬件设计:RS485电平标准
单片机·嵌入式硬件·fpga开发
ElePower95275 小时前
STM32学习(一)
stm32·嵌入式硬件