基于单片机作为控制器,利用温度传感器等采集大棚温度,并结合其它元器件,设计一个农业大棚温度自动控制系统,实现对棚内温度的设定、采集、检测、控制、报警、调节等功能。
1、提出农业大棚温度自动控制系统的总体设计方案;
2、对系统的进行硬件、软件设计;
3、应用Proteus软件对系统进行仿真验证。
系统设计上,首先对系统分析确定系统需要实现的功能,确定系统框架选择适合本次系统的元器件。根据各方面的分析和对比,本设计选择STC89C51单片机作为控制器,温度传感器为DS18B20,当温度超出设置上下限阀值,则系统报警并启动继电器进行温度控制。系统的人机交互使用独立按键实现对温度的调节,使用LCD1602液晶显示器显示系统的各项信息。软件设计采用Keil平台,C语言进行编程,最后使用Proteus软件对系统模拟仿真。仿真结果表明,本次系统能够实现对温度的检测,并且可以通过按键来调节温度阀值,保证当温度超过设定范围后报警,并开启继电器控制升降温设备,满足设计需求。
//程序头函数
#include
//显示函数
#include
//宏定义
#define uint unsigned int
#define uchar unsigned char
//管脚声明
sbit jdq= P2^4; //继电器
sbit Feng = P1^1; //蜂鸣器
//按键
sbit Key1=P1^3; //设置
sbit Key2=P1^4; //加
sbit Key3=P1^5; //减
sbit Key4=P1^6; //确定
sbit pwm = P1^2;
uchar f_pwm_l ;
sbit DQ=P1^0; //定义DS18B20总线I/O
signed char w,bj,bjx,bjd; //温度值全局变量
uint c; //温度值全局变量
bit bdata flag=0,flag_BJ,flag_off=1;
//时间计算
#define Imax 14000 //此处为晶振为11.0592时的取值,
#define Imin 8000 //如用其它频率的晶振时,
#define Inum1 1450 //要改变相应的取值。
#define Inum2 700
#define Inum3 3000
//解码变量
unsigned char Im[4]={0x00,0x00,0x00,0x00};
//全局变量
uchar f;
unsigned long m,Tc;
unsigned char IrOK;
//设置变量
uchar xx=20;
//下限
uchar sx=30;
//上限
int ds=0;
uchar Mode=0;
void delay(uint z)
{
uint i,j;
for(i=0;i0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
Delay_DS18B20(4);
}
return(dat);
}
/*****写一个字节*****/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
Delay_DS18B20(5);
DQ = 1;
dat>>=1;
}
}
/*****读取温度*****/
unsigned int Read Temperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
Init_DS18B20();
Write One Char(0xCC); //跳过读序号列号的操作
Write One Char(0x44); //启动温度转换
Init_DS18B20();
Write One Char(0xCC); //跳过读序号列号的操作
Write One Char(0xBE); //读取温度寄存器
a=Read One Char(); //读低8位
b=Read One Char(); //读高8位
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
t= tt*10+0.5; //放大10倍输出并四舍五入
return(t);
}
/*****读取温度*****/
void check_wendu(void)
{
c=Read Temperature()-5; //获取温度值并减去DS18B20的温漂误差
w=c/10; //计算得到整数位
if(w<0){w=0;} //设置温度显示上限
if(w>99){w=99;} //设置温度显示上限
}
void Key()
{
//模式选择
if(Key1==0)
{
while(Key1==0);
Feng=0;
Mode++;
Display_wd();
if(Mode==4)
{
Mode=1;
Feng=1;
}
write_com(0x38);//屏幕初始化
write_com(0x0d);//打开显示 无光标 光标闪烁
write_com(0x06);//当读或写一个字符是指针后一一位
switch(Mode)
{
case 1:
{
write_com(0x80+15);//位置
Feng=1;
break;
}
case 2:
{
write_com(0x80+0x40+5);//位置
Feng=1;
break;
}
case 3:
{
write_com(0x80+0x40+14);//位置
Feng=1;
break;
}
}
}