keil c语言

2020-02-04 09:32发布

怎么实现多功能按键?即在按下设置键后,再按键进行相关配置,最后按确定键确定刚才的设置,请问这个程序怎样写?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
12条回答
hepday
2020-02-04 20:07
#ifndef                _MENU_H_
#define     _MENU_H_                 

#include"AT89X52.h"
#include"LCD1602.h"

#define KEY_NULL         0x00
#define KEY_ESC                0x01
#define KEY_SET                0x08
#define KEY_UP                0x02
#define KEY_DOWN        0x04

///-----------------------------------------------
//          LCD相关定义
///-----------------------------------------------
#define         LCD_MAX_DISP_LINES        (2)


///--------------------------------------------------------------------
//  MENU相关定义
///--------------------------------------------------------------------
#define IS_ROOTMENU                        0xFF
#define NOT_ROOTMENU                0x00
//菜单类型:正常菜单,选项型菜单(返回一数值),显示信息型菜单(显示一定信息)
#define MENUTYPE_NORMAL                0x01
#define MENUTYPE_OPTION                0x02
#define MENUTYPE_DISP                0x03

//--------------------------------------------------------------------*
//  目录结构体定义
//---------------------------------------------------------------------*/
struct  MenuItem                                                //typedef
{
        char         CurLevelMenuMaximum;                //本级菜单的最大个数
        char         *DisplayString;                                //菜单条显示内容
        void         (*CurrentOperator)();                //该菜单需要的操作函数指针
        struct         MenuItem *ChildrenMenus;        //子菜单指针
        struct         MenuItem *ParentMenus;                //父菜单指针
        unsigned char         MenuType;                                //菜单类型:正常菜单,选项型菜单(返回一数值),显示信息型菜单(显示一定信息)
        unsigned char   *ReturnParameter;        //返回参数
}        Null;

unsigned char Para = 3;

void         NullOperator(void)
{                                                }

//--------------------------------------------------------------------*
//  菜单数组声明
//---------------------------------------------------------------------*/
struct         MenuItem RootMenu[4];
struct         MenuItem RunState[3];
struct         MenuItem SetTime[1];
struct         MenuItem SetDateTime[1];

//--------------------------------------------------------------------*
// 全局变量定义声明区*
//---------------------------------------------------------------------*/
struct         MenuItem (*MenuPoint) = RootMenu;
char         DisplayStart = 0;
char         UserChoose = 0;
char         DisplayPoint = 0;
char         MaxItems;
unsigned         char NullParameter = 0;
unsigned         char Option = 0;


//--------------------------------------------------------------------*
//        char CurLevelMenuMaximum;                //本级菜单的最大个数
//        char *DisplayString;                        //菜单条显示内容
//        void (*CurrentOperator)();                //该菜单需要的操作函数指针
//        struct MenuItem *ChildrenMenus;        //子菜单指针
//        struct MenuItem *ParentMenus;        //父菜单指针
//---------------------------------------------------------------------*/
const unsigned char RootMenu_RunState[] = {"  1.OpenSystem "};
const unsigned char RootMenu_SetTime [] = {"  2.SetPasword "};
const unsigned char RootMenu_DataOper[] = {"  3.DataOper   "};
const unsigned char RootMenu_SysInfo [] = {"  4.SysInfo    "};

struct MenuItem xdata RootMenu[4]=        //根目录菜单
{
        {4,RootMenu_RunState,NullOperator ,RunState,&Null,MENUTYPE_NORMAL,&NullParameter},
        {4,RootMenu_SetTime ,NullOperator ,SetTime ,&Null,MENUTYPE_NORMAL,&NullParameter},//SetDateTime
        {4,RootMenu_DataOper,NullOperator ,&Null   ,&Null,MENUTYPE_NORMAL,&NullParameter},//
        {4,RootMenu_SysInfo ,NullOperator ,&Null   ,&Null,MENUTYPE_NORMAL,&NullParameter},
};

const unsigned char RunState0[] = {"  2400          "};
const unsigned char RunState1[] = {"  4800          "};
const unsigned char RunState2[] = {"  9600          "};

struct MenuItem xdata RunState[3]=        //1级目录菜单A
{
        {3,RunState0,NullOperator,&Null,RootMenu,MENUTYPE_OPTION,&Para},
        {3,RunState1,NullOperator,&Null,RootMenu,MENUTYPE_OPTION,&Para},
        {3,RunState2,NullOperator,&Null,RootMenu,MENUTYPE_OPTION,&Para},
};

const unsigned char SetTime0[]  = {"  Test          "};
struct MenuItem xdata SetTime[1]=        //2级目录菜单A
{
        {1,SetTime0,NullOperator,&Null,RootMenu ,MENUTYPE_DISP,&NullParameter},
};

//--------------------------------------------------------------------*
// 函数声明区*
//---------------------------------------------------------------------*/
void sHOWMENU(void);
void KeyProcess_MenuUpdate(unsigned char KeyNum);

