液晶多级菜单实现加强版

admin 2017-5-25 2163


最近有位兄台写了篇 单片机C语言下LCD多级菜单的一种实现方法
大致如下

typedef struct
{
 uchar  KeyStateIndex ;   / / 当前状态索引号
 uchar  KeyDnState ;   / / 按下“向下”键时转向的状态索引号
 uchar  KeyUpState ;   / / 按下“向上”键时转向的状态索引号
 uchar  KeyCrState ;   / / 按下“回车”键时转向的状态索引号
 uchar  KeyBackState ;   / / 按下“退回”键时转向的状态索引号
 void   (*CurrentOperate)( ) ;   / / 当前状态应该执行的功能操作
}  KbdTabSt ruct ;
# define SIZE - OF KEYBD - MENU 55   / / 菜单总长度
KbdTabSt ruct code KeyTab[ SIZE - OF - KEYBD - MENU ] =
{
 {0 ,0 ,0 ,1 ,0 , MainJob1 } ,
 {1 ,7 ,2 ,8 ,0 , Dsp Point} ,   / / 第一层
 {2 ,1 ,3 ,8 ,0 , DspCurve},   / / 第一层
 {3 ,2 ,4 ,36 ,0 ,Dsp Kout} ,   / / 第一层
 {4 ,3 ,5 ,50 ,0 , DisCloseDown } ,   / / 第一层
 {5 ,4 ,6 ,8 ,0 ,  ModifyPoint} ,   / / 第一层
 {6 ,5 ,7 ,52 ,0 , SetCloseDown } ,   / / 第一层
 {7 ,6 ,1 ,0 ,0 , Cancel} ,   / / 第一层
 …
 …
 {52 ,53 ,53 ,0 ,1 ,  OkSetCloseDown1} ,
 {53 ,52 ,52 ,0 ,1 , OkSetCloseDown2} ,
 {54 ,0 ,0 ,0 ,0 , Disable} ,
  …
  …
} ;
 void Get Keylnput (void)
{
 switch ( status &0xf0)
  {
  case 0xe0 :/ / 回车键,找出新的菜单状态编号
   …
        KeyFuncIndex = KeyTab[ KeyFuncIndex ] . KeyCrState ;
   …
   break ;
  case 0xb0 :/ / 向下键,找出新的菜单状态编号
   …
    KeyFuncIndex = KeyTab [ KeyFuncIndex ] . KeyDn2State ;
   …
  break ;
   case 0xd0 :/ / 向上键,找出新的菜单状态编号
   …
    KeyFuncIndex = KeyTab [ KeyFuncIndex ] . KeyUp2State ;
   …
   break ;
  case 0x70 :/ / 回退键,找出新的菜单状态编号
   …
    KeyFuncIndex = KeyTab [ KeyFuncIndex ] . KeyBack2State ;
   …
   break ;
  case 0 ;
    return ;   / / 错误的处理
    break ;
   }
  KeyFuncPt r = KeyTab[ KeyFuncIndex ] . CurrentOperate ;
  ( * KeyFuncPt r) () ;   / / 执行当前按键的操作
}

但是如果采用触摸屏,并且有多个界面需要切换,那么这种结构就大打折扣。
我要设计的界面是基于这个结构体的:

typedef struct _window_d{
    void (*draw)();//每个界面的画界面函数
    TKEY (*key_map)(unsigned int x, unsigned int y);//每个界面的所有按键(触摸按键)
    void (*key_process)(TKEY_EVENT *event);//每个界面的按键处理函数
}TBasicWindow;

下面是按键识别:

#define  UP     0   //按键弹起
#define  DOWN   1   //按键按下
typedef enum _key_enum_{
    KEY_NULL,
    MAIN_REVIEW,//第一个界面三个按键
    MAIN_PRINT,
    MAIN_SAVE,
    PATIENT_OK,//第二个界面三个按键
    PATIENT_BACK,
    PATIENT_NAME_ZONE,
    ..........
}TKEY;
typedef struct _key_{
    TKEY key;
    unsigned int TouchStatus;
}TKEY_EVENT;
void GetKey(TKEY_EVENT *event)
{
   unsigned int Y = 0;
   unsigned int X = 0;
   unsigned short c[3]={0};
   unsigned int TouchStatus = DOWN;
   get_coord(c);
   
   if(c[0] && !send)
   {
        X = c[1];
        Y = c[2];
        TouchStatus = DOWN;
   }
   
   if(!c[0])
   {
        X = c[1];
        Y =  c[2];
        TouchStatus = UP;
   }
   event->key = CurrentWin->key_map(X, Y);
   event->TouchStatus = TouchStatus;
}

写完上面的框架就是每个界面的函数了,我拿一个界面来说,其它都是这个框架:

TBasicWindow MainWin = {
        draw: MainDraw,
        key_map: MainKeyMap,
    key_process: MainKeyProcess,
};
void MainDraw(){
...
}
TKEY MainKeyMap(unsigned int x, unsigned int y)
{
    if((x > 95*0&& x <= 95*0) && (y > 685 && y < 790))   return MAIN_REVIEW;
    if((x > 95*1&& x <= 95*1) && (y > 685 && y < 790))   return MAIN_PRINT;
    if((x > 95*2&& x <= 95*2) && (y > 685 && y < 790))   return MAIN_SAVE;
}
void MainKeyProcess(TKEY_EVENT *event)
{
    static TKEY PressKey = KEY_NULL;//记录第一次按下的按键
    
    switch(event->key){
        case MAIN_REVIEW:
             if(event->TouchStatus){//按键按下
                PressKey = MAIN_REVIEW;//记录第一次按下触摸屏的按键
                MainKeyDisplay(PressKey, DOWN);//按键按下
             }
             else{//按键弹起
                MainKeyDisplay(PressKey, UP);//弹起先前一次按下的按键,不一定是MAIN_PATIENT
                if(PressKey != MAIN_REVIEW) break;//两次按键不一致则不执行
                //begin (按下和弹起都是PATIENT,则执行PATIENT的按键处理)
                CurrentWin = &ManagementWin;
                CurrentWin->draw();
                //end
             }
             break;
        ...
}

其它的界面都是这样写的,然后主函数只要这样就行了:

TBasicWindow *CurrentWin = &MainWin;
void main(void)
{
        TKEY_EVENT event;
        while(1){
                GetKey(&event);
                       CurrentWin->key_process(&event);
        }
}

最后贴两张界面照片

最新回复 [2]
  • ChinaMobile 5月前
    0 2
    ui用什么做的
  • admin 5月前
    0 3
    ChinaMobile ui用什么做的
    作者是自己实现的UI
返回