铭正同创的笔记 https://bbs.21ic.com/?264857 [收藏] [复制] [RSS] http://www.mzdeisgn.com.cn    铭正同创专业液晶模块+工控产品技术服务!    淘宝店铺:http://shop35039656.taobao.com   

日志

基于MzLH06-128128液晶模块的菜单程序编程(3)

已有 1610 次阅读2009-3-4 10:42 |个人分类:LCD的GUI探讨|系统分类:单片机| LCD, 液晶模块, 菜单编程, 驱动, MzLH06, LCM






基于MzLH06液晶模块的菜单程序编写三





4参考的菜单响应控制结构代码
4.1键盘扫描服务程序简介
    在此,仅介绍本工程范例所使用的键盘的键值定义,不再对具体的键盘扫描程序进行详述,用户最好可以根据自己的需要以及自身使用的MCU及键盘连接的特点来做自己的键盘扫描服务程序;本工程范例当中的键盘扫描服务程序仅仅是一个简单的程序。
    在前面的硬件连接的介绍中,MCS51的P0.0~P0.3四个端口分别连接上四个按键:K1~K4;在程序中(感兴趣的可以参考Key_Service.c文件中的Key_Get ()函数)分别定义短按K1~K4键时返回1~4的键值,而当K1和K2键长按下时,分别返回5和6。
    而从菜单响应的功能上定义,在本工程当中,定义K1为控制菜单选择项向上,K2为控制菜单项向下,而K4为确定键,K3为返回键(在进入菜单子项响应函数后,短按或长按该键会重新返回菜单列表)。
    函数Key_Get()的部分代码如下所示:



4.2菜单响应控制结构详解
    为了方便使用,配合着MzMenu_GUI代码提供了一份参考的响应控制代码,用户可以参照它的架构编写自己需要的控制代码。
    首先,菜单响应控制代码需要定义几个变量,如下:



     上面定义的变量当中,有几个是用于暂存菜单组资源中的一些数据的,比如Item_Num、PageItem_Num等,其实在前面介绍的菜单显示控制的代码(Menu_GUI.c)当中已有定义了,这里再定义实际上是为多级菜单的使用而做的;因为在Menu_GUI.c当中定义的变量只能供当前选用的菜单组使用,如有多级菜单时,相互之间有层层的调用关系,单靠其中的变量是无法得知全部的菜单组资源的参数的。由此,建议每个菜单界面都应定义上述的变量,以供当前的菜单响应控制使用。
    Exit_flag变量为循环退出标识,将在菜单响应控制的循环当中控制着是否继续下去,该变量被设置为0时,表示要退出当前的菜单。当然,如用户的菜单只有一层,而且始终在使用该菜单的话,可以不使用这个变量,直接在菜单响应控制的循环当中用1替代它即可。


    菜单响应控制的参考代码如下:






Key_Initial();
LCD_Init();
SetBackLight(0);    //设置背光的亮度等级为0
ClrScreen();       //清屏
FontMode(0,1);

