不知道怎么改

2019-03-24 17:34发布

/*********************************************************
-- 程序名称:温室定(变)量灌溉控制器:
-- 功    能:1).系统菜单; 2).空气湿度测量; 3).温度测量;
                           4).变量轮灌; 5).定量轮灌;         6).定量点灌;
                          7).更新定时时间;                                8).系统自检.
-- 时    间:2010-11-4
-- 编    程:杨术明          Version:v1.0
-- 修改时间:2010-11-11
;*********************************************************/
//------------包含文件--------
#include<reg52.h>
#include<math.h>
#include<string.h>
#include<INTRINS.H>
#include <absacc.h>
#include <stdio.h>
//#include<stdlib.h>
#include "scancodesysm.h"
#include "STC5A_EEPROM.h"         
#define        uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long        
//----------------------
#define BYTE_BIT0        0x01
#define BYTE_BIT1        0x02
#define BYTE_BIT2        0x04
#define BYTE_BIT3        0x08
#define BYTE_BIT4        0x10
#define BYTE_BIT5        0x20
#define BYTE_BIT6        0x40                                                                                                                                                                                A
#define BYTE_BIT7        0x80
//---------------------
/***********************JHD19264A接口*****************************
;连线图:
;LCM---89C52  LCM---89C52   LCM-------89C52     LCM----------89C52
;DB0---P0.0   DB4---P0.4    D/I-------P2.2      CS1----------P2.3  
;DB1---P0.1   DB5---P0.5    R/W-------P2.1      CS2----------P2.4  
;DB2---P0.2   DB6---P0.6    RST--------VCC      RST----------P3.4
;DB3---P0.3   DB7---P0.7    E---------P2.0                           
;注:89C52的晶振频率为11.0592MHz
;写汉字液晶子程 液晶屏分为4行*12列汉字,全部使用模拟接口方式
;******************************************************************/
//-----常用操作命令和参数定义---------
#define         DISPON                0x3f        //显示on               
#define         DISPOFF        0x3e        //显示off               
#define         DISPFIRST        0xc0        //显示起始行定义        
#define         SETX                0x40        //X定位设定指令(页)        
#define         SETY                0xb8        //Y定位设定指令(列)        
#define         Lcdbusy        0x80        //LCM忙判断位               
//--------显示分区边界位置------------
#define         MODL                0x00        //左区                        
#define         MODM                0x40        //左区和中区分界        
#define         MODR                0x80        //中区和右区分界        
#define        LCMLIMIT        0xC0        //显示区的右边界
sfr         Datalcm                =0x80;                //数据口        
//-----液晶显示器接口引脚定义--------
sbit        Elcm                   =P2^0;                //
sbit        Rwlcm                =P2^1;                //
sbit        Dilcm                =P2^2;                //
sbit        CS1LCM                =P2^3;                //
sbit        CS2LCM                =P2^4;                //
//----蜂鸣器,继电器---------------
sbit           relay                =P2^5;
sbit           Beep                =P2^6;  
bdata         uchar keyflag=0;
sbit         key0flag=keyflag^0;
sbit         key1flag=keyflag^1;
//sbit         timeflag=keyflag^2;
sbit         serialflag=keyflag^3;
sbit         tempflag=keyflag^4;
sbit         soilflag=keyflag^5;
//----DHT21-------------------------
sbit   DHT21_DAT         =P2^7;        //DHT21 DATA引脚
uchar  data U8FLAG,k,err;
uchar  idata U8count,U8temp;
uchar  idata U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;        //16位湿度数据+16位温度数据+8位校验位;
uchar  idata U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
uchar  idata U8comdata;
float  xdata temp=0,humidity=0;

