|
发表于 2011-12-9 21:41:06
|
显示全部楼层
#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
嘿嘿这是论坛里大神的,我正在学,表示很多看不懂 |
|