SetBackLightAuto(100);   //设置背光缓慢打开,至最亮
Item_Num = GetMLNum(Menu_List01);   //获取要显示的菜单的菜单项个数
PageItem_Num = GetMLiNum_Page(Menu_List01); //获取要显示的菜单的页数
Initial_Menu(Menu_List01);
while(1)
 {
  KeyScan_Service(); 
  uiKey = Key_Get();
  if(uiKey)
  {
   switch(uiKey)     //判断键值进行分支控制界面
   {
    case 4:    //确定键按下
     Enter_Flag=1;   //enter flag set
     break;
    case 3:    //down 向下键按下
     if(Active_Index<Item_Num) 
     {
      Active_Index++;
      if(Temp_Index<PageItem_Num-1) Temp_Index++;
      else if(First_Index<Item_Num) First_Index++;
      Update_Flag = 1;
     }
     break;
    case 1:    //up  向上键按下
     if(Active_Index>0)
     {
      Active_Index--;
      if(Temp_Index>0) Temp_Index--;
      else if(First_Index>0) First_Index--;
      Update_Flag = 1;
     }
     break;
   /* case 2:     //返回键按下
     Exit_flag = 0;//
     break;*/
    default:break;
   }
  } 
  if(Update_Flag)      //Update_Flag为1时刷新菜单
  {
   UpDate_Menu(First_Index,Active_Index,(unsigned char**)Menu_List01);
   Update_Flag=0;
  }
  if(Enter_Flag)      //有确定键按下时,则进入相应的功能函数
  {
   Enter_Flag = 0;
   switch(Active_Index)
   {
    case 0:      //这里定义了响应第一项菜单
       BaseTest();
     Redraw_Menu(First_Index,Active_Index,Menu_List01);
     Update_Flag = 1;
     break;
    case 1:      //这里定义了响应第二项菜单    
     BitmapTest();
     Redraw_Menu(First_Index,Active_Index,Menu_List01);
     Update_Flag = 1;
     break; 
    case 2:      //这里定义了响应第三项菜单
     EditTest();
     Redraw_Menu(First_Index,Active_Index,Menu_List01);
     Update_Flag = 1;
     break;
    case 3:      //这里定义了响应第四项菜单
     MessageScroll();
     Redraw_Menu(First_Index,Active_Index,Menu_List01);
     Update_Flag = 1;
     break; 
    case 4: break;    //如感兴趣可以自己加进去
    default:break;
  } 
 }
}


    Key_Initial()是键盘扫描程序初始化函数,用户可根据自己的键盘扫描程序来修改这块的代码,而如果在之前已经进行过键盘扫描的初始化,则此处没有必要再重新初始化;比如在一个二级的菜单响应控制代码当中,它是由上一级的菜单响应控制代码响应操作而进入的,这时就无需再初始化键盘了。
    LCD_Initil()函数的调用也如此,如果是在二级菜单的响应控制代码中的话,是无需进行第二次初始化的。
    接下来,调用Menu_GUI.c中的函数来初始化变量Item_Num和PageItem_Num的数值,注意,在调用相关的菜单GUI显示控制函数时,都要传递当前选择的菜单组资源到调用的函数当中的。有些编译器对数据的类型定义要求较严,这时在传递参数时需要对参数进行类型声明或强制转换。
    每一个菜单组资源在使用时,在该菜单组的响应控制代码当中都要对其进行初始化,也就是调用Initial_Menu函数。
    从前面的代码中可以看出,这份示例的菜单响应控制代码使用的菜单组资源是Menu_List01,它的定义在前面已经介绍过了。


    while(Exit_flag)定义了菜单响应控制的循环,标志变量Exit_flag决定着这个循环是否继续下去。
    Key_Get()函数可以获取到当前有效的按键值,当然,用户使用自己定义的键盘扫描程序时,应视自己的代码而定,反正只要能够获取到有效的按键值就可以了。获取的键值存放于uiKey变量当中;需要注意的是,在没有键按下时,获取键值的函数应返回0或其它的数值以区别有效的键值。
    在上面的代码当中,当有效的按键按下时,uiKey的值为非零,这时会进行一个Switch的分支判断,以响应不同的按键。在代码当中,定义了uiKey的键值为1、2、3时的按键含意,也就是按键的作用;键值1为菜单项向上移动,键值3为菜单项向下移动,键值4为确定键,而在代码当中,有一段屏蔽掉的代码,为退出键的定义的,定义的键值为2。
    当键值为1时,会调整当前活动的菜单项,并置标志变量Update_flag为1,让程序在循环当中刷新显示的菜单。
    键值为3时,也调整当前活动的菜单项,当然是向下调整了,同时置标志变量Updage_flag为1,以控制刷新显示的菜单。
    键值为4时,为确定键按下,置Enter_flag为1,在后面的代码当中会进行相对应的菜单项响应操作分支。


    当键值分支处理代码执行结束后,循环当中会判断当前的显示是否需要刷新,即判断Update_flag的值,如果需要刷新,则调用UpDate_Menu函数。
    随后的代码中,判断Enter_flag即确定按键是否按下,如按下,则进入菜单响应控制的分支处理;在switch分支中,根据Active_Index的值判断当前处于选择状态的菜单项是哪一个,然后进行分支处理,也就是每个case分支对应一个菜单项的响应,这里用户可以根据自己的需要进行代码的编写;例如在上面的代码当中就有一段屏蔽的代码,其响应第一项菜单项,调用了一个Basetest()函数进入了一个显示界面(具体显示什么无所谓了,仅供参考),从该函数退出后,需要调用一个Redraw_Menu函数,重绘当前的菜单显示,然后置显示刷新标识Update_flag为1,在下一次循环中完成刷新显示。


    每次循环里,都调用一个键盘扫描的函数:KeyScan_Service(),其实可以根据用户自己的键盘扫描程序架构而定的,这里仅供参考。


5操作演示
    本工程范例当连接无误且MCU以及LCD模块都确认正常工作时,上电后,会将当前的菜单列表显示如下:



    此时可以按下Key3键以控制当前选择的菜单项,如下图是按下一次Key3键后菜单的显示情况:



    而再连续按下两次Key3键后,则会选择第四项菜单,当然用户也可以体验一下K1向上键的效果。



    在菜单列表项的选择中,主要是通过向上选择键和向下选择键来切换菜单项的选择,而在所选择的菜单项按下确定键,则会进行该项菜单的响应函数或代码,当然需要写有响应代码方可。在本工程范例中,给前四项菜单安排了响应函数,分别是:



    分别对应着前四项菜单,下面的图片为这些各项菜单响应内容的显示效果(也就是选择在这几个项的菜单下时,按下确定键后出现的显示效果,图中仅示例三项):



    而当进入各个菜单项的响应界面后,如要返回上层的菜单列表,可以按K2键,不过在第三项菜单较为特殊,它是Edit输入框控件的功能演示应用,在它的显示界面里本身就有键控响应Edit输入框的控制,所以在该项菜单的响应显示界面中,需要长按K2键才可退出。


资料下载:
AVR单片机控制MzLH06模块的菜单程序范例(IAR forAVR)
51单片机控制MzLH06模块的菜单程序范例(Keil C51)
MzLH06液晶模块编程手册V1.0


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)