1 概述
液晶显现器(Liquid Crystal Display,LCD)因为其体积和功耗等要素,十分合适嵌入式环境的运用。近年来,跟着微处理器功用的进步,嵌入式体系完成的功用越来越强壮,产生的数据量也越来越大。相对应地,需求显现的数据量也随之增大。嵌入式环境下运用LCD显现器,因为条件约束,体积较小,且显现的内容有限。并且,传统的 LCD显现方法总是不加挑选地显现一切监控的信息,在监控的信息量十分巨大时会导致不能及时显现用户所需求的信息。多级菜单显现则是将信息分类显现的一种显现方法,该方法依据用户的挑选,对显现信息加以挑选并分级显现,这样既确保用户获取其所需的信息,又能保证信息显现的实时性。
2 多级菜单的结构
规划多级菜单的意图在于将需求显现的信息分门归类,便利用户挑选。所以在规划菜单时需求依据整个体系的功用和要求来设定菜单的级数,以及各级子菜单的个数。整个多级菜单的拓扑结构为树型结构,主菜单为根节点,子菜单为枝节点,终究一级菜单为叶节点,如图1所示。
图1 多级菜单的结构图
3 多级菜单的程序规划
3.1 循环方法
循环方法的规划思路:预先界说一个包括6个结构元素的结构体、5个字符型和1个指针型。第1个字符变量寄存当时界面的索引号;第2个字符变量寄存按下 “down(向下)”键时需求跳转到的索引号;第3个字符变量寄存按下“up(向上)”键时需求跳转到的索引号;第4个字符变量寄存按下“enter(进入)”键时需求跳转的索引号;第5个字符变量寄存按下“esc(退出)”键时需求跳转的索引号;第6个变量为函数指针变量,寄存当时索引号下需求履行的函数的进口地址。
将一切需求显现的界面其所对应的履行函数和按键索引号以结构体的方法列表存储。详细完成如下:
typedef struct{
uchardown_index;
ucharup_index;
ucharenter_index;
ucharesc_index;
void (*operate)();
}Key_index_struct;
假定菜单分3级,共10个界面,则有:
Key_index_struct const Key_tab[10]={
{0, 0, 0, 1, 0,(*main_menu)},
{1, 2, 3, 4, 0,(*sub_menu1)},
{2, 3, 1, 5, 0,(*sub_menu2)},
{3, 1, 2, 7, 0,(*sub_menu3)},
{4, 4, 4, 4, 1,(*sub_menu1_1)},
{5, 6, 6, 5, 2,(*sub_menu2_1)},
{6, 5, 5, 5, 2,(*sub_menu2_2)},
{7, 8, 9, 7, 3,(*sub_menu3_1)},
{8, 9, 7, 8, 3,(*sub_menu3_2)},
{9, 7, 8, 9, 3,(*sub_menu3_3)},
};
void Lcd_display(void){
switch(Key_status){
case enter:
Key_fun=Key_tab[Key_fun].enter_index;
break;
case down:
Key_fun=Key_tab[Key_fun].down_index;
break;
case up:
Key_fun=Key_tab[Key_fun].up_index;
break;
case esc:
Key_fun=Key_tab[Key_fun].esc_index;
break;
default:
return;
break;
}
Key_fun_Pt=Key_tab[Key_fun].operate;
(*Key_fun_Pt)();//履行当时按键的操作
}
当微处理器扫描键盘检测到有按键按下时,依据按键按下的类型,回来在当时界面下其所对应的跳转索引号,并履行相应的函数。
因为每个界面的制作都是由一个独立函数完成的,从循环方法的完成过程中发现,每产生一次按键按下操作都需求从头制作整个屏幕。假如中心处理器是低速主频的处理器,在界面切换的时分会闪耀。并且,每一个界面都有固定不变的索引号,在添加或删去界面的时分需求从头修正整个列表,降低了程序的可移植性。
3.2 查询方法
查询方法是经过结构体对本身的递归调用完成菜单的多级嵌套。
结构体经过对本身的两次调用构建双向列表。一个菜单界面即为一个节点,节点的前驱和后继别离寄存其父节点和子节点的进口地址。
菜单参数的结构体界说如下:
typedef struct Lcd_menu_content{
uchar *lpIcon;//显现图标
uchar *lpText;//显现文本信息
uchar nTextCount; //菜单对应的文本信息的个数
}Lcd_menu_content;
每个界面对应一个节点,节点都界说成如下结构体的变量:
typedef struct Lcd_menu{
struct Lcd_menu*lpfather;//父级
struct Lcd_menu*lpson;//大儿子
uchar nSonCount;//父级的儿子个数
Lcd_menu_content lpIconAndText;
uchar Flag_return;//回来标志
void (*operate)();//处理函数进口地址
}Lcd_menu;
由图1可知,多级菜单的拓扑结构为树型拓扑结构,即每一个节点只要一个父节点和若干个子节点。所以,对整个叉树进行遍历即可精确地查找到菜单界面地点的节点。
结构体完成的链表如图2所示。
图2 结构体链表
查询方法与循环方法比较,因为减少了查表次数,因此改进了MPU的功率;但查询方法占用MPU处理时刻过长,不习惯需求高速处理数据的运用。并且,在查询方法中添加或删去节点对程序改动较大,也不合适移植。
3.3 状况机方法
状况机是由事情驱动,在各个状况之间跳转。选用状况机方法时,只需求供给驱动事情(在此规划中驱动事情为有用的按键按下),然后依据按键扫描回来的键值,决议所要跳转的下一状况。
如图3所示,体系启动初始化是显现Main_menu界面,当按键检测有回来值(即有按键按下)时,依据按下的按键所代表的操作跳转到指定的状况。例如:按下Up或许是down键时,只是在Main_menu界面内高亮显现不同区域;按下Enter时,则要依据本来按下的Up和down键来挑选需求跳转的方向,假定在按下Enter之前仅按下一次down键,则key_v的值为2(key_v的值默以为1,即默许选中子菜单的第一项),就跳转为 Sub_menu2界面;按下Esc键时,为从子菜单回来到上一级菜单,假如已经是主菜单了则回来的仍是主菜单。
图3 多级菜单的状况图
因为运用的是状况机的方法,只要产生一次有用的按键,状况才会产生一次跳转。并且,仅当Enter和Esc键按下时,才会切换界面。所以即便是在高速MPU运用中,也不会呈现屏幕闪耀的作用。
从图3中能够看出,当要产生状况跳转时,意图状况只能是当时状况几个分支猜测中的一个,然后不需求遍历整个列表,能够习惯高速数据处理的场合。
多级菜单的程序流程如图4所示。体系上电初始化后显现主菜单,键盘扫描能够经过主程序中循环查询或许中止扫描来完成,终究依据键盘回来的键值挑选下一状况。
图5为根据状况机的多级菜单的完成。
图4 多级菜单的程序流程图
图5 多级菜单的完成
结语
以上三种多级菜单的完成方法均具有很强的实用性。循环方法和查询方法下,程序结构简略易用,而状况机方法下程序可移植性强。状况机程序规划不只能够用在人机接口规划中,还可用于嵌入式通信协议等其他场合中。