原创 C语言菜单设计

2008-5-26 20:51 7020 6 8 分类: MCU/ 嵌入式

const unsigned char menu0_1[] FLASH={"1.自动操作"};
const unsigned char menu0_2[] FLASH={"2.手动操作"};
const unsigned char menu0_3[] FLASH={"3.系统设置"};


const unsigned char menu1[]  FLASH={"1.密码设置"};
const unsigned char menu2[]  FLASH={"2.车位设置"};
const unsigned char menu3[]  FLASH={"3.PLC选择"};
const unsigned char menu4[]  FLASH={"4.卡号设置"};
const unsigned char menu5[]  FLASH={"5.站号设置"};


const unsigned char menu6[]  FLASH={"1.系统密码设置"};
const unsigned char menu7[]  FLASH={"2.自动密码设置"};
const unsigned char menu8[]  FLASH={"3.手动密码设置"};
const unsigned char menu9[]  FLASH={"1.增加车位号码"};
const unsigned char menu10[] FLASH={"2.已设置号码数量"};
const unsigned char menu11[] FLASH={"1.增加卡片"};
const unsigned char menu12[] FLASH={"2.感应删除卡片"};
const unsigned char menu13[] FLASH={"3.手动删除卡片"};
const unsigned char menu14[] FLASH={"4.统计卡片数量"};


const unsigned char menu15[]  FLASH={"6.运行次数统计"};
#define  MAX_KEYTABSTRUCT_NUM 18
#define MENU_AUTOMIMA     1
#define MENU_SHOUMIMA      2


#define MENU_SYSTEMMIMA    3
#define MENU_MIMA       4
#define MENU_MIMA_SITONG      5
#define MENU_MIMA_ZHIDONG    6
#define MENU_MIMA_SHOUDONG     7


#define MENU_CHEWEI      8
#define MENU_CHEWEI_ADD    9
#define MENU_CHEWEI_CHAKAN     10


#define MENU_PLCSEL      11


#define MENU_KAHAO      12
#define MENU_KAHAO_ADD    13
#define MENU_KAHAO_GANYINDELL   14
#define MENU_KAHAO_SHOUDONGDELL   15
#define MENU_KAHAO_CHAKAN   16


#define MENU_ZHANHAO     17


#define MENU_GONUM      18
typedef struct
{
 uchar MenuID;      //本菜单状态索引号
 uchar ParMenuID;    //父菜单状态索引号
 const uchar *MenuName;  //菜单文本内容
 void (*CurrentOperate)(void); //本菜单的功能函数
}KeyTabStruct;
//菜单表,
const KeyTabStruct KeyTab[MAX_KEYTABSTRUCT_NUM] FLASH=
 {
// 菜单ID       父菜单ID  菜单名     菜单功能函数
// MenuID,              ParMenuID,     MenuName,      CurFunction
 {MENU_AUTOMIMA, 0, menu0_1, autodo_ex},
 {MENU_SHOUMIMA, 0, menu0_2, shoudo_ex},
 {MENU_SYSTEMMIMA, 0, menu0_3, NULL},
    {MENU_MIMA,    MENU_SYSTEMMIMA,   menu1,  NULL},
 {MENU_MIMA_SITONG,  MENU_MIMA,      menu6,  set_system_mima},
 {MENU_MIMA_ZHIDONG, MENU_MIMA,  menu7,  set_zhidong_mima},
 {MENU_MIMA_SHOUDONG,MENU_MIMA,  menu8,      set_shoudong_mima},
 {MENU_CHEWEI,      MENU_SYSTEMMIMA,   menu2,      NULL},
 {MENU_CHEWEI_ADD,   MENU_CHEWEI,    menu9,  add_chewei},
 {MENU_CHEWEI_CHAKAN,MENU_CHEWEI, menu10,  chakan_chehao_num},
 {MENU_PLCSEL,   MENU_SYSTEMMIMA,   menu3,      select_plc},
 {MENU_KAHAO,   MENU_SYSTEMMIMA,   menu4,      NULL},
 {MENU_KAHAO_ADD, MENU_KAHAO,  menu11,  add_mifare_menu},
 {MENU_KAHAO_GANYINDELL,MENU_KAHAO, menu12,  auto_del_mifare_menu},
 {MENU_KAHAO_SHOUDONGDELL,MENU_KAHAO,menu13,  shou_del_mifare_menu},
 {MENU_KAHAO_CHAKAN, MENU_KAHAO,  menu14,  count_mifare_menu},
 {MENU_ZHANHAO,   MENU_SYSTEMMIMA,   menu5,  select_zaihao},
 {MENU_GONUM,   MENU_SYSTEMMIMA,   menu15,  show_gonum}
 };


