本设计由STC89C52单片机电路+LCD1602液晶显示电路+光照检测电路+土壤湿度传感器电路+A/D采样
PCF8591电路+风扇控制电路+继电器控制电路+高亮LED灯补光电路+高亮LED灯加热电路+按键控制电
路+电源电路组成。
1、通过光敏电阻检测光照强度,然后A/D模块PCF8591处理后,将光照强度值实时显示在液晶上,
并且可以按键控制光照的强度值,当光照低于设定的阈值,1颗白色高亮LED灯亮进行补光,光照高
于设定的阈值,就不用管。
2、通过DS18B20检测温度值,并且实时显示在1602液晶上,并且可以通过按键设定温度值,当温度
低于设定值时,通过一颗黄色高亮LED灯模拟。当温度超过设定值时,风扇旋转。
3、通过土壤湿度传感器检测土壤的湿度,并且将湿度值实时显示在液晶上,并且可以设定土壤的
使读者,当土壤湿度小于设定的阈值,继电器打开,进行水泵加水,当土壤湿度大于设定的阈值,继电器不工作
main主函数代码如下
#include <reg52.h>
#include "1602.h"
#include "18B20.h"
#include "i2c.h"
#include "delay.h"
#include <intrins.h>
#include <stdio.h>
//端口绑定
sbit led_light=P1^0;//补光灯
sbit led_warming=P1^1;//补温灯
sbit fan=P1^4; //风扇
sbit relay=P1^3;//继电器
sbit key_choice=P3^4;//选择设置键
sbit key_plus=P3^5;//加号键
sbit key_sign=P3^6;//减号键
//申明数组(1602)
char disdat[16];//打印数组
char disset[16];//设置数组
//申明变量值
unsigned char rekey;//检查按键是否重复
unsigned char setFlag=0;//按键设置位
unsigned int time_20ms;//定时器计数
unsigned char readTem=0;//定义一个读取温度的标志位
unsigned char readADCFlage=0;//定义一个读取ADC的标志位
//ADC采集
float Lv=0.0;//采集光照电压
float Tv=0.0;//采集土壤湿度的电压
float midval=0.0;//ADC采集数据变量申明
//温度采集
int temp;//定义一个温度的读取位
float temperature;//定义一个温度转换值
//预设值
unsigned char setLval=60;//光照
unsigned char setTval=35;//温度
unsigned char setHval=60;//湿度
//申明3个变量,用来存储光照,湿度,温度的值
unsigned int Lval=0;
unsigned int Tval=0;
unsigned int Hval=0;
/* 定时器中断配置函数 */
void Init_Timer0()
{
TMOD |= 0x01; //配置定时器T0模式1
TH0=(65536-20000)/256; //定时20ms
TL0=(65536-20000)%256;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
/* 主函数 */
void main()
{
Init_Timer0(); //定时器初始化
Initlcd1602(); //1602液晶初始化
DelayMs(10); //延时10ms
//显示1602
//sprintf()函数用于将格式化的数据写入字符串,其原型为:
//int sprintf(char *str, char * format [, argument, ...]);
sprintf(disdat,"L:%2d H:2d T:2d C ",Lval,Hval,Tval);
Lcd1602ShowStr(0,0,disdat);//显示第一行
sprintf(disset,"L:%2d H:2d T:2d C ",setLval,setHval,setTval);
Lcd1602ShowStr(0,1,disset); //显示第二行
//功能核心代码
while(1)
{
//==========按键检测操作模块区=============
//首先判断按键
if((key_choice==0)||(key_plus==0)||(key_sign==0))
{
if(rekey==0)
{
DelayMs(10);//延时10ms
//选择键设置
if(key_choice==0)
{
if(setFlag==0)//进入设置
{
setFlag=1;//设置光照
}else if(setFlag==1){
setFlag=2;//设置湿度
}else if(setFlag==2){
setFlag=3;//设置温度
}else if(setFlag==3){
setFlag=0;//退出设置
}
rekey=1;
}
//加号键设置
if(key_plus==0)
{
if(setFlag==1)//光照设置
{
if(setLval<99)
{
setLval++;
}
}else if(setFlag==2){//湿度设置
if(setHval<99)
{
setHval++;
}
}else if(setFlag==3){//温度设置
if(setTval<99)
{
setTval++;
}
}
rekey=1;//避免重复按键
}
//减号键设置
if(key_sign==0)
{
if(setFlag==1)
{
if(setLval>0)
{
setLval--;
}
}else if(setFlag==2){
if(setHval>0)
{
setHval--;
}
}else if(setFlag==3){
if(setTval>0)
{
setTval--;
}
}
rekey=1;//避免重复按键
}
}
}else{//按键设置完成复位
rekey=0;
}
//==========ACD转换及液晶刷新功能模块区=============
if(readADCFlage==1)
{
midval=ReadADC(0);
Tv=5.15 - (float)midval * 5.15 / 255;
Hval=(unsigned int)(Tv * 100) / 5.16;
DelayMs(10);
midval=ReadADC(1);
Lv=5.15 - (float)midval * 5.15 / 255;
Hval=(unsigned int)(Lv * 100) / 5.16;
DelayMs(10);
//显示1602
sprintf(disdat,"L:%2d H:2d T:2d C ",Lval,Hval,Tval);
Lcd1602ShowStr(0,0,disdat);//显示第一行
readADCFlage=0;//ACD的标志位复位
if(setFlag==1)
{
Lcd1602ShowChar(0,1,'S');
Lcd1602ShowChar(5,1,' ');
Lcd1602ShowChar(10,1,' ');
}else if(setFlag==2){
Lcd1602ShowChar(0,1,' ');
Lcd1602ShowChar(5,1,'S');
Lcd1602ShowChar(10,1,' ');
}else if(setFlag==3){
Lcd1602ShowChar(0,1,' ');
Lcd1602ShowChar(5,1,' ');
Lcd1602ShowChar(10,1,'S');
}else{
Lcd1602ShowChar(0,1,' ');
Lcd1602ShowChar(5,1,' ');
Lcd1602ShowChar(10,1,' ');
}
if(Lval <= setLval)//光照对比
{
led_light=0;//打开光照灯
}else{
led_light=1;//关闭光照灯
}
if(Tval <= setTval)//温度对比
{
led_warming=0;//打开补温灯
fan=1;//关闭风扇
}else{
led_warming=1;//关闭补温灯
fan=0;//打开风扇
}
if(Hval <= setHval)//湿度对比
{
relay=0; //打开继电器
}else{
relay=1; //关闭继电器
}
}
//==========读取DS18B20温度值功能模块区=============
if(readTem==1)
{
temp=ReadTemperature();//温度读取
temperature=(float)temp * 0.0625;//温度处理
if(temperature>1)//防止温度读错
{
Tval=(unsigned int)temperature;//取整,去掉小数部分
}
readTem=0;//温度的标志位复位
}
}
}
/*
定时器0的中断服务函数
目的:在很短的时间内去进行实时采集ADC,DS18B20的数值
*/
void InterruptTimer0() interrupt 1
{
//重新赋值
TH0=(65536-20000)/256; //定时20ms
TL0=(65536-20000)%256;
//定时器计数+1
time_20ms++;
//采集ADC
if(time_20ms % 20 == 0)
{
readADCFlage=1;
}
//采集DS18B20
if(time_20ms % 40 == 0)
{
readTem=1;
time_20ms=0;
}
}
剩下的文件上传不了,有需要的可以加,免费分享!
|