嵌入式应用系统中,使用点阵式液晶屏作为人机交互的界面和使用键盘控制显示的内容已成为主流趋势。但点阵式液晶屏显示的内容非常有限,如何设计一个合理的结构化菜单就成了嵌入式开发中非常关键的问题。本文介绍了一种用链表表示菜单的树形结构。该方法使设计的菜单结构清晰、功能明确、扩展性好,易维护。
此外,良好的菜单设计除包括基本的工作流程选择外,还应包括自动锁屏、手动锁屏及解锁的操作。这样可以延长LCD的使用寿命,起到保护LCD显示屏的作用。
下面以6个按键、ARM芯片LPC3250和OCMJ2X10C_5液晶屏组成的系统为例,在C语言环境下进行介绍。
1 系统硬件总体框图
本文设计了一个在ARM嵌入式平台上实现LCD160×32多级菜单的电路。采用LPC3250的ARM芯片为控制芯片,OCMJ2X10C_5液晶屏为显示模块,采用键盘扫描作为输入控制。系统总体硬件框图如图1所示。
2 键盘扫描模块
锁屏和解锁功能需区分按下系统键的时间长短,键盘中断输入控制方式不易实现这种区分。但因键盘扫描有一个合理的时间阈值,从而容易实现这种区分。故本文采用键盘扫描作为输入控制,其电路原理图如图2所示。
3 点阵式液晶模块
本文中系统采用160×32点阵液晶屏[1],可显示16×16点阵的汉字2行10列。它还可显示字母和数字,并且提供了多功能指令。本文中液晶屏和CPU之间采用串行连接方式[2],其电路原理图如图3所示。
4 基于链表的网状菜单模型
本文采用链表法[3]将每个菜单抽象成统一的对象,用面向对象的思想设计菜单结构。每个对象节点需储存自己的基本属性及其父节点、第一个子节点和左右兄弟节点的位置。本文以三级菜单为例,基于C语言用链表结构来完成对菜单树的设计,通过“上”、“下”、“左”、“右”、“确认”、“返回”6个按键实现对菜单的选择。
链表法实现多级菜单的显示,首先建立一个结构体,定义结构体变量。本文中结构体的C语言源代码如下:
typedef struct MENU_STRUCT{
INT8U name[LCD_WIDTH_IN_HALF_WORD];
INT8U value[LCD_WIDTH_IN_HALF_WORD];
INT32S value_PreIdx;/*保存value上一个值*/
INT32S value_CurIdx;/*保存value当前值*/
INT8U value_addr;/*menu在LCD屏上的显示位置*/
INT8U idx[8];/*菜单索引号*/
pfMenu pfHook;/*菜单响应函数*/
pfMenu pfDisp;/*菜单显示函数*/
struct MENU_STRUCT*parent;/*菜单的上一级菜单*/
struct MENU_STRUCT*firstchild;
/*菜单的第一个子菜单*/
struct MENU_STRUCT*nextsiling;
/*菜单的下一个兄弟菜单*/
struct MENU_STRUCT*presiling;
/*菜单的前一个兄弟菜单*/
struct MENU_STRUCT*nextNode;
/*用于菜单数组的管理*/
}*pMENU_STRUCT;
结构体指针parent、firstchild、nextsiling、presiling和nextNode管理一段存储菜单项的内存空间,它们通过链表的方式建立起菜单的网状结构,便于菜单项的删除、扩展和维护。通过链表结构可由当前菜单确定它的父菜单及第一个兄弟菜单,从而查找到当前菜单所在的菜单项并在液晶屏上显示。每层的菜单结构模型如图4所示。
5 菜单响应按键的基本事件
通过按键事件可对菜单进行显示、编辑、进入下级菜单、返回上级菜单、锁屏、解锁等操作。在μC/OS-II系统中[4-5],按键任务模块发送按键状态消息,LCD显示任务模块接收消息并做相应的消息处理。非锁屏状态程序流程图如图5所示。
6 液晶屏锁屏与解锁
嵌入式系统显示屏离不开锁屏与解锁操作。锁屏状态下按任意键可点亮LCD液晶屏并显示解锁提示信息。通过手动长按系统键或持续一段时间无按键操作,则进入锁屏状态;锁屏和解锁的流程图分别如图6、图7所示。
本文以6个按键、LPC3250的ARM芯片和LCD液晶屏为例,在C语言环境下介绍了用链表设计菜单结构和锁屏解锁的方法。该方法设计的菜单结构清晰,扩展性好,具有很好的可移植性,易维护,适用于嵌入式应用系统开发。同时,此方法也为其他应用系统的多级菜单设计提供了参考和选择。