找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1463|回复: 2
打印 上一主题 下一主题
收起左侧

这是一个单片机盆栽自动浇水系统的主程序,有没有大佬解释一下,每条程序的意思!

[复制链接]
跳转到指定楼层
楼主
ID:715024 发表于 2020-5-22 13:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<stc12.h>
#include <stdio.h>
#include "lcd.h"
#include <intrins.h>
#include"ds1302.h"
#include "EEPROM.h"

#define uint unsigned int
#define uchar unsigned char

#define EEPROMFLAG        0X5A
//IO定义
sbit KEY_up = P2^2;
sbit KEY_down = P2^3;
sbit KEY_set = P2^4;
sbit LED = P2^3;
sbit Relay = P1^4;

//ADC0832端口定义
sbit ADC_DO = P1^1;
sbit ADC_CLK = P1^0;
sbit ADC_CS = P1^2;
/*-------------函数声明----------------*/
void SysInit();
void delay_ms(uint ms);
void BuzzerVoice(void);
void KeyHandle(void);                        //按键处理函数
void GetHumidity(void);
void HumidityHandle(void);
uchar ADC0832(uchar channel);
void ClearBuffer(void);
void Read_EEPROM(void);
void Writer_EEPROM(void);
/*-------------变量定义-----------------*/
char Buffer[20]= {0};
uchar SysState = 0,CurrentMode = 0,SysCount = 0;
uint CurrentHumidity = 0;                //当前湿度值
uchar MaxHumidity = 80,MinHumidity = 20;                        //湿度最值
uchar Sec_Pre = 60;
uchar KeyState = 0;
uchar RelayFlag = 0;
void main(void)
{
    SysInit();
        
    while(1)
    {
        KeyHandle();
        GetHumidity();                //获取湿度
                HumidityHandle();                //湿度处理
    }
}


//启动界面
void Display_Startup(void)
{
    uint temp=0,i;
    LcdWriteStr(1,2," System loadig");
    for(i=1; i<=16; i++)
    {
        delay_ms(100);
        LcdWriteChar(2,i,'.');
    }
    LcdClear();
    delay_ms(500);
}

//主界面
void Display_main(void)
{
    Ds1302ReadTime();
    LcdClear();
        CurrentHumidity = 100 - (ADC0832(0)/255.0)*100;
        LcdWriteNum(1,5,CurrentHumidity,3);
    LcdWriteStr(1,1,"Hum:   %   CLOSE");
    sprintf(Buffer,"20%02d/%02d/%02d %02d:%02d",(int)TIME[6],(int)TIME[4],(int)TIME[3],(int)TIME[2],(int)TIME[1]);                //输出时间
    LcdWriteStr(2,1,Buffer);
}



void SysInit()
{
        P1M0 = 0X10;
        P1M1 = 0X00;
        Relay = 0;
    LcdInit();
        Display_Startup();
        Read_EEPROM();
    Display_main();

}

void Delay100us()                //@11.0592MHz
{
    unsigned char i;

    i = 43;
    while (--i);
}


//获取AD值
uchar ADC0832(uchar channel)
{
    uchar i,ADC_Data;

    ADC_CS=0;
    ADC_Data=0;
    ADC_DO=0;
    Delay100us();

    ADC_CLK=0;
    Delay100us();
    ADC_DO=1;  //第一个脉冲  启动AD转换器
    ADC_CLK=1;
    Delay100us();
    ADC_CLK=0;

    Delay100us();
    ADC_CLK=1; // 第二的脉冲 送出1
    ADC_DO=1;
    Delay100us();
    ADC_CLK=0;

    Delay100us();

    if(channel == 0)
    {
        ADC_DO=0;
    }
    else
    {
        ADC_DO=1;
    }

    ADC_CLK=1;   //第三个脉冲 送出0
    Delay100us();
    ADC_CLK=0;

    ADC_DO=0;   //D1口转为高阻态
    ADC_DO=1;   //D0口脱离高阻态 为输出做准备

    for (i=0; i<8; i++) //读出数据
    {
        ADC_CLK=1;
        Delay100us();
        ADC_CLK=0;
        Delay100us();
        ADC_Data=(ADC_Data<<1)|ADC_DO;
    }
    ADC_CS=1;
    return(ADC_Data);
}

//获取湿度
void GetHumidity(void)
{
    if(SysState == 0)
    {
        Ds1302ReadTime();
        if(Sec_Pre != TIME[0])
        {
            CurrentHumidity = 100 - (ADC0832(0)/255.0)*100;
            LcdWriteNum(1,5,CurrentHumidity,3);
            Sec_Pre = TIME[0];
            sprintf(Buffer,"20%02d/%02d/%02d %02d:%02d",(int)TIME[6],(int)TIME[4],(int)TIME[3],(int)TIME[2],(int)TIME[1]);                //输出时间
            LcdWriteStr(2,1,Buffer);
        }
    }
}

