自动浇花系统采用51单片机+LCD1602液晶+土壤传感器+继电器+ADC0832+水泵设计而成。
系统三个按键分别是:系统复位键、设置键、加键、减键。
1、土壤干湿度传感器实时给单片机传输信号。
2、按键设置土壤干湿度阈值,实现土壤水分的动态控制。
3、液晶实时显示土壤湿度情况,所设置的阈值,直观明了。
4、ADC0832将模拟信号转换成数字信号传给单片机。
按键调节上下限值,LCD1602实时显示土壤湿度值,并显示上下限值。土壤检测传感器检测湿度值低于下限时,蜂鸣器报警并驱动水泵浇水,湿度值高于上限时停止浇水。
单片机源程序如下:
#include
#include "intrins.h"
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define LCDIO P0 //液晶屏数据口
//ADC0832的引脚
sbit ADCLK =P1^1; //ADC0832 clock signal
sbit ADDIO =P1^3; //ADC0832 k in
sbit ADCS =P1^4; //ADC0832 chip seclect
sbit rs=P1^0; //定义1602 RS
sbit lcden=P1^2; //定义1602 EN
sbit key1=P3^0; //设定
sbit key2=P3^1; //加
sbit key3=P3^2; //减
sbit motor=P3^7; //继电器接口
sbit speak=P1^5; //蜂鸣器接口
uchar key; //设定指针
uint RH=400,RL=200;//水位上下限
float temp_f;
ulong temp;
uchar v;
uchar count,s1num;
uchar code table[]= " moisture: ";
uchar code table1[]="RH: % ";
uchar getdata; //获取ADC转换回来的值
/*********************************************/
void delay(uint z) //延时
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/**********************************************/
void write_com(uchar com)
{
rs=0;
// rd=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/*********************************************/
void write_date(uchar date)
{
rs=1;
// rd=0;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void lcdinit()
{
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
/***********************************************/
void init()
{
uchar num;
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<15;num++)
{
write_date(table1[num]);
delay(5);
}
}
//****************************************************************************/
/************
读ADC0832函数
************/
//采集并返回
/****************************************************************************
函数功能:AD转换子程序
入口参数:CH(如果读取CH0,channel的值为0x01,如果读取CH1则channel的值为0x03)
出口参数:adval
****************************************************************************/
uchar Adc0832() //AD转换,返回结果
{
uchar i;
uchar dat=0;
ADCLK=0;
ADDIO=1;
ADCS=0; //拉低CS端
ADCLK=1;
ADCLK=0; //拉低CLK端,形成下降沿1
ADDIO=1;//指定转换通道是CH1还是CH2,指定值位与0x1,取最后一位的值
ADCLK=1;
ADCLK=0; //拉低CLK端,形成下降沿2
ADDIO=0;//指定值右移一位,再取最后一位的值
ADCLK=1;
ADCLK=0; //拉低CLK端,形成下降沿3
ADDIO=1;
for(i=0;i<8;i++)
{
ADCLK=1;
ADCLK=0; //形成一次时钟脉冲
if(ADDIO)
dat|= 0x80>>i; //收数据
}
ADCS=1; //拉低CS端
ADCLK=1;
ADDIO=1; //拉高数据端,回到初始状态
return(dat); //return dat
}
/***************************************************************************/
/********************************************************/
void displayRH() //下限显示
{write_com(0xc0+3);
write_date(RH/100%10+0x30);//上限百位
write_date(RH/10%10+0x30);//上限十位
//write_date('.');
//write_date(RH%10+0x30);
}
void displayRL() //下限显示
{write_com(0xca);
write_date('R');
write_date('L');
write_date(':');
write_date(RL/100%10+0x30);//下限百位
write_date(RL/10%10+0x30);//下限十位
write_date('%');
}
/**************************************************/
/********************************************************/
void keyscan() //按键处理
{bit kk1=0,kk2=0;
if(key1==0)
{delay(30);
while(key1==0);
if(key>=2)
{key=0;
}
else
{key++;
}
switch(key)
{speak=1;kk2=motor;motor=1;
case 1:{write_com(0x0f);write_com(0xce); //光标闪烁
while(key1!=0) //等待按键松开
{
if(key2==0) //key2按键下
{delay(30); //按键延时消抖
if(key2==0) //确定key2按下
{
while(key2==0); //等待松开
if(RL>=998)
{RL=999; //RL下限最大设置为99
}
else
{RL+=10; //RL加1
}
}
displayRL(); //调用RL下限显示函数
write_com(0xce);
}
if(key3==0) //key3按下
{delay(30); //按键延时消抖
if(key3==0) //确定key3按下
{
while(key3==0); //等待key3按键松开
if(RL<=1) //RL最小设置为1
{RL=0;
}
else
{RL-=10; //RL下限减1
}
}
displayRL(); //调用RL下限显示函数
write_com(0xce);
}
}while(key1==0);
}
case 2:{write_com(0x0f);write_com(0xc4); //RH设置数据,光标闪烁
while(key1==1)
{
if(key2==0) //key2按下
{delay(30); //按键延时消抖
if(key2==0) //确定key2按下
{
while(key2==0); //等待松开
if(RH>=998) //RH最大设置为99
{RH=999;
}
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』