uint   xdata U16temp1=0, U16temp2=0;
int  xdata adjh=0,adjt=0;
//========继电器组定义(7站)==================
/*sbit        RELAY1                = P1^1;             //
sbit        RELAY2                = P3^7;
sbit        RELAY3                = P1^3;
sbit        RELAY4                = P1^2;
sbit        RELAY5                = P1^4;
sbit        RELAY6                = P2^7;
sbit        RELAY7                = P3^5;  */
//========继电器组定义(4站)==================
sbit        RELAY1                = P1^3;             //
sbit        RELAY2                = P3^7;                                //
sbit        RELAY3                = P1^4;
sbit        RELAY4                = P1^2;
//==============PS2键盘=================
sbit           Key_CLK                =P3^3; //INT1
sbit           Key_Data        =P3^6; //WR
sbit           Redled                =P3^5; //T1
//-------------STC12C5A32AD------------
sfr            CLK_DIV         =0x97;        //时钟分频寄存器
sfr         AUXR                =0x8e;        //辅助寄存器
sfr         AUXR1                =0xA2;        //辅助寄存器1,AUXR1.2为ADRJ:0,10位结果的高8位存放在ADC_RES中,低2位存放在ADC_RES1的低2位;1,10位结果的高2位存放在ADC_RES1的低2位,低8位存放在ADC_RES中
sfr         P1ASF                =0X9D;        //P1口模拟特殊功能选择寄存器,相应位置1,P1.4则当A/D使用
sfr         ADC_CONTR         =0XBC;        //A/D转换控制寄存器,ADC_POWER SPEED1 SPEED2 ADC_FLAG ADC_START CHS2 CHS1 CHS0
sfr         ADC_RES         =0XBD;        //A/D转换结果寄存器
sfr         ADC_RESL         =0XBE;        //A/D转换结果寄存器低
sfr            BRT                 =0x9C;        //时钟分频寄存器
sfr         WDT_CONTR         =0xC1;        //看门狗SFR,声明寄存器        STC12c系列
//============命令帧,数据帧头及分机编号,命令类型定义=======
#define RELAYNO1                0x01
#define RELAYNO2                0x02
#define RELAYNO3                0x03
#define RELAYNO4                0x04
#define RELAYNO5                0x05
#define RELAYNO6                0x06
#define RELAYNO7                0x07

#define COMTEMP                        0x01
#define COMSOIL                        0x02
#define COMTEMP_SOIL        0x03
#define COMOK                        0x04
#define COMERR                        0x05
#define SOIL_LOWERLIMIT                15
#define SOIL_UPPERLIMIT                20
#define TEMP_LOWERLIMIT                15
#define TEMP_UPPERLIMIT                eeprom[6]
#define HUMI_LOWERLIMIT                eeprom[5]
#define HUMI_UPPERLIMIT                50

//----------------------------------------------------------------------------------------------------------------
bdata uchar DATA_BUF;
#define DATA7        ((DATA_BUF&BYTE_BIT7) != 0)          // 就是一个宏定义, 遇到宏 DATA7 就会替换成 ((DATA_BUF & BYTE_BIT7) != 0)
#define DATA0   ((DATA_BUF&BYTE_BIT0) != 0)
sbit        flag        =DATA_BUF^7;
sbit        flag1        =DATA_BUF^0;

uchar idata  str[5]={0};
char xdata timerset[4]={25,25,25};
float xdata soilmoisture=0;
float xdata soil;
//char* soil;
//char txbuf[];        ///        待定
/****************全局变量定义*******************/
uchar col,row,cbyte;                //列x,行(页)y,输出数据
bit TimeFlag=0;
bit Hzflag=0;
bit Disflag=0,CheckFlag=0,ESCFlag=0,OKFlag=0;
uint  TimeCounter,TimeCnt; //TimeCounter:电磁阀开启时间常数;TimeCnt:计数器
uint xdata timersendcontrol=300;//定时灌溉时间控制参数          300/300=1min
bit numlockflag=0,validflag=0;//收到有效键码标志
uchar IntNum = 0; //中断次数计数
uchar KeyV; //键盘传来的通码或断码
uchar retkey,key;
bit Key_UP=1,Shift = 0;//Key_UP=0是键松开标识,Shift=0是Shift键按下标识
bit BF = 0; //标识是否有键按下标识,有键按下在中断中置1,解码完毕清0
uchar         rxflag=0;
// ------------------通信变量-------------------------
//uchar  data   uc0;//,RetKey;
uchar  xdata ComBuf[20]; //register for display
char   xdata eeprom[7]; //eerom中参数:T0 T1 T3 AT AH HL TL
//eeprom[0]=timerset[0],eeprom[1]=timerset[1],eeprom[2]=timerset[2]
//eeprom[3]=adjt,                eeprom[4]=adjh,                  eeprom[5]=Humid LOW
//eeprom[6]=Temp LOW
//---------------键值定义-------------------
display[];