void HumidityHandle(void)
{
    if(SysState == 0)
    {

                if(CurrentHumidity <= MinHumidity)
                {
                        if(RelayFlag != 1)
                        {
                                RelayFlag = 1;
                                Relay = 1;
                                LcdWriteStr(1,12,"OPEN ");
                        }
                }
                else if(CurrentHumidity >= MaxHumidity)
                {
                        if(RelayFlag != 0)
                        {
                                RelayFlag = 0;
                                Relay = 0;
                                LcdWriteStr(1,12,"CLOSE ");
                        }
                }
    }
}

//按键扫描
void KEY_Scan()
{
    static uchar KeyFlag = 0;
    if((KEY_up == 0 || KEY_down == 0 || KEY_set == 0)&& KeyFlag == 0)
    {
        delay_ms(10);
        if(KEY_up == 0)        KeyState = 1;
        else if(KEY_down == 0) KeyState = 2;
        else if(KEY_set == 0) KeyState = 3;

        if(KeyState != 0)
        {
            KeyFlag = 1;
        }
    }
    if(KeyFlag == 1)
    {
        if(KEY_up == 1 && KEY_down == 1 && KEY_set == 1)
            KeyFlag = 0;
    }
}

void Set_Handle()
{
    if(SysState  == 0)
    {
        SysState = 1;
        SysCount = 0;
        CurrentMode = 1;
        LcdClear();
        LcdWriteStr(2,1,"  Set Timer");
        LcdWriteStr(1,1,"->Set Humidity");
    }
    else
    {
        SysCount++;
        if(CurrentMode == 1)                //设置浓度
        {
            if(SysCount == 1)                //最大浓度
            {
                SysState = 2;
                                LcdClear();
                LcdWriteStr(1,1,"Max:");
                LcdWriteStr(2,1,"Min:");
                LcdWriteNum(1,5,MaxHumidity,3);
                LcdWriteNum(2,5,MinHumidity,3);
                                LcdWriteCom(0x80+4);        //定位光标
                LcdWriteCom(0x0f);                //光标闪烁
            } else if(SysCount == 2)                //最小浓度
            {
                LcdWriteCom(0xC0+4);        //定位光标
            }
            else
            {
                                Writer_EEPROM();                //写入数据
                                LcdWriteCom(0x0c);  //开显示不显示光标
                SysState = 0;
                Display_main();
            }
        }
        else                //设置时间
        {
            if(SysCount == 1)
            {
                SysState = 2;
                LcdClear();
                LcdWriteStr(1,5,"Set Timer");
                Ds1302ReadTime();
                ClearBuffer();
                sprintf(Buffer,"20%02d/%02d/%02d %02d:%02d",(int)TIME[6],(int)TIME[4],(int)TIME[3],(int)TIME[2],(int)TIME[1]);                //输出时间
                LcdWriteStr(2,1,Buffer);
                Buffer[0] = TIME[6];                 //年
                Buffer[1] = TIME[4];                 //月
                Buffer[2] = TIME[5];                 //日
                Buffer[3] = TIME[2];                 //时
                Buffer[4] = TIME[1];                 //分
                                LcdWriteCom(0xC0+2);        //定位光标
                LcdWriteCom(0x0f);                //光标闪烁
            }
                        else if(SysCount == 2)
                        {
                                LcdWriteCom(0xC0+5);        //定位光标
                        }
                        else if(SysCount == 3)
                        {
                                LcdWriteCom(0xC0+8);        //定位光标
                        }
                        else if(SysCount == 4)
                        {
                                LcdWriteCom(0xC0+11);        //定位光标
                        }
                        else if(SysCount == 5)
                        {
                                LcdWriteCom(0xC0+14);        //定位光标
                        }
                        else
                        {
                                TIME[6] = Buffer[0];                 //年
                                TIME[4] = Buffer[1];                 //月
                                TIME[5] = Buffer[2];                 //日
                                TIME[2] = Buffer[3];                 //时
                                TIME[1] = Buffer[4];                 //分
                                TIME[0] = 0;                                //秒
                                Ds1302WriteTime();
                                LcdWriteCom(0x0c);  //开显示不显示光标
                                SysState = 0;
                Display_main();
                        }
        }
    }
}


//湿度设置
void Humidity_Set(void)
{
        if(SysCount == 1)
        {
                if(KeyState == 1)
                {
                        if(MaxHumidity < 100)
                                MaxHumidity++;
                }
                else
                {
                        if(MaxHumidity-1 > MinHumidity)
                                MaxHumidity--;
                }
                LcdWriteNum(1,5,MaxHumidity,3);
                LcdWriteCom(0x80+4);        //定位光标
        }
        else
        {
                if(KeyState == 1)
                {
                        if(MinHumidity <= MaxHumidity-1)
                                MinHumidity++;
                }
                else
                {
                        if(MinHumidity > 0)
                                MinHumidity--;
                }
                LcdWriteNum(2,5,MinHumidity,3);
                LcdWriteCom(0xC0+4);        //定位光标
        }
}

