×
单片机 > 单片机程序设计 > 详情

单片机自动浇花器

发布时间:2020-06-17 发布时间:
|

自动浇花系统采用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;

}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
C51 特殊功能寄存器SFR的名称和地址