typedef struct
{
 unsigned char IndexMenuID[10];//本级菜单的菜单项的索引号的数组
 char FocusMenuId; //为本级菜单的焦点
 char FocusLine;  //本焦点在屏上是第几项
 char StartLine;  //屏上的第一项菜单在IndexMenuID[10]上的索引值
}view_menu;
view_menu viewmenu;
//本函数得到本级菜单的当前菜单项与下个菜单项索引号的增量
//参数keyTabIndex:本级菜单的当前菜单的索引号
//返回参数:0:当前菜单项为本级菜单的最后一个菜单项,>0:表示下一个菜单项索引号与本级菜单项索引号的差值
uchar get_next(uchar keyTabIndex)
{
 uchar nextKeyTabIndex="keyTabIndex"+1;
 while((nextKeyTabIndex<=MAX_KEYTABSTRUCT_NUM)&&(pgm_read_byte(&KeyTab[nextKeyTabIndex].ParMenuID)>pgm_read_byte(&KeyTab[keyTabIndex].ParMenuID)))
 {
  nextKeyTabIndex++;
 }
 if (pgm_read_byte(&KeyTab[nextKeyTabIndex].ParMenuID)== pgm_read_byte(&KeyTab[keyTabIndex].ParMenuID))
 {
  return nextKeyTabIndex - keyTabIndex;
 }
 return 0;
}
//本函数得到本级菜单的当前菜单项与上一个菜单项索引号的差值
//参数keyTabIndex:本级菜单的当前菜单的索引号
//返回参数:0:当前菜单项为本级菜单的第一个菜单项,>0:表示上一个菜单项索引号与本级菜单项索引号的差值
uchar get_prev(uchar KeyTabIndex)
{
 uchar prevKeyTabIndex ;
 if(KeyTabIndex==0)
  return 0;
 prevKeyTabIndex= KeyTabIndex - 1; 
 while ((prevKeyTabIndex > 0)&&(pgm_read_byte(&KeyTab[prevKeyTabIndex].ParMenuID) > pgm_read_byte(&KeyTab[KeyTabIndex].ParMenuID)))
 {
  prevKeyTabIndex--;
 }
 if (pgm_read_byte(&KeyTab[prevKeyTabIndex].ParMenuID)== pgm_read_byte(&KeyTab[KeyTabIndex].ParMenuID))
 {
  return KeyTabIndex - prevKeyTabIndex;
 }
 return 0;
}
//得本级菜单的菜单项索引号数组IndexMenuID[10]
//参数KeyTabIndex:为本级菜单的父菜单ID,
//返回本级菜单的菜单项个数.
char SetViewMenu(uchar KeyTabIndex,view_menu *ViewMenu)
{
 uchar i = 0 ;
 uchar tmpKeyTabIndex;
 char result = 1;
 tmpKeyTabIndex = KeyTabIndex - get_prev(KeyTabIndex);
 while (tmpKeyTabIndex < KeyTabIndex)
 {
  KeyTabIndex = tmpKeyTabIndex;
  tmpKeyTabIndex = KeyTabIndex - get_prev(KeyTabIndex);
  result++;
 }
 tmpKeyTabIndex = KeyTabIndex + get_next(KeyTabIndex);
 //ViewMenu->IndexMenuID[i++] = pgm_read_byte(&KeyTab[KeyTabIndex].MenuID);
 ViewMenu->IndexMenuID[i++] = KeyTabIndex+1;
 while (tmpKeyTabIndex > KeyTabIndex)
 {
  KeyTabIndex = tmpKeyTabIndex;
  //ViewMenu->IndexMenuID[i++] = KeyTab[KeyTabIndex].MenuID;
  ViewMenu->IndexMenuID[i++] = KeyTabIndex+1;
  tmpKeyTabIndex = KeyTabIndex + get_next(KeyTabIndex);
 }
 ViewMenu->IndexMenuID = '\0';


 return result;
}
/*
for(line=ViewMenu->StartLine;((ViewMenu->IndexMenuID[line-1]!='\0')&& (line-ViewMenu->StartLine+1<=LCD_CH_LINE));line++)
 {
  if(ViewMenu->FocusLine==line)
   Print_flash_str(LCD_MENU_START, line-ViewMenu->StartLine+1, (unsigned char *)KeyTab[ViewMenu->IndexMenuID[line-1]-1].MenuName,0);
  else
   Print_flash_str(LCD_MENU_START, line-ViewMenu->StartLine+1, (unsigned char *)KeyTab[ViewMenu->IndexMenuID[line-1]-1].MenuName,1);
 }
*/
//显示当前菜单
void PrintViewMenuWindow(view_menu *ViewMenu)
{
 unsigned char line;
 print_blank();
 for(line=ViewMenu->StartLine;((ViewMenu->IndexMenuID[line-1]!='\0')&& ((line-ViewMenu->StartLine)+1<=LCD_CH_LINE));line++)
 //for(line=0;((ViewMenu->IndexMenuID[ViewMenu->StartLine+line-1]!='\0')&&(line {
  if((ViewMenu->FocusLine-1)==(line-ViewMenu->StartLine))
   Print_flash_str(LCD_MENU_START, (line-ViewMenu->StartLine)*2, (unsigned char *)pgm_read_word(&KeyTab[ViewMenu->IndexMenuID[line-1]-


1].MenuName),0);
  else
   Print_flash_str(LCD_MENU_START, (line-ViewMenu->StartLine)*2, (unsigned char *)pgm_read_word(&KeyTab[ViewMenu->IndexMenuID[line-1]-


1].MenuName),1);
 }  
}
//菜单主函数基于AVRX操作系统
void menu_ex(void)
{
 //pdataMessage pMsg;
 KeyTabStruct tempkeytab;
 viewmenu.FocusMenuId=MENU_AUTOMIMA;
 viewmenu.StartLine=1;
 viewmenu.FocusLine=1;
 SetViewMenu(viewmenu.FocusMenuId-1, &viewmenu); 
 menufreetime=0;
 while(1)
 {
  //SetViewMenu(viewmenu.FocusMenuId-1, &viewmenu);
  PrintViewMenuWindow(&viewmenu);
  AvrXStartTimerMessage(&freetimer, 6000, &MyQueue);//进入
   pMsg = (pdataMessage)AvrXWaitMessage(&MyQueue);
   if(pMsg==&keymessage)
   {
     AvrXAckMessage(&pMsg->mcb);
    if(AvrXCancelTimerMessage(&freetimer, &MyQueue) != &freetimer.u.mcb)
     AvrXHalt();
    switch(*((uchar *)pMsg->data))
    {
     case KEYUP:
      if(viewmenu.FocusLine==1)
      {
       if(viewmenu.StartLine>1)
        viewmenu.StartLine--;
       else
       {
        if(strlen(viewmenu.IndexMenuID)<=LCD_CH_LINE)
        {
         viewmenu.FocusLine=strlen(viewmenu.IndexMenuID);
         viewmenu.StartLine=1;
        }
        else
        {
         viewmenu.FocusLine=LCD_CH_LINE ;
         viewmenu.StartLine=strlen(viewmenu.IndexMenuID)-LCD_CH_LINE+1;
        }
       }        
      }
      else
      {
       viewmenu.FocusLine--;
      } 
      //PrintViewMenuWindow(&viewmenu);
      break;
     case KEYDOWN://KEYDOWN:
      if(viewmenu.FocusLine      {
       if((viewmenu.StartLine+viewmenu.FocusLine)       {
        viewmenu.FocusLine++;
        //PrintViewMenuWindow(&viewmenu);
       }
       else
       {
        if(strlen(viewmenu.IndexMenuID)==2)
         viewmenu.FocusLine++;
        else
        {
         viewmenu.StartLine=1;
         viewmenu.FocusLine=1;
        }
       }
      }
      else
      {
       viewmenu.FocusLine=LCD_CH_LINE; 
       if((viewmenu.StartLine+viewmenu.FocusLine)<=strlen(viewmenu.IndexMenuID))
       {
        viewmenu.StartLine++;
       }
       else
       {
        viewmenu.FocusLine=1;
        viewmenu.StartLine=1;      
       }
      }
      //PrintViewMenuWindow(&viewmenu);
      break;
      
     case KEYOK:
      memcpy_P((uchar *)&tempkeytab,(uchar *)&KeyTab[viewmenu.IndexMenuID[viewmenu.StartLine+viewmenu.FocusLine-2]


-1],sizeof(KeyTabStruct));
      if(tempkeytab.CurrentOperate!=NULL)
      {
       
       tempkeytab.CurrentOperate();
       if(menufreetime>MENUFREETIME)
        {
         return ;
        }
      }
      else
      {
       if(tempkeytab.MenuID==MENU_SYSTEMMIMA)
       {
        if(!check_mima(SYSTEMMIMA))
         break;
        
       }
       if(viewmenu.FocusMenuId       {
        if(pgm_read_byte((uchar *)&KeyTab[viewmenu.IndexMenuID[viewmenu.StartLine+viewmenu.FocusLine


-2]].ParMenuID)
        ==pgm_read_byte((uchar *)&KeyTab[viewmenu.IndexMenuID[viewmenu.StartLine+viewmenu.FocusLine-


2]-1].MenuID))
        {
         viewmenu.FocusMenuId=pgm_read_byte((uchar *)&KeyTab[viewmenu.IndexMenuID


[viewmenu.StartLine+viewmenu.FocusLine-2]].MenuID);
         viewmenu.StartLine=1;
         viewmenu.FocusLine=1;
         SetViewMenu(viewmenu.FocusMenuId-1, &viewmenu);
        }
       }     
      }
      //PrintViewMenuWindow(&viewmenu);
      break;
     case KEYCONSEL://KEYCONSEL:
      memcpy_P((uchar *)&tempkeytab,(uchar *)&KeyTab[viewmenu.IndexMenuID[viewmenu.StartLine+viewmenu.FocusLine-2]


-1],sizeof(KeyTabStruct));
      if(tempkeytab.ParMenuID==0)
       return;
      viewmenu.FocusMenuId=tempkeytab.ParMenuID;
      viewmenu.StartLine=1;
      viewmenu.FocusLine=1;
      SetViewMenu(viewmenu.FocusMenuId-1, &viewmenu);
      //PrintViewMenuWindow(&viewmenu);
     default:
      break;
    }
    menufreetime=0; 
    
   }
   else if(pMsg==&plcmessage)
   {
    //PLC发送的信息
    AvrXAckMessage(&pMsg->mcb);
   if(AvrXCancelTimerMessage(&freetimer, &MyQueue) != &freetimer.u.mcb)
    AvrXHalt();
   }
   else if(pMsg==&mfacemessage)
   {
    //读卡器发送的信息
    AvrXAckMessage(&pMsg->mcb);
    if(AvrXCancelTimerMessage(&freetimer, &MyQueue) != &freetimer.u.mcb)
    AvrXHalt();
   }
   else if((pTimerMessageBlock)pMsg == &freetimer)
   {
    //睡眠时间到,进入跑马灯显示状态
    if(++menufreetime>MENUFREETIME)
    {
     return ;
    }
   }
   else
         {
              AvrXHalt();
         }
 }
}

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

xucun915_925777961 2009-2-27 13:23

真是高手,俺学习学习……

用户1095637 2008-6-10 12:50

正要用這個,先謝過了
相关推荐阅读
用户136065 2012-05-29 16:46
立体车库操作盒(内有本项目的源代码,电路图)
https://static.assets-stash.eet-china.com/album/old-resources/2009/2/26/8ba54db8-208e-4ab8-850e-b7...
用户136065 2008-12-17 13:50
STM32 protel 封装(不断更新中)
STM32 Protel 封装只画了三个封装(LQFP48,LQFP64,LQFP100)https://static.assets-stash.eet-china.com/album/old-res...
用户136065 2008-11-03 16:54
最新发现与创新:科学家证实电子电路存在记忆电阻
 美国科学家日前宣布,他们已证实电子电路存在第四种基本元件———记忆电阻(简称忆阻),并成功设计出一个能工作的忆阻实物模型。   早在1971年,非线性电路理论先驱、美国加利福尼亚大学伯克利分校的华裔...
用户136065 2008-11-03 12:06
国内主要网络电台地址
mms://211.89.225.101/live3 中央电台音乐频道      收听mms://vl.sina.com.cn/popmusic 东广音乐台动感101mms://vstream.sin...
用户136065 2008-11-03 11:47
W5100集TCP/IP协议栈、以太网MAC和PHY为一体
W5100是WIZnet公司最新推出的固件网络芯片,它是在W3150A+的基础上,集成了以太网物理层RTL8201CP核,因此W5100集TCP/IP协议栈、以太网MAC和PHY为一体。W5100支持...
用户136065 2008-10-20 11:22
iccavr用户手册(中文)
https://static.assets-stash.eet-china.com/album/old-resources/2008/10/20/370fcf86-59d6-46f9-a7e5-e01...
EE直播间
更多
我要评论
2
6
关闭 站长推荐上一条 /3 下一条