#define NoKeyPress    0xff   //* 没有键按下

#define KEY_INS                0
#define KEY_END                1
#define KEY_DOWN        2
#define KEY_PgDn        3
#define KEY_LEFT        4
#define KEY_RIGHT        6
#define KEY_HOME        7
#define KEY_UP                8
#define KEY_PgUp        9
#define KEY_ESC                10
#define KEY_OK                13

//--------Menu Definition-------------------
uchar  iMenuID;        //当前菜单的ID
uchar  iMenuNextID;           //将要显示菜单的ID,
uchar idata cMenuTemp1;//显示菜单时的临时索引号
//======当前状态索引号定义===========
#define                 MAX_KEYTABSTRUCT_NUM                        20
#define         MENU_FACE                                                0
#define         MENU_ROOT                                                1

#define         MENU_Mode                                                2
#define                MENU_Mode_UNIFORMRATE                        3
#define                MENU_Mode_SELECT                                4
#define                MENU_Selfcheck                                        5
#define                MENU_Selfcheck_KBCHECK                        6
#define                MENU_Selfcheck_DHT21                    7
#define                MENU_Selfcheck_SENSORCHECK                8
#define                MENU_Selfcheck_nRF905CHECK                9

#define                MENU_SystemSet                                        10
#define                MENU_SystemSet_COM                                11
#define                MENU_SystemSet_COM_BAUDRATE                12
#define                MENU_SystemSet_COM_SELECOM                13
#define                MENU_SystemSet_INITIALAMOUNT        14
                                                                                       
#define                MENU_Experiment                                        15
#define                MENU_Experiment_DHT21_ADJUST        16
#define                MENU_Experiment_SENSOR                        17
#define                MENU_Experiment_WATERMAN                18
#define                MENU_Experiment_EMVopen                        19

//-------------------------------------------------
typedef struct
        {
        uchar KeyTab_MenuIndex;                //当前状态索引号
        uchar KeyTab_MaxItems;                //本级菜单最大条目数
    uchar KeyTab_PressOk;            //按下"回车"键时转向的状态索引号
           uchar KeyTab_PressEsc;                //按下"返回"键时转向的状态索引号
    uchar KeyTab_PressDown;            //按下"向下"键时转向的状态索引号
           uchar KeyTab_PressUp;            //按下"向上"键时转向的状态索引号
        void (*CurrentOperate)();   //当前状态应该执行的功能操作
        }KeyTabStruct;
        void    (*KeyFuncPtr)();        //按键功能指针
typedef struct PID
{
int SetPoint; //设定目标 Desired Value
long SumError; //误差累计
double Proportion; //比例常数 Proportional Const
double Integral; //积分常数 Integral Const
double Derivative; //微分常数 Derivative Const
int LastError; //Error[-1]
int PrevError; //Error[-2]
} PID;
static PID sPID;
static PID *sptr = &sPID;