//时间处理
void Timer_Handle(void)
{
        if(SysCount == 1)                //年
        {
                if(KeyState == 1)
                        Buffer[0]++;
                else
                {
                        if(Buffer[0] > 0)
                                Buffer[0]--;
                }
                LcdWriteNum(2,3,Buffer[0],2);
                LcdWriteCom(0xC0+2);        //定位光标
        }
        else if(SysCount == 2)                //月
        {
                if(KeyState == 1)
                {
                        if(Buffer[1] < 12)
                                Buffer[1]++;
                }
                else
                {
                        if(Buffer[1] > 1)
                                Buffer[1]--;
                }
                LcdWriteNum(2,6,Buffer[1],2);
                LcdWriteCom(0xC0+5);        //定位光标
        }
        else if(SysCount == 3)                //日
        {
                if(KeyState == 1)
                {
                        if(Buffer[2] < 31)
                                Buffer[2]++;
                }
                else
                {
                        if(Buffer[2] > 1)
                                Buffer[2]--;
                }
                LcdWriteNum(2,9,Buffer[2],2);
                LcdWriteCom(0xC0+8);        //定位光标
        }
        else if(SysCount == 4)                //时
        {
                if(KeyState == 1)
                {
                        if(Buffer[3] < 24)
                                Buffer[3]++;
                }
                else
                {
                        if(Buffer[3] > 0)
                                Buffer[3]--;
                }
                LcdWriteNum(2,12,Buffer[3],2);
                LcdWriteCom(0xC0+11);        //定位光标
        }
        else if(SysCount == 5)                //分
        {
                if(KeyState == 1)
                {
                        if(Buffer[4] < 59)
                                Buffer[4]++;
                }
                else
                {
                        if(Buffer[4] > 0)
                                Buffer[4]--;
                }
                LcdWriteNum(2,15,Buffer[4],2);
                LcdWriteCom(0xC0+14);        //定位光标
        }
}

void Up_Handle(void)
{
    if(SysState == 1)
    {
        CurrentMode = 1;
        LcdWriteStr(2,1,"  Set Timer");
        LcdWriteStr(1,1,"->Set Humidity");
    }
    else if(SysState == 2)
    {
        LcdWriteCom(0x0c);  //开显示不显示光标
        if(CurrentMode == 1)                //湿度设置
        {
                        Humidity_Set();
        }
        else                                 //时间设置
        {
                        Timer_Handle();
        }
        LcdWriteCom(0x0f);                //光标闪烁
    }
}

void Dec_Handle(void)
{
    if(SysState == 1)
    {
        CurrentMode = 2;
        LcdWriteStr(1,1,"  Set Humidity");
        LcdWriteStr(2,1,"->Set Timer");
    }
        else if(SysState == 2)
        {
                LcdWriteCom(0x0c);  //开显示不显示光标
                if(CurrentMode == 1)                //湿度设置
        {
                        Humidity_Set();
                }
                else
                {
                        Timer_Handle();
                }
                LcdWriteCom(0x0f);                //光标闪烁
        }
}

//按键处理
void KeyHandle(void)
{
    KEY_Scan();
    if(KeyState != 0)
    {
        switch(KeyState)
        {
        case 1:                        //增加按键
            Up_Handle();
            break;
        case 2:                        //减少按键
            Dec_Handle();
            break;
        case 3:                        //设置按键
            Set_Handle();
            break;
        }
        KeyState = 0;
    }
}

void ClearBuffer(void)
{
    uchar i;
    for(i=0; i<20; i++)
        Buffer[ i] = 0;
}

//写入EEPROM
void Writer_EEPROM(void)
{
        IapEraseSector(0);
        IapProgramByte(0,EEPROMFLAG);
        IapProgramByte(1,MaxHumidity);
        IapProgramByte(2,MinHumidity);
}

//读取EEPROM
void Read_EEPROM(void)
{
        uchar temp;
        temp = IapReadByte(0);
        if(temp != EEPROMFLAG)                //第一次写入数据
        {
                MaxHumidity = 80;
                MinHumidity = 20;
                Writer_EEPROM();
        }
        else
        {
                MaxHumidity = IapReadByte(1);
                MinHumidity = IapReadByte(2);
        }
}
void delay_ms(uint ms)                //@11.0592MHz
{
    unsigned char i, j;

    while(ms--)
    {
        _nop_();
        i = 11;
        j = 120;
        do
        {
            while (--j);
        } while (--i);
    }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:584814 发表于 2020-5-23 09:22 | 只看该作者
这么短的程序不值得逐条解释要弄个万行起步的才得劲
回复

使用道具 举报

板凳
ID:715024 发表于 2020-5-23 14:26 | 只看该作者
man1234567 发表于 2020-5-23 09:22
这么短的程序不值得逐条解释要弄个万行起步的才得劲

拜托能不能帮我解释一下,大佬~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表