单片机
返回首页

单片机自动浇花系统

2019-10-17 来源:51hei

自己做的基于stc89c51单片机的自动浇花系统,有自动和手动两种模式,可以设置湿度的上下限,利用lcd1602显示,有一点遗憾的是设置湿度上下限时,没有光标闪动提示,希望大家给点建议,帮助改进,我把源程序附在这。


仿真原理图如下
 

原理图:
 


单片机源代码:

#include

#define uchar unsigned char

#define uint unsigned int 


sbit ad_cs=P1^3;         //ADC0832的控制位

sbit ad_clk=P1^0;

sbit ad_dat=P1^1;


sbit lcd_rs=P2^7;         //LCD1602的控制位

sbit lcd_e=P2^6;


sbit key1=P1^4;                 //独立按键

sbit key2=P3^2;

sbit key3=P3^3;


sbit relay=P1^6;     //继电器


bit flag=1;                     //工作模式标志

bit flag_motor=1;         //手动模式下,抽水机开关标志

bit flag_jia=0;

bit flag_jian=0;


uchar Hum_H=60;                 //自动模式下,湿度设定最大值

uchar Hum_L=30;                 //自动模式下,湿度设定最小值


uchar num=0;


/********************延时函数1ms*****************

void delay_ms(uint a)                                        

{

        uint i;

        while(a--)

        for(i=0;i<125;i++);

}

*************************************/



/*******************延时函数50us******************/

void delay_50us(uint a)

{

        uint i;

        while(a--)

        for(i=0;i<19;i++);

}

/*************************************/


/*******************ADC读取******************/

uchar read_ad(uchar channel)  

{

        uchar i;

        uchar dat1,dat2;

        ad_clk=0;

        ad_cs=0;

        ad_dat=1;

        ad_clk=1;

        ad_clk=0;  //起始信号


        ad_dat=1;

        ad_clk=1;

        ad_clk=0;  //选择单通道模式


        ad_dat=channel;//0对应通道0,1对应通道1

        ad_clk=1;

        ad_clk=0;


        ad_dat=1;


        for(i=0;i<8;++i)

        {

                 ad_clk=1;

                ad_clk=0;

                dat1=dat1<<1;

                if(ad_dat)

                dat1|=0x01;        

        

        }

        for(i=0;i<8;i++)

        {

                 dat2=dat2>>1;

                if(ad_dat)

                dat2|=0x80;        

                

                ad_clk=1;

                ad_clk=0;

        } 

        ad_cs=1;

        return (dat1==dat2)?dat1:0;

        

}

/*************************************/


/*******************LCD1602初始化******************/

void write_com(uchar com)        //写指令

{

        lcd_e=0;

        lcd_rs=0;

        P0=com;

        delay_50us(10);

        lcd_e=1;

        delay_50us(10);

        lcd_e=0;

}


void write_data(uchar dat)  //写数据

{

        lcd_e=0;

        lcd_rs=1;

        P0=dat;

        delay_50us(10);

        lcd_e=1;

        delay_50us(10);

        lcd_e=0;

}                         


void init_lcd1602()                 //lcd 初始化

{

        delay_50us(300);

        write_com(0x38);

        delay_50us(100);

        write_com(0x38);

        delay_50us(100);

        write_com(0x38);

        write_com(0x38);

        write_com(0x08);

        write_com(0x01);

        write_com(0x06);

        write_com(0x0c);

}


void display_shu(uchar add,uchar dat)          //显示数字

{

        uchar l,m;

        

//        k=dat/100;

        l=dat%100/10;

        m=dat%10;


        write_com(0x80+add);

//        write_data(k+0x30);

        write_data(l+0x30);

        write_data(m+0x30);

}


void display_string(uchar add,uchar *dat)  //显示字符串

{

        uchar i;

         write_com(0x80+add);

        while(dat!=0&&(*dat!='')&&i<16)

        {

                 write_data(*dat);

                dat++;

                i++;

                if(i==15) i=0;

        }

}

/*****************************************/


/****************主函数*******************/

void main()