/*****************函数列表**********************/
void Lcminit(void);                //液晶模块初始化        
void Delay(uchar);                //延时,入口数为Ms        
void Delay1(uint j);
//void delay1(uint i);
void lcdbusyL(void);                //busy判断、等待(左区)        
void lcdbusyM(void);                //busy判断、等待(中区)        
void lcdbusyR(void);                //busy判断、等待(右区)        
//void Putedot(uchar);                //半角字符输出               
void Putedot(uchar Order,bit DispAttrib); //半角字符输出
void Putcdot(uchar);                //全角(汉字)输出        
void Wrdata(uchar);                    //数据输出给LCM               
void Lcmcls( void );                //LCM全屏幕清零(填充0)        
void wtcom(void);                        //公用busy等待               
void Locatexy(void);                //光标定位               
void WrcmdL(uchar);                        //左区命令输出               
void WrcmdM(uchar);                        //中区命令输出               
void WrcmdR(uchar);                        //右区命令输出               
void Putstr(uchar *puts,uchar i);        //中英文字符串输出        
void Timer0init(void);
void Timer1init(void);
uchar Key_Press(bit b);
void  RestWatchdog(void);
void  TranDataBy232(uchar d);
void  OpeningBeep(uchar OBN);
void InitSBUF(void);
void RecvToBuf(void);
void CheckLED(void);
//void DispFirstmenu(void);
void Lcmclsline(uchar lineNo );
void MenuFunctionDemo1(void);
void JudgeHLight(void);
void DispFace(void);
uchar Decode(uchar ScanCode);
void FlashLed(uchar num);
void Config905(void);
void nRF905Init(void);
void read_humidity(void);
void work_humidity(void);
void SendData(uchar *a);
void eeprom_initialize(void);
void eeprom_save(void);
void work_adc(void);
void IncPIDInit(void);
int IncPIDCalc(int NextPoint);
/******************数组列表*********************/
uchar code Ezk[];                //ASCII常规字符点阵码表0        
uchar code Hzk[];                //自用汉字点阵码表        
uchar code STR0[];
uchar code STR1[];                //自定义字符串               
//uchar code STR2[];
uchar code Hzk1[];                //自用汉字点阵码表1        
uchar code Hzk2[];                //自用汉字点阵码表1        
//KeyTabStruct code KeyTab[MAX_KEYTABSTRUCT_NUM];
KeyTabStruct xdata KeyTab[MAX_KEYTABSTRUCT_NUM];
uchar code *Menu_Root[4]=
        {
        " Mode ",
        " Check",
        " Set  ",
        " Help "
        };
uchar code Menu_RootID[4]=
        {
        MENU_Mode,
        MENU_Selfcheck,
        MENU_SystemSet,
        MENU_Experiment
        };
uchar code *Menu_Mode[2]=
        {
        " Variable   Rate",
        " Rotational Rate",
        };
uchar code Menu_ModeID[2]=
        {
        MENU_Mode_UNIFORMRATE,
        MENU_Mode_SELECT
        };
//
uchar code *Menu_Selfcheck[5]=
        {
        " Keyboard Check",
        " DHT21    Check",
        " EEPROM   Check",
        " nRF905   Check",
        };                        
uchar code Menu_SelfcheckID[4]=
        {
        MENU_Selfcheck_KBCHECK,
        MENU_Selfcheck_DHT21,
        MENU_Selfcheck_SENSORCHECK,
        MENU_Selfcheck_nRF905CHECK,
        };
//
uchar code *Menu_SystemSet[2]=
        {
        " Set Partime ",
        " Set Alltime"
        };
uchar code Menu_SystemSetID[2]=
        {
        MENU_SystemSet_COM,
        MENU_SystemSet_INITIALAMOUNT
        };
uchar code *Menu_COM[2]=
        {
        " T0-T3     ",
        " Selected Rate"
        };
uchar code Menu_COMID[2]=
        {
        MENU_SystemSet_COM_BAUDRATE,
        MENU_SystemSet_COM_SELECOM
        };
uchar code *Menu_Experiment[4]=
        {
        " DHT21 Adjust_H",
        " Adj   All    ",
        " Irri  Manually",
        " DHT21 Adjust_T"
        };
uchar code Menu_ExperimentID[4]=
        {
        MENU_Experiment_DHT21_ADJUST,
        MENU_Experiment_SENSOR,
        MENU_Experiment_WATERMAN,
        MENU_Experiment_EMVopen,
        };
//uchar code MenuNULL[]={"              "};
/********************************
--------- 主程序---------------
********************************/
void main(void)