//------------------------------------------------------------------*
// 函数说明:目录显示函数*
//------------------------------------------------------------------*/
void        sHOWMENU(void)
{                char StrTemp[17];
                unsigned char i = 0x00;
                bit M;
                MaxItems     = MenuPoint[0].CurLevelMenuMaximum;
                DisplayPoint = DisplayStart;

                if (MaxItems >= 2)
                        {        for (i = 0;i < LCD_MAX_DISP_LINES;i++)
                                        {        WrintStringFor_LCD1602(i,0,MenuPoint[DisplayPoint].DisplayString);
                                                if (MenuPoint[DisplayPoint].MenuType != MENUTYPE_DISP)       
                                                        {        if ((DisplayPoint) == UserChoose)
                                                                        {Set_LCD1602(0,i,0x7e);}
                                                                else
                                                                        {Set_LCD1602(0,i,' ');}
                                                                WrintStringFor_LCD1602(1,i,StrTemp);
                                                        }
                                                else{        WrintStringFor_LCD1602(0,i,StrTemp);}
                                                DisplayPoint += 1;
                                                if ((DisplayPoint) == (MaxItems))
                                                {
                                                                DisplayPoint = 0;
                                                }       
                                        }
                        }
                else{        for (i = 0; i < MaxItems;i++)
                                        {        WrintStringFor_LCD1602(i,0,MenuPoint[DisplayPoint].DisplayString);
                                                if (MenuPoint[DisplayPoint].MenuType != MENUTYPE_DISP)
                                                {        if ((DisplayPoint) == UserChoose)
                                                                {        Set_LCD1602(0,i,0x7e);        }
                                                        else{   Set_LCD1602(0,i, ' ');  }
                                                        WrintStringFor_LCD1602(1,i,StrTemp);
                                                }
                                                else        {   WrintStringFor_LCD1602(0,i,StrTemp);}
                                                DisplayPoint += 1;
                                                if ((DisplayPoint) == (MaxItems))
                                                                {        DisplayPoint = 0;                }
                                        }
                                //-----------------------------------------------------------------------/
                                //TODO:当该级菜单数<LCD能显示的行数,有些行需要显示空白
                                for (i= MaxItems;i < LCD_MAX_DISP_LINES;i++)
                                {
                                                WrintStringFor_LCD1602(0, i, "                ");
                                }
                                //-----------------------------------------------------------------------*/
                        }
}

//--------------------------------------------------
// [按键说明] *
// ----------------------------------- *
// [K1] KEY_UP(向上) *
// [K5] KEY_DOWN(向下) *
// [K2] KEY_ENTER(确定) *
// [K6] KEY_ESC(后退) *
//---------------------------------------------------/
void         KeyProcess_MenuUpdate(unsigned char KeyNum)
{                if (KeyNum != KEY_NULL)
                {        switch (KeyNum)
                        {        case KEY_UP:
                                         UserChoose --;
                                         if (UserChoose < 0)
                                                 {        UserChoose = MaxItems - 1;}
                                         Option --;
                                         if (Option >= MenuPoint[0].CurLevelMenuMaximum)
                                                 {        Option = MenuPoint[0].CurLevelMenuMaximum - 1;}
                                         break;
                                case KEY_ESC:
                                         if (MenuPoint[0].ParentMenus != &Null)
                                                 {        MenuPoint    = MenuPoint[0].ParentMenus;
                                                         UserChoose   = 0;
                                                        DisplayPoint = *MenuPoint[0].ReturnParameter;
                                                 }
                                         break;
                                case KEY_DOWN:
                                         UserChoose ++;
                                         if (UserChoose == MaxItems)
                                                 {        UserChoose = 0;        }
                                         Option++;
                                         if (Option >= MenuPoint[0].CurLevelMenuMaximum)
                                                 {        Option = 0;                }
                                         break;
                                case KEY_SET:
                                         if (MenuPoint[UserChoose].CurrentOperator != NullOperator)
                                                 { (*MenuPoint[UserChoose].CurrentOperator)(); }
                                         //如果菜单类型不是“正常型MENUTYPE_NORMAL”,则按KEY_SET键返回上一级菜单
                                         if ( MenuPoint[DisplayPoint].MenuType != MENUTYPE_NORMAL )
                                                {        if (MenuPoint[UserChoose].ParentMenus != &Null)                //如果操作函数不为空并且子菜单不为空,则进行菜单切换
                                                                {   * MenuPoint[0].ReturnParameter = Option;        //保存选择参数
                                                                        MenuPoint = MenuPoint[UserChoose].ParentMenus;
                                                                        UserChoose = 0;
                                                                        DisplayStart = 0;
                                                                }
                                         }
                                         else
                                                 {        if (MenuPoint[UserChoose].ChildrenMenus != &Null)        //如果操作函数不为空并且子菜单不为空,则进行菜单切换
                                                                {        MenuPoint = MenuPoint[UserChoose].ChildrenMenus;
                                                                        UserChoose        = * MenuPoint[0].ReturnParameter;
                                                                        DisplayStart = UserChoose;
                                                                        Option = UserChoose;
                                                                }
                                                }
                                        break;
                        }
                        if ((UserChoose < DisplayStart) || (UserChoose > (DisplayStart+(LCD_MAX_DISP_LINES-1))))
                                {        DisplayStart = UserChoose;                } //菜单翻页
                        sHOWMENU();
                }       
}

#endif
嘿嘿这是论坛里大神的,我正在学,表示很多看不懂

一周热门 更多>