{

        EA=1;                                                          //开总中断

        EX0=1;                                                          //开外部中断0

        EX1=1;                                                          //开外部中断1

        IT0=0;                                                          //外部中断0触发方式为低电平

        IT1=0;                                                          //外部中断1触发方式为低电平

        

        init_lcd1602();        

        

        display_string(0,'Hum:  %');      //实时显示当前的湿度

        display_string(11,'H:  %');       //显示设置的湿度最大值


        display_string(0x40,'Mode:');          //显示工作模式

        display_string(0x40+11,'L:  %');  //显示设置的湿度最小值



    while(1)

        {        

                uchar i;

                

                i=100-read_ad(0)*0.39;

                display_shu(4,i);

                display_shu(13,Hum_H);

                display_shu(0x40+13,Hum_L);

                if(key1==0)        

                        {

                                delay_50us(100);

                                if(key1==0)

                                {

                                        while(!key1);

                                        num++;

                                        if(num>2) num=0;

                                }        

                            

                                switch (num)                                         //选择工作模式和调整湿度设置最大、最小值

                            {

                                case 0:flag=~flag;

                                           flag_jia=0;

                                           flag_jian=0;

                                           //write_com(0x80+0x40);

                                       //write_com(0x0f);

                                           break;

                                case 1://write_com(0x80+9);

                                       //write_com(0x0f);

                                           //delay_50us(1000);

                                           //write_com(0x0c);

                                           flag_jia=1;

                                           flag_jian=0;

                                           break;

                                case 2://write_com(0x80+0x40+9);

                                       //write_com(0x0f);

                                           //delay_50us(1000);

                                           //write_com(0x0c);

                                           flag_jian=1;

                                           flag_jia=0;

                                           break;        

                           }

                           if(flag==0&&num==1)        

                           {

                                   flag=~flag;

                                   num=0;

                                   flag_jia=0;

                                   flag_jian=0;

                           }                

                    }                   

                if(flag==0)                              //手动模式

                {

                        

                         display_string(0x40+5,'MT');

                        if(flag_motor) relay=1;

                        else if(i                        else relay=1;

                }                                

                else                                                          //自动模式

                {

                        display_string(0x40+5,'AT');

                        if(i<(Hum_L+Hum_H)/2)                   //最大和最小值的平均值作为抽水的判断条件

                        {

                                 relay=0;

                        }

                        else relay=1;

                }

     }        

}

/********************************************/


/***********************外部中断*********************/

void int0() interrupt 0

{

        delay_50us(20);

        if(key2==0)

        while(!key2);

        flag_motor=~flag_motor;

        if(flag&&flag_jia)

          {

                    //write_com(0x80+9);

              //write_com(0x0f);

                  //delay_50us(1000);

              //write_com(0x0c);

                  //delay_50us(1000);

                  Hum_H++;

                  if(Hum_H>=99) Hum_H=99;

          } 

        if(flag&&flag_jian)

          {

                    //write_com(0x80+0x40+9);

                  //write_com(0x0f);

                  //delay_50us(1000);

                  //write_com(0x0c);

                  //delay_50us(1000);

                  Hum_L++;

                  if(Hum_L>=Hum_H) Hum_L=Hum_H-1;

          }    

}


void int1() interrupt 2

{

        delay_50us(20);

        if(key3==0)

        while(!key3);        

        if(flag&&flag_jian)

          {

                    //write_com(0x80+0x40+9);

                  //write_com(0x0f);

                  //delay_50us(1000);

                  //write_com(0x0c);

                  //delay_50us(1000);

                  Hum_L--;

                  if(Hum_L<=1) Hum_L=1;

          }

        if(flag&&flag_jia)

          {

              //write_com(0x80+9);

              //write_com(0x0f);

                  //delay_50us(1000);

              //write_com(0x0c);

                  //delay_50us(1000);

                  Hum_H--;

                  if(Hum_H<=Hum_L) Hum_H=Hum_L+1;

          }

}

/********************************************/


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 简洁的过零调功器电路设计与分析

  • CCFL的工作原理及电子驱动电路解析

  • MT3608构成3.7V转12V的升压电路图

  • 基于M66T旋律发​​生器的电路图解析

  • 基于CA3193的热电偶放大器电路

  • 基于TDA1554的立体声放大器电路

    相关电子头条文章