{        

    uchar i;
        CLK_DIV=2;
        //WDT_CONTR = 0x3E;// 4.55s 启动看门狗
        Delay(20);
        FlashLed(3);
        OpeningBeep(3);
        col=0;
        row=0;
        eeprom_initialize();
        //for(i=0;i<4;i++) timerset=25;
        TimeFlag=0;
        iMenuID=MENU_FACE;
        iMenuNextID=MENU_ROOT;//按下回车时显示Menu-root菜单
        Timer0init(); Timer1init();
        InitSBUF();
        Lcminit();                //液晶模块初始化,包括全屏幕清屏
        IncPIDInit();
        retkey=0xff;
        IT1 = 0; //设外部中断1为低电平触发
        EX1 = 1; //开中断
        DispFace();
        i=3;
        while(1)
        {
            key=Key_Press(0);//按键扫描程序
                if(i) key= KEY_OK;//directly go to the variable rate irrigation mode
                if(i!=0) i=i-1;
                switch(key)
                {
                        case        KEY_OK://KEY_OK,        KEY_UP,        KEY_ESC,
                                        if(KeyTab[iMenuID].KeyTab_PressOk!=99)        
                                        //if((KeyTab[iMenuID].KeyTab_PressOk!=99)&&(iMenuNextID!=99))//ysm
                                        { //还有子菜单,将子菜单的索引号作为当前索引号
                                                //iMenuID=KeyTab[iMenuID].KeyTab_PressOk;
                                                iMenuID=iMenuNextID;//用iMenuID暂存父菜单ID,以备按下ESC时能回到先前显示状态,即高亮显示菜单不变.
                                                iMenuNextID=KeyTab[iMenuID].KeyTab_PressOk;//将要高亮显示的子菜单索引号
                                                //TranDataBy232(iMenuID);
                                                //TranDataBy232(iMenuNextID);
                                                JudgeHLight();//显示子菜单
                                        }
                                        KeyFuncPtr=KeyTab[iMenuID].CurrentOperate;//无子菜单则执行该菜单命令
                                    (*KeyFuncPtr)();   //执行当前按键的操作
                                        //TranDataBy232(key);OpeningBeep(1);
                                        break;
                        case        KEY_UP:
                                        if(KeyTab[iMenuNextID].KeyTab_PressUp!=99)//&&(iMenuNextID!=99))
                                                {//当前高亮显示菜单还有兄菜单
                                                //KeyTab[iMenuID].KeyTab_PressOk=KeyTab[iMenuNextID].KeyTab_PressUp;
                                                iMenuNextID=KeyTab[iMenuNextID].KeyTab_PressUp;
                                                //TranDataBy232(iMenuID);
                                                //TranDataBy232(iMenuNextID);
                                                JudgeHLight();
                                                }
                                        break;
                        case        KEY_DOWN:
                                        if(KeyTab[iMenuNextID].KeyTab_PressDown!=99)//&&(iMenuNextID!=99))
                                                { //当前高亮显示菜单还有弟菜单
                                                iMenuNextID=KeyTab[iMenuNextID].KeyTab_PressDown;
                                                //TranDataBy232(iMenuID);
                                                //TranDataBy232(iMenuNextID);
                                                JudgeHLight();
                                                }
                                        break;
                        case        KEY_ESC:
                                        if(KeyTab[iMenuID].KeyTab_PressEsc!=99)
                                                { //菜单还没到顶,还有父菜单
                                                iMenuNextID=iMenuID;//YSM:从iMenuID取回进入父菜单的高亮显示菜单的ID
                                                iMenuID=KeyTab[iMenuID].KeyTab_PressEsc;//将父菜单的索引号作为当前索引号
                                                //iMenuNextID=KeyTab[iMenuID].KeyTab_PressOk;
                                                JudgeHLight();        //显示父菜单
                                                //TranDataBy232(iMenuID);
                                        //        TranDataBy232(iMenuNextID);
                                                KeyFuncPtr=KeyTab[iMenuID].CurrentOperate;
                                            (*KeyFuncPtr)();    //执行当前按键的操作
                                                }
                                        break;
                        default:
                                        break;
                }                 
                }
}
void Timer0init(void)
{
        TR0 = 0; //关闭定时器0
        TH0=0x4B; //200ms@(11.0592/4=2.7648)Mhz  12/11.0592=1.085*4=4.34us          65536-46083=19453=0x4BFD
        TL0=0xFD;
}
void Timer0_int(void) interrupt 1 using 1
{        
        TH0=0x4B; //200ms@11.0592Mhz  12/11.0592=1.085us          65535-4608=56319=0xEDFF
        TL0=0xFD;
        TimeCnt--;        
        if(TimeCnt==0)
                {
                        TimeFlag=1;        TR0=0;TH0=0x4B;TL0=0xFD;
                        TimeCnt=TimeCounter;
                }
}
void Timer1init(void)
{
        TR1 = 0; //关闭定时器0
        TH1=0; //284ms@(11.0592/4=2.7648)Mhz  12/11.0592=1.085*4=4.34us          65536*4.34=284 426us=284ms
        TL1=0;
}
void Timer1_int(void) interrupt 3 using 3
{        
        TH0=0; //200ms@11.0592Mhz  12/11.0592=1.085us          65535-4608=56319=0xEDFF
        TL0=0;
        WDT_CONTR = 0x3E;//喂狗
}        
/**********************
----- 外部中断0  -----
/**********************/
void External0(void) interrupt 0 using 2
{
        CheckFlag=1;
        _nop_();
}

