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 |