/**************************
------  外部中断1  -------
**************************/

//void External1(void) interrupt 2 using 3
//{

//   _nop_();
//}
/****************************************/
/*        一个字串的输出                        */
/****************************************/
void Putstr(uchar *puts,uchar i)
        {
                uchar j,X;
                for (j=0;j<i;j++)
                {
                X = puts[j];
                        if (X&0x80)
                                {
                                        Putcdot(X&0x7f);        //只保留低7位
                                }
                        else Putedot(X-0x20,0);                //ascii码表从0x20开始
                }
        }

/****************************************/
/*   半角字符点阵码数据输出                */
//DispAttrib=0:nomal;=1反显
/****************************************/
void Putedot(uchar Order,bit DispAttrib)
        {
        uchar i,bakerx,bakery;        //共定义4个局部变量                        
        int x;                        //偏移量,字符量少的可以定义为uchar        
        bakerx = col;                //暂存x,y坐标,已备下半个字符使用        
        bakery = row;
        x=Order * 0x10;                //半角字符,每个字符16字节        
//上半个字符输出,8列        
        for(i=0;i<8;i++)
                {
                cbyte = Ezk[x];
                if(DispAttrib)                                //取点阵码,rom数组        
                        {Wrdata(~cbyte);}
                else
                        {Wrdata(cbyte);}                                //写输出一字节               
                x++;
                col++;
                if (col==LCMLIMIT){col=0;row++;row++;};        //下一列,如果列越界换行
                        if (row>7) row=0;                //如果行越界,返回首行        
                }                                        //上半个字符输出结束        

        col = bakerx;                                        //列对齐               
        row = bakery+1;                                        //指向下半个字符行        
//下半个字符输出,8列        
        for(i=0;i<8;i++)
                {
                cbyte = Ezk[x];                                //取点阵码               
                if(DispAttrib)                                //取点阵码,rom数组        
                        {Wrdata(~cbyte);}
                else
                        {Wrdata(cbyte);}                                //写输出一字节               
                x++;
                col++;
                if (col==LCMLIMIT){col=0;row=row+2;};        //下一列,如果列越界换行
                        if (row>7) row=1;                //如果行越界,返回首行        //
                }                                        //下半个字符输出结束        
        row=bakery;
        }                                                //整个字符输出结束        


/****************************************/
/*  全角字符点阵码数据输出                */
/****************************************/
void Putcdot(uchar Order)
        {
        uchar i,bakerx,bakery;                //共定义3个局部变量               
        int x;                                //偏移量,字符量少的可以定义为uchar        
        bakerx = col;                        //暂存x,y坐标,已备下半个字符使用        
        bakery = row;
        x=Order * 0x20;                        //每个字符32字节        
        
//上半个字符输出,16列        
        for(i=0;i<16;i++)
                {
                if(Hzflag)
                        Wrdata(Hzk1[x]);                                //写输出一字节               
                else
                        Wrdata(Hzk2[x]);
                x++;
                col++;
                if (col==LCMLIMIT){ col=0;row++;row++;}        //下一列,如果列越界换行
                        if (row>6) row=0;                //如果行越界,返回首行        
                }                                        //上半个字符输出结束        
               
//下半个字符输出,16列        
        col = bakerx;
        row = bakery+1;
        for(i=0;i<16;i++)                                //下半部分
                {
                if(Hzflag)
                        Wrdata(Hzk1[x]);                                //写输出一字节               
                else
                        Wrdata(Hzk2[x]);
                x++;
                col++;
                if (col==LCMLIMIT){col=0;row++;row++;}        //下一列,如果列越界换行
                        if (row>7) row=1;                //如果行越界,返回首行        
                }                                        //下半个字符输出结束        
        row = bakery;
        }                                            &
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。