单片机C语言下LCD多级菜单的一种实现方法

合集下载

单片机汇编语言下LCD多级菜单的一种实现方法

单片机汇编语言下LCD多级菜单的一种实现方法

单片机汇编语言下LCD多级菜单的一种实现方法万方数据万方数据单片机汇编语言下LCD多级菜单的一种实现方法作者:高璇作者单位:安徽理工大学电气与信息工程学院,安徽,淮南,232001;中煤北京煤矿机械有限责任公司设备动力部,中国,北京,102400 刊名:科技信息英文刊名:SCIENCE & TECHNOLOGY INFORMATION年,卷(期):2010,(31)被引用次数:0次参考文献(3条)1.ST7920控制器系列中文字库液晶模块中文说明书 20052.STC89C51RC/RD+系列单片机器件手册 20033.蔡美琴MCS-51系列单片机系统及其应用 2005相似文献(10条)1.会议论文宋晓辉.叶桦.丁昊基于单片机的多级菜单实现方法改进2007介绍了一种在C语言环境下,基于单片机的多级菜单实现方法.该方法从菜单的功能结构发,在程序设计中做了几点改进.首先对菜单数据项和功能函数各自进行独立设计,通过在数据结构中增加按键有效标志、字符串指针、存储器地址以及与复用相关的元素,实现了两者源代码空间的有效分离,从而大大提高了程序的可维护性;其次引入菜单项复用的思想,简化了程序结构.该设计的多级菜单在自动售货机的服务模式的实际应用表明,此改进方法使菜单设计变得更为简单方便,软件通用性更高,维护更容易.2.期刊论文陆铮.罗嘉单片机C语言下LCD多级菜单的一种实现方法-工矿自动化2006(1)介绍了在C语言环境下,在LCD液晶显示屏上实现多级嵌套菜单的一种简便方法,提出了一个结构紧凑、实用的程序模型.3.期刊论文宋晓辉.叶桦.丁昊.Song Xiaohui.Ye Hua.Ding Hao基于单片机的多级菜单实现方法改进-东南大学学报(自然科学版)2007,37(z1)介绍了一种在C语言环境下,基于单片机的多级菜单实现方法.该方法从菜单的功能结构发,在程序设计中做了几点改进.首先对菜单数据项和功能函数各自进行独立设计,通过在数据结构中增加按键有效标志、字符串指针、存储器地址以及与复用相关的元素,实现了两者源代码空间的有效分离,从而大大提高了程序的可维护性;其次引入菜单项复用的思想,简化了程序结构.该设计的多级菜单在自动售货机的服务模式的实际应用表明,此改进方法使菜单设计变得更为简单方便,软件通用性更高,维护更容易.4.期刊论文唐炜.卢道华.顾金凤单片机系统中液晶显示多级菜单的软硬件设计-华东船舶工业学院学报(自然科学版)2003,17(1) 以8031单片机控制GXM-12864液晶显示器为例,通过建立小字库,结合具体实例介绍了实现多级菜单显示的方法.当菜单显示内容改变时,只需修改相应参数,而不修改程序.文中提及的硬件电路和软件设计通用性较强,具有更一般的实际意义.5.期刊论文汪高勇.宋毅恒.尚举邦.WANG Gao-yong.SONG Yi-heng.SHANG Ju-bang C51与单片机系统多级菜单的模块化设计-光电技术应用2009,24(2)介绍了一种基于单片机系统的多级菜单模块化编程方法.该方法从模块化的角度将菜单编程简单地划分为共用键盘处理和菜单模块两部分,使得菜单具有通用的模块化结构,方便了菜单的加载与卸载,增强了C51语言在单片机系统人机接口的设计,软件结构清晰,维护方便.6.期刊论文朱青.张兴敢.柏业超.ZHU Qing.ZHANG Xing-gan.BAIYe-chao一种多功能水情自动测报系统设计-现代电子技术2011,34(3) 为满足当前水情数据测报的要求,设计实现了一种多功能水情自动测报系统.该系统基于PIC16F887单片机、GSM模块,可接收多种形式的传感器信号,并存储在大容量的FLASH存储器中,同时通过GSM模块发送水情数据和报警信息.另外,该系统借助LCD液晶显示屏可显示多级中文菜单,方便控制和查询.该系统的功耗低,体积小,功能扩展性强,经过多次测试,操作方便,工作可靠,在水情自动测报领域具有很大的推广价值.7.期刊论文王运良.张建忠.程明.WANG Yun-liang.ZHANG Jian-zhong.CHENG Ming基于ATmega16L单片机的中文菜单显示技术-江苏电器2006(1)针对目前电力测量仪表广泛使用中文液晶显示器的趋势,介绍一种由ATmega16L单片机和液晶MSC-G12864组成的多级中文菜单滚动显示系统,应用结果证明该实现方法简单,系统易于扩展和维护.描述了硬件电路的结构,详细分析了多级菜单软件的实现方法,包括中英文字符的存储,菜单项的构成以及整个菜单的滚动显示,给出了部分程序清单.8.期刊论文李敏通.张战国.LI Mintong.ZHANG Zhanguo一种建立单片机应用系统菜单的新方法-计算机工程2006,32(16) 提出了一种用一维线性数组实现树形拓扑结构多级菜单的方法,并用C51语言编程验证了这种方法的可行性.该方法对存储资源的利用效率高,逻辑关系清晰,且菜单的建立和修改方便,适合在单片机应用系统中使用.9.期刊论文基于单片机实现的实用汉字液晶显示设计方法-硅谷2009(19)介绍一种在多级菜单界面设计上非常简单实用的采用C51语言实现液晶显示的方法;同时介绍自定义字库和硬件汉字库的设计方法和应用.10.期刊论文陈国鹏.Chen Guopeng基于PIC18F6622的人机界面设计-工业控制计算机2009,22(9)介绍了如何使用PIC单片机PIC18F6622和液晶模块MTG-S32240进行显示控制系统的设计,分析了其硬件平台的设计要点,给出了清晰的人机界面软件设计架构,介绍了其中最主要的多级菜单的设计方法.设计的显示控制系统在实际系统中运行稳定可靠,证明了设计方法的正确性.本文链接:/doc/887e05f29e31433239689316.html /Periodical_kjxx201031057.aspx授权使用:南华大学(nhdx),授权号:af1513e4-a30e-4369-9f7f-9f1000acb2e6下载时间:2011年6月28日。

一种易于移植的单片机液晶显示多级菜单设计

一种易于移植的单片机液晶显示多级菜单设计

一种易于移植的单片机液晶显示多级菜单设计王勇【摘要】LCD display as a human-computer interaction is very popular in various application situations of embedded microcontroller systems. However, general LCD display menu design is a little bit complicated, and does not have the portability, therefore the complexity in development and system maintenance and the cost are increased. In this paper we introduce the window and message mechanisms of Windows Operating System, and design a multilevel menu. The core of the menu is a universal window engine which does not depend on specific hardware and the content of menu. Research and application show that the menu design has the characters of simple structure, easy to use, little resource consumption, portable and so on. In the end of the paper we present an application example running in the FYD12864 LCD module.%在单片机嵌入式系统的许多应用场合均采用液晶显示器作为人机交互的方式,然而通常的液晶显示菜单设计较为复杂,且基本不具备可移植性,从而增加了开发、维护的复杂性和成本.引入Windows系统下的窗口和消息机制,设计一个多级菜单,该菜单的核心部分是一个不依赖具体硬件和菜单内容的通用的窗口引擎.研究和应用表明,该菜单设计具有结构简单、使用方便、占用资源少以及易于移植等特点.最后给出一个在FYD12864液晶模块上使用此方法的应用案例.【期刊名称】《计算机应用与软件》【年(卷),期】2011(028)012【总页数】6页(P263-268)【关键词】单片机;液晶显示;菜单;窗口引擎【作者】王勇【作者单位】电子科技大学四川成都610054东莞电子科技大学电子信息工程研究院广东东莞523808【正文语种】中文【中图分类】TP3110 引言单片机系统,特别是8位单片机系统通常可用资源较少,速度相对较慢,一般不适合部署操作系统,更谈不上图形引擎了。

单片机C语言下LCD多级菜单的一种实现方法

单片机C语言下LCD多级菜单的一种实现方法

单片机C语言下LCD多级菜单的一种实现方法(转)2012-1-10 00:45阅读(1)单片机菜单程序#include#include#define SIZE_OF_KEYBD_MENU 20 //菜单长度uchar KeyFuncIndex=0;//uchar KeyFuncIndexNew=0;void (*KeyFuncPtr)(); //按键功能指针typedef struct{uchar KeyStateIndex; //当前状态索引号uchar KeyDnState; //按下"向下"键时转向的状态索引号uchar KeyUpState; //按下"向上"键时转向的状态索引号uchar KeyCrState; //按下"回车"键时转向的状态索引号void (*CurrentOperate)(); //当前状态应该执行的功能操作} KbdTabStruct;KbdTabStruct code KeyTab[SIZE_OF_KEYBD_MENU]={{ 0, 0, 0, 1,(*DummyJob)},//顶层{ 1, 2, 0, 3,(*DspUserInfo)},//第二层{ 2, 1, 1, 9,(*DspServiceInfo)}, //第二层{ 3, 0, 0, 1,(*DspVoltInfo)},//第三层>>DspUserInfo的展开{ 4, 0, 0, 1,(*DspCurrInfo)},//第三层>>DspUserInfo的展开{ 5, 0, 0, 1,(*DspFreqInfo)},//第三层>>DspUserInfo的展开{ 6, 0, 0, 1,(*DspCableInfo)},//第三层>>DspUserInfo的展开...........{ 9, 0, 0, 1,(*DspSetVoltLevel)}//第三层>>DspServiceInfo的展开..........};void GetKeyInput(void){uchar KeyValue;KeyValue=P1&0x07; //去掉高5bitdelay(50000);switch(KeyValue){case 1: //回车键,找出新的菜单状态编号{KeyFuncIndex=KeyTab[KeyFuncIndex].KeyCrState;break;}case 2: //向上键,找出新的菜单状态编号{KeyFuncIndex=KeyTab[KeyFuncIndex].KeyUpState; break;}case 4: //向下键,找出新的菜单状态编号{KeyFuncIndex=KeyTab[KeyFuncIndex].KeyDnState; break;}default: //按键错误的处理......break;}KeyFuncPtr=KeyTab[KeyFuncIndex].CurrentOperate; (*KeyFuncPtr)();//执行当前按键的操作}//其中KeyTab的设计颇费尽心机。

基于STM32单片机LCD多级菜单的设计

基于STM32单片机LCD多级菜单的设计

基于STM32单片机LCD多级菜单的设计摘要本设计介绍了以ARM内核嵌入式处理器STM32为控制核心,辅以低功耗的液晶模块MFG240160-3-A,以及相应的按键控制电路,实现了LCD多级菜单的设计。

在本系统中,侧重点在于LCD的显示上,因此此系统的硬件结构很简单,侧重点在于软件架构及程序的编写上,该系统程序量大,函数封装多,关于实时时钟信息、波形存储信息都留有相应的软件接口,以便与其它模块正确的相连接。

本系统硬件电路简单,但显示信息丰富,可以移植到各种便携式的电子产品上去,为电子产品的显示界面的设计提供了一个新的思路。

关键词 STM32单片机;LCD多级菜单;低功耗;Base on STM32 Microprocessor LCD modules in the multi-level menu display systemAbstractThis design describes to STM32 embedded processor based on ARM core for control, coupled with low power consumption of LCD module MFG240160-3-A as well as the corresponding keys control circuitry, enabling multi-level menu design of LCD. In this system, the focus is on the LCD display, so this system hardware structure is very simple, the emphasis lies in software architectures and applications, the system capacity, function encapsulates the information about the real-time clock, waveform stored information will have the appropriate software interface so that correct with other modules that you are connecting to. This system is simple, but the display information-rich, portable to avariety of portable electronic products, for electronic product display interface design provides a new train of thought.Keywords: STM32; LCD multi-level menu; low-power;目录摘要(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((I Abstract(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( ((II 前言 ............................................................... 4 1方案设计 (5)1.1 设计方案概述 (5)1.2 电路介绍 (5)2 器件介绍 (9)2.1 STM32简介 (9)2.2 MFG240160-3-A LCD介绍 (13)3 软件设计 (16)3.1 STM32单片机的初始化 (16)3.2 液晶屏的初始化 (20)3.3 数据的传输 (20)3.4 字模的提取 (21)3.5 菜单框架的设计 (23)3.6 字模库的建立 (25)3.7 函数库的封装 (25)3.8 菜单标记 (26)3.9 时钟信息的显示 (27)3.10 波形的显示 (28)4 结论 (30)参考文献 (31)致谢 ............................................ 错误~未定义书签。

51单片机实现多级液晶显示中文菜单

51单片机实现多级液晶显示中文菜单

51单片机实现多级液晶显示中文菜单【摘要】以AT89C51单片机控制使用比较普遍的YM12864液晶显示器为基础,介绍了一种采用分页原理实现多级中文菜单操作的方法。

给出了YM12864主要技术参数、显示特性和核心的程序。

设计的中文菜单具有一定的通用性,只需更改其中的菜单项即可将此设计应用到家电、仪器仪表等设备上,为操作者提供友好方便的中文操作界面。

【关键词】单片机;分页;YM12864液晶;中文菜单一、引言目前小型的显示器主要有LCD和LED,LED显示器只能显示数字和有限个英文字符,不能显示汉字,显示内容不直观,操作人员只能根据约定格式了解显示内容。

而LCD则可显示各种汉字和图形,尤其能实现中文菜单显示,为操作者提供方便友好的操作界面,并且功耗低,因此LCD得到广泛应用。

而现在市面上带中文字库的LCD比比皆是,价格适中,且大部分具有与MCU统一的标准接口,为使用LCD实现中文菜单操作提供了很大的方便。

相信更多的电子产品在提升性能的同时,设计更加人性化的中文菜单交互界面,将会使产品具有更广阔的前景。

二、YM12864液晶显示模块简介YM12864汉字图形点阵液晶显示模块,可显示汉字及图形,内置8192个中文汉字(16X16点阵)、128个字符(8X16点阵)及64X256点阵显示RAM (GDRAM)。

主要技术参数和显示特性:电源:VDD 3.3V~+5V(内置升压电路,无需负压)显示内容:128列×64行与MCU接口:8位或4位并行/3位串行多种软件功能:光标显示、画面移位、自定义字符、睡眠模式等。

其引脚功能为通用20脚LCD接口,用户指令集也为通用128*64LCD用户指令集,相关资料很容易获取。

因其内置中文字库,省去了自己造字库的工作量,而只需写入相应的汉字和字符内码即可显示所需要的汉字和字符,这在许多程序开发软件中很容易实现,如:WA VE、KEIL等。

所以使用带中文字库的LCD来实现中文菜单操会更加简便。

(完整版)单片机多级菜单编程实现

(完整版)单片机多级菜单编程实现

单片机多级菜单编程实现单片机多级菜单编程实现(ZT)建立一个树状的菜单结构,用链表实现链表中包含:1、指向同级左右菜单和指向父菜单、子菜单的四个菜单结构体指针;2、进入该菜单时需要执行的初始化函数指针3、退出该菜单时需要执行的结束函数指针4、该菜单内的按键处理函数指针数组的指针操作菜单模块需要的按键操作有:左、右、确认、退出。

采用这种办法,可以方便的添加或删减菜单。

并且只需要在其头文件中修改初始变量就可以实现,完全无须修改C文件中的任何函数。

具体结构定义我的定义,做个参考:#define MENU_HLP_EN //菜单帮助信息使能typedef struct{void (*pMenuTaskInit)(void); //指向菜单任务初始化函数的指针void (*pMenuTaskEnd)(void); //指向菜单任务结束函数的指针}MENU_TASK_TYP;typedef struct MenuTyp{INT8U *MenuName; //菜单名称字符串WORK_MOD WorkMod; //工作状态编号MENU_TASK_TYP *pMenuTask; //指向菜单任务的指针void (**pTaskKeyDeal)(void); //指向菜单任务按键处理函数数组的指针#ifdef MENU_HLP_ENINT8U *MenuHlp; //菜单帮助字符串#endifstruct MenuTyp *pParent; //指向上层菜单的指针struct MenuTyp *pChild; //指向子菜单的指针struct MenuTyp *pRight; //指向右菜单的指针struct MenuTyp *pLeft; //指向左菜单的指针}MENU_TYP;我根据网上的资料做的一个菜单:/****************菜单数据结构**********************/struct KeyTabStruct{uint8 MenuIndex; //当前状态索引号uint8 MaxItems; //本级菜单最大条目数uint8 ShowLevel; //菜单显示内容uint8 PressOk; //按下"回车"键时转向的状态索引号uint8 PressEsc; //按下"返回"键时转向的状态索引号uint8 PressDown; //按下"向下"键时转向的状态索引号uint8 PressUp; //按下"向上"键时转向的状态索引号void (*CurrentOperate)(); //当前状态应该执行的功能操作};uint8 MenuID; //菜单ID号uint8 MenuNextID; //下级菜单ID号//CurMenuID=本菜单ID//MaxMenuItem=同级菜单最大项数//OkMenuID=子菜单层所对应的菜单ID,ID=999为菜单已经到底了//EscMenuID=父菜单层所对应的菜单ID,ID=999为菜单已经到顶了//DownMenuID=弟菜单层所对应的菜单ID,ID=999为菜单是独生子//UpMenuID=兄菜单层所对应的菜单ID,ID=999为菜单是独生子//CurFunction=本菜单所对应的菜单函数指针const struct KeyTabStruct KeyTab[MAX_KEYTABSTRUCT_NUM]={//CurMenuID, axMenuItem, MenuShowLevel, OkMenuID, EscMenuID, DownMenuID, UpMenuID, CurFunction{MENU_EDIT, 0, 0, MENU_DATA_VIEW, MENU_NO, MENU_NO, MENU_NO, *MenuEdit},{MENU_DATA_VIEW, 3, 1, MENU_DATA_VIEW_FIRE, MENU_EDIT, MENU_ SYS_EDIT, MENU_PRINT_DATA,*MenuEdit},{MENU_DATA_VIEW_FIRE, 5, MENU_NO, MENU_NO, MENU_DATA_VIEW, MENU_DATA_VIEW_TROUBLE, MENU_STEP_FOLLOW, *MenuDataViewIn}, {MENU_DATA_VIEW_TROUBLE, 5, MENU_NO, MENU_NO, MENU_DATA_VI EW, MENU_DATA_VIEW_REPEAT, MENU_DATA_VIEW_FIRE, *MenuDataVie wIn},{MENU_DATA_VIEW_REPEAT, 5, MENU_NO,MENU_NO, MENU_DATA_VIEW, MENU_FACE_CHECK,MENU_DATA_VIEW_TROUBLE, *MenuDataViewIn},{MENU_FACE_CHECK, 5, MENU_NO,MENU_NO, MENU_DATA_VIEW, MENU_STEP_FOLLOW,MENU_DATA_VIEW_REPEAT, *MenuFaceCheck},{MENU_STEP_FOLLOW, 5, MENU_NO,MENU_NO, MENU_DATA_VIEW, MENU_DATA_VIEW_FIRE, MENU_FACE_CH ECK,*MenuStepFollow},{MENU_SYS_EDIT, 3,2, MENU_SUM_SET, MENU_EDIT,MENU_PRINT_DATA, MENU_DATA_VIEW, *MenuEdit},{MENU_SUM_SET, 6, MENU_NO,MENU_NO, MENU_SYS_EDIT, MENU_EDIT_INSULATE,MENU_TIME_SET, *MenuSumSet},{MENU_EDIT_INSULATE, 6, MENU_NO,MENU_NO, MENU_SYS_EDIT, MENU_EDIT_HZ, MENU_SUM_SET,*MenuEditInsulate},{MENU_EDIT_HZ, 6, MENU_NO,MENU_NO, MENU_SYS_EDIT, MENU_LD_CONTROL,MENU_EDIT_INSULATE, *MenuEditHZ},{MENU_LD_CONTROL, 6,MENU_NO, MENU_NO, MENU_SYS_EDIT, MENU_LD_DELAY,MENU_EDIT_HZ, *MenuLDControl},{MENU_LD_DELAY, 6,MENU_NO, MENU_NO, MENU_SYS_EDIT, MENU_TIME_SET,MENU_LD_CONTROL, *MenuLDDelay},{MENU_TIME_SET, 6, MENU_NO,MENU_NO, MENU_SYS_EDIT, MENU_SUM_SET, MENU_LD_DELAY,*MenuTimeSet},{MENU_PRINT_DATA, 3, 3,MENU_PRINT_DATA_FIRE, MENU_EDIT, MENU_DATA_VIEW,MENU_SYS_EDIT, *MenuEdit},{MENU_PRINT_DATA_FIRE, 4,MENU_NO, MENU_NO, MENU_PRINT_DATA,MENU_PRINT_DATA_TROUBLE, MENU_PRINT_SET, *MenuPrintDataIn}, {MENU_PRINT_DATA_TROUBLE, 4, MENU_NO,MENU_NO, MENU_PRINT_DATA, MENU_PRINTER_CHECK,MENU_PRINT_DATA_FIRE, *MenuPrintDataIn},{MENU_PRINTER_CHECK, 4, MENU_NO,MENU_NO, MENU_PRINT_DATA, MENU_PRINT_SET,MENU_PRINT_DATA_TROUBLE, *MenuPrintDataIn},{MENU_PRINT_SET, 4, MENU_NO,MENU_NO, MENU_PRINT_DATA, MENU_PRINT_DATA_FIRE,MENU_PRINTER_CHECK, *MenuPrintSet},};/**************************************编程菜单显示数据******************************/const struct MenuDispData MenuEditShow[][MENU_MAX] = {{{MENU_NO , 0, 0, "选择: 消音→退出"}, //主菜单{MENU_DATA_VIEW , 1, 6, "⒈数据查看"},{MENU_SYS_EDIT , 2, 6, "⒉系统编程"},{MENU_PRINT_DATA , 3, 6, "⒊数据打印"}},{{MENU_NO , 0, 0, "数据查看: 消音→退出"}, //数据查看{MENU_DATA_VIEW_FIRE , 1, 4, "⒈火警"},{MENU_DATA_VIEW_TROUBLE, 2, 4, "⒉故障"},{MENU_DATA_VIEW_REPEAT , 3, 4, "⒊重码"},{MENU_FACE_CHECK , 1,12, "⒋面板检测"},{MENU_STEP_FOLLOW , 2,12, "⒌单步跟踪"}},{{MENU_NO , 0, 0, "系统编程: 消音→退出"}, //系统编程{MENU_SUM_SET , 1, 0, "⒈容量设置"},{MENU_EDIT_INSULATE , 2, 0, "⒉隔离点"},{MENU_EDIT_HZ , 3, 0, "⒊汉字描述"},{MENU_LD_CONTROL , 1,12, "⒋联动控制"},{MENU_LD_DELAY , 2,12, "⒌模块延时"},{MENU_TIME_SET , 3,12, "⒍时钟调整"}},{{MENU_NO , 0, 0, "数据打印: 消音→退出"}, //数据打印{MENU_PRINT_DATA_FIRE , 1, 0, "⒈火警数据"},{MENU_PRINT_DATA_TROUBLE,2, 0, "⒉故障数据"},{MENU_PRINTER_CHECK , 3, 0, "⒊打印机自检"},{MENU_PRINT_SET , 1,12, "⒋打印设置"}},};/***********************************等待按键******************** **************/void WaitKey(void){uint32 time;time = RTCFlag;WhichKey = KEY_NONE;while(!EscFlag){if(RTCFlag - time >= EDIT_TIME)EscFlag = TRUE;if(WhichKey != KEY_NONE){KeySound(300); //按键音return;}}}/*********************************显示多级菜单**********************************/void MenuEdit(){uint32 i,j=0;uint32 oldid;j = KeyTab[MenuID].ShowLevel;if(WhichKey == KEY_ESC || WhichKey == KEY_OK){ClearScreen();for(i=0;i<KeyTab[MenuNextID].MaxItems+1;i++) ShowString(MenuEditShow[j][i].Lin,MenuEditShow[j] [i].Column,MenuEditShow[j][i].Pdata,0); //初始化显示oldid =0;//没有原先选择的项}else{if(WhichKey == KEY_UP)oldid = KeyTab[MenuNextID].PressDown;elseoldid = KeyTab[MenuNextID].PressUp;//指示原先的项}for(i=1;i<KeyTab[MenuNextID].MaxItems+1;i++){if(MenuEditShow[j][i].Id == oldid)ShowString(MenuEditShow[j][i].Lin,MenuEditShow[j][i].Column,MenuEditShow[j][i].Pdata,0); //正常显示原先的项else{if(MenuEditShow[j][i].Id == MenuNextID)ShowString(MenuEditShow[j][i].Lin,MenuEditShow[j][i].Column,MenuEditShow[j][i].Pdata,1); //反显当前选择的项}}WhichKey = KEY_NONE;}/******************************系统编程************************* ******/uint32 Edit(void){struct KeyTabStruct NowKeyTab; //指示当前的菜单值uint32 escflag = FALSE;ResetFlag = FALSE;ChangeFlag = FALSE;EscFlag = FALSE;MenuID = MENU_EDIT;NowKeyTab = KeyTab[MenuID];MenuNextID = NowKeyTab.PressOk;(*NowKeyTab.CurrentOperate)(); //显示主菜单do{if(WhichKey == KEY_NONE)WaitKey(); //等待按键switch(WhichKey){case KEY_ESC : if(NowKeyTab.PressEsc != MENU_NO) {MenuID =NowKeyTab.PressEsc;MenuNextID =NowKeyTab.MenuIndex;NowKeyTab = KeyTab[MenuID];NowKeyTab.PressOk =MenuNextID;(*NowKeyTab.CurrentOperate)(); //显示当前菜单}elseescflag =TRUE; //退出编程状态break;case KEY_OK : if(NowKeyTab.PressOk != MENU_NO) {MenuID =NowKeyTab.PressOk;NowKeyTab = KeyTab[MenuID];MenuNextID =NowKeyTab.PressOk;}(*NowKeyTab.CurrentOperate)(); //执行当前按键的操作break;case KEY_UP : if((MenuNextID != MENU_NO) && (KeyTab[MenuNextID].PressUp != MENU_NO)){NowKeyTab.PressOk =KeyTab[MenuNextID].PressUp;MenuNextID = KeyTab[MenuNextID].PressUp;(*NowKeyTab.CurrentOperate)(); //执行当前按键的操作}break;case KEY_DOWN: if((MenuNextID != MENU_NO) && (KeyTab[MenuNextID].PressDown != MENU_NO)){NowKeyTab.PressOk =KeyTab[MenuNextID].PressDown;MenuNextID = KeyTab[MenuNextID].PressDown;(*NowKeyTab.CurrentOperate)(); //执行当前按键的操作}break;case KEY_RESET: ResetFlag = TRUE;break;default : break;}}while(!ResetFlag && !EscFlag && !escflag);if(ChangeFlag && !EscFlag && !ResetFlag) EditDataChange();if(ResetFlag)return SYS_RESET;else{return 0;}}关于这个菜单的说明:1.我用的是ARM处理器,所以51的时候把const改成code,uint32改成unsign ed char。

51单片机实现多级液晶显示中文菜单共5页word资料

51单片机实现多级液晶显示中文菜单共5页word资料

51单片机实现多级液晶显示中文菜单一、引言目前小型的显示器主要有LCD和LED,LED显示器只能显示数字和有限个英文字符,不能显示汉字,显示内容不直观,操作人员只能根据约定格式了解显示内容。

而LCD则可显示各种汉字和图形,尤其能实现中文菜单显示,为操作者提供方便友好的操作界面,并且功耗低,因此LCD得到广泛应用。

而现在市面上带中文字库的LCD比比皆是,价格适中,且大部分具有与MCU统一的标准接口,为使用LCD实现中文菜单操作提供了很大的方便。

相信更多的电子产品在提升性能的同时,设计更加人性化的中文菜单交互界面,将会使产品具有更广阔的前景。

二、YM12864液晶显示模块简介YM12864汉字图形点阵液晶显示模块,可显示汉字及图形,内置8192个中文汉字(16X16点阵)、128个字符(8X16点阵)及64X256点阵显示RAM(GDRAM)。

主要技术参数和显示特性:电源:VDD 3.3V~+5V(内置升压电路,无需负压)显示内容:128列×64行与MCU接口:8位或4位并行/3位串行多种软件功能:光标显示、画面移位、自定义字符、睡眠模式等。

其引脚功能为通用20脚LCD接口,用户指令集也为通用128*64LCD 用户指令集,相关资料很容易获取。

因其内置中文字库,省去了自己造字库的工作量,而只需写入相应的汉字和字符内码即可显示所需要的汉字和字符,这在许多程序开发软件中很容易实现,如:WAVE、KEIL等。

所以使用带中文字库的LCD来实现中文菜单操会更加简便。

三、原理分析通常的人机交互界面有两种方式,选择菜单和输入参数,为了便于分析,本文使用三级树状菜单结构,如图1所示,来阐述中文菜单的显示原理。

因YM12864满屏能显示四行、每行八个汉字,故将四个选择或参数输入菜单项编为一页,不足一页的补空格。

补空格的目的是为了归一化操作,可大大简化程序。

每一个菜单、参数输入、空格都为固定的八个汉字空间。

图1中顶级菜单1、顶级菜单2、顶级参数输入3、顶级4构成一级菜单,四个菜单项为一页同时显示在液晶屏幕上;一级菜单1-1、一级菜单1-2、一级参数输入1-3、一级空格1-4构成了顶级菜单1下的二级菜单,也组成一页同时显示在液晶屏幕上,三级菜单也是如此。

12864液晶多级菜单设计

12864液晶多级菜单设计
索引号即用户想要执行哪个函数的代号,然后有三个键,用户可以自己定义别的按键,最后一个是函数指针,即索引号对应的函数。然后在定 义一个结构体数组,如下 key_table code table[n]= { {0,2,1,3,(*fun1)}, {1,0,2,4,(*fun2)}, {2,1,0,5,(*fun3)}, {3,0,6,3,(*fun4)}, {4,1,6,4,(*fun5)}, {5,2,6,5,(*fun6)}, {6,0,0,0,(*fun7)}, ............ }; 其中 n 为函数数组大小。下面详细介绍 key_table code table[n]里面的值是怎么确定的。 首先可以先这样定义该数组 key_table code table[n]= { {0,x,y,z,(*fun1)}, {1,x,y,z,(*fun2)}, {2,x,y,z,(*fun3)}, {3,x,y,z,(*fun4)}, {4,x,y,z,(*fun5)}, {5,x,y,z,(*fun6)}, {6,x,y,z,(*fun7)}, ............ }; 其中,x,y,z 是未知数,先不确定,他们对应的是三个键按下要指示的索引值,如果四个键,就有四个未知数,在确定他们之前,必须要了解自己函数执行什么命令。加入开始时 时执行数组里面的第一个即 table[0],而想在此按上键执行函数 fun6,那么 table[0]里面需要这样设置{0,5,y,z,(*fun1) }, 同样,如果希望按下键执行 fun7则需要设置为{0,x,6,z,(*fun1) } , 如果希望按确认键执行 fun3则需要设置为{0,x,y,2,(*fun1) } ; 如果上面三种情况都想要就设置为{0,5,6,2,(*fun1) }. 其它数组元素一次类推。这一步做完了看主程序里面(主要是 while(1)里面) 。 /*******************find index****************************/ switch(key) { case 0x44: break; case 0x24: break; case 0x14: break; default:break; } current_operation_index=table[func_index].current_operation; (*current_operation_index)();// 执行当前操作函数 其中,key 是返回的按键值,这个用户视情况而定, 下面是详细的例子, 主要是以结构体为基础设计的,以12864显示函数代替了用户需要的函数功能,只需要修改相应的函数和索引号,就可以达到任意界面切换了是小弟研究了还久才搞定的,虽然网 上也有这些,但是都不够系统,只有基本的东西,这篇例子希望能够给读者一些有用的东西,仅供参考哦! : #include <reg52.h> #include "fun.h" func_index=table[func_index].down;// 向下翻 func_index=table[func_index].enter;// 回车 func_index=table[func_index].up; // 向上翻

(完整版)单片机多级菜单编程实现

(完整版)单片机多级菜单编程实现

单片机多级菜单编程实现单片机多级菜单编程实现(ZT)建立一个树状的菜单结构,用链表实现链表中包含:1、指向同级左右菜单和指向父菜单、子菜单的四个菜单结构体指针;2、进入该菜单时需要执行的初始化函数指针3、退出该菜单时需要执行的结束函数指针4、该菜单内的按键处理函数指针数组的指针操作菜单模块需要的按键操作有:左、右、确认、退出。

采用这种办法,可以方便的添加或删减菜单。

并且只需要在其头文件中修改初始变量就可以实现,完全无须修改C文件中的任何函数。

具体结构定义我的定义,做个参考:#define MENU_HLP_EN //菜单帮助信息使能typedef struct{void (*pMenuTaskInit)(void); //指向菜单任务初始化函数的指针void (*pMenuTaskEnd)(void); //指向菜单任务结束函数的指针}MENU_TASK_TYP;typedef struct MenuTyp{INT8U *MenuName; //菜单名称字符串WORK_MOD WorkMod; //工作状态编号MENU_TASK_TYP *pMenuTask; //指向菜单任务的指针void (**pTaskKeyDeal)(void); //指向菜单任务按键处理函数数组的指针#ifdef MENU_HLP_ENINT8U *MenuHlp; //菜单帮助字符串#endifstruct MenuTyp *pParent; //指向上层菜单的指针struct MenuTyp *pChild; //指向子菜单的指针struct MenuTyp *pRight; //指向右菜单的指针struct MenuTyp *pLeft; //指向左菜单的指针}MENU_TYP;我根据网上的资料做的一个菜单:/****************菜单数据结构**********************/struct KeyTabStruct{uint8 MenuIndex; //当前状态索引号uint8 MaxItems; //本级菜单最大条目数uint8 ShowLevel; //菜单显示内容uint8 PressOk; //按下"回车"键时转向的状态索引号uint8 PressEsc; //按下"返回"键时转向的状态索引号uint8 PressDown; //按下"向下"键时转向的状态索引号uint8 PressUp; //按下"向上"键时转向的状态索引号void (*CurrentOperate)(); //当前状态应该执行的功能操作};uint8 MenuID; //菜单ID号uint8 MenuNextID; //下级菜单ID号//CurMenuID=本菜单ID//MaxMenuItem=同级菜单最大项数//OkMenuID=子菜单层所对应的菜单ID,ID=999为菜单已经到底了//EscMenuID=父菜单层所对应的菜单ID,ID=999为菜单已经到顶了//DownMenuID=弟菜单层所对应的菜单ID,ID=999为菜单是独生子//UpMenuID=兄菜单层所对应的菜单ID,ID=999为菜单是独生子//CurFunction=本菜单所对应的菜单函数指针const struct KeyTabStruct KeyTab[MAX_KEYTABSTRUCT_NUM]={//CurMenuID, axMenuItem, MenuShowLevel, OkMenuID, EscMenuID, DownMenuID, UpMenuID, CurFunction{MENU_EDIT, 0, 0, MENU_DATA_VIEW, MENU_NO, MENU_NO, MENU_NO, *MenuEdit},{MENU_DATA_VIEW, 3, 1, MENU_DATA_VIEW_FIRE, MENU_EDIT, MENU_ SYS_EDIT, MENU_PRINT_DATA,*MenuEdit},{MENU_DATA_VIEW_FIRE, 5, MENU_NO, MENU_NO, MENU_DATA_VIEW, MENU_DATA_VIEW_TROUBLE, MENU_STEP_FOLLOW, *MenuDataViewIn}, {MENU_DATA_VIEW_TROUBLE, 5, MENU_NO, MENU_NO, MENU_DATA_VI EW, MENU_DATA_VIEW_REPEAT, MENU_DATA_VIEW_FIRE, *MenuDataVie wIn},{MENU_DATA_VIEW_REPEAT, 5, MENU_NO,MENU_NO, MENU_DATA_VIEW, MENU_FACE_CHECK,MENU_DATA_VIEW_TROUBLE, *MenuDataViewIn},{MENU_FACE_CHECK, 5, MENU_NO,MENU_NO, MENU_DATA_VIEW, MENU_STEP_FOLLOW,MENU_DATA_VIEW_REPEAT, *MenuFaceCheck},{MENU_STEP_FOLLOW, 5, MENU_NO,MENU_NO, MENU_DATA_VIEW, MENU_DATA_VIEW_FIRE, MENU_FACE_CH ECK,*MenuStepFollow},{MENU_SYS_EDIT, 3,2, MENU_SUM_SET, MENU_EDIT,MENU_PRINT_DATA, MENU_DATA_VIEW, *MenuEdit},{MENU_SUM_SET, 6, MENU_NO,MENU_NO, MENU_SYS_EDIT, MENU_EDIT_INSULATE,MENU_TIME_SET, *MenuSumSet},{MENU_EDIT_INSULATE, 6, MENU_NO,MENU_NO, MENU_SYS_EDIT, MENU_EDIT_HZ, MENU_SUM_SET,*MenuEditInsulate},{MENU_EDIT_HZ, 6, MENU_NO,MENU_NO, MENU_SYS_EDIT, MENU_LD_CONTROL,MENU_EDIT_INSULATE, *MenuEditHZ},{MENU_LD_CONTROL, 6,MENU_NO, MENU_NO, MENU_SYS_EDIT, MENU_LD_DELAY,MENU_EDIT_HZ, *MenuLDControl},{MENU_LD_DELAY, 6,MENU_NO, MENU_NO, MENU_SYS_EDIT, MENU_TIME_SET,MENU_LD_CONTROL, *MenuLDDelay},{MENU_TIME_SET, 6, MENU_NO,MENU_NO, MENU_SYS_EDIT, MENU_SUM_SET, MENU_LD_DELAY,*MenuTimeSet},{MENU_PRINT_DATA, 3, 3,MENU_PRINT_DATA_FIRE, MENU_EDIT, MENU_DATA_VIEW,MENU_SYS_EDIT, *MenuEdit},{MENU_PRINT_DATA_FIRE, 4,MENU_NO, MENU_NO, MENU_PRINT_DATA,MENU_PRINT_DATA_TROUBLE, MENU_PRINT_SET, *MenuPrintDataIn}, {MENU_PRINT_DATA_TROUBLE, 4, MENU_NO,MENU_NO, MENU_PRINT_DATA, MENU_PRINTER_CHECK,MENU_PRINT_DATA_FIRE, *MenuPrintDataIn},{MENU_PRINTER_CHECK, 4, MENU_NO,MENU_NO, MENU_PRINT_DATA, MENU_PRINT_SET,MENU_PRINT_DATA_TROUBLE, *MenuPrintDataIn},{MENU_PRINT_SET, 4, MENU_NO,MENU_NO, MENU_PRINT_DATA, MENU_PRINT_DATA_FIRE,MENU_PRINTER_CHECK, *MenuPrintSet},};/**************************************编程菜单显示数据******************************/const struct MenuDispData MenuEditShow[][MENU_MAX] = {{{MENU_NO , 0, 0, "选择: 消音→退出"}, //主菜单{MENU_DATA_VIEW , 1, 6, "⒈数据查看"},{MENU_SYS_EDIT , 2, 6, "⒉系统编程"},{MENU_PRINT_DATA , 3, 6, "⒊数据打印"}},{{MENU_NO , 0, 0, "数据查看: 消音→退出"}, //数据查看{MENU_DATA_VIEW_FIRE , 1, 4, "⒈火警"},{MENU_DATA_VIEW_TROUBLE, 2, 4, "⒉故障"},{MENU_DATA_VIEW_REPEAT , 3, 4, "⒊重码"},{MENU_FACE_CHECK , 1,12, "⒋面板检测"},{MENU_STEP_FOLLOW , 2,12, "⒌单步跟踪"}},{{MENU_NO , 0, 0, "系统编程: 消音→退出"}, //系统编程{MENU_SUM_SET , 1, 0, "⒈容量设置"},{MENU_EDIT_INSULATE , 2, 0, "⒉隔离点"},{MENU_EDIT_HZ , 3, 0, "⒊汉字描述"},{MENU_LD_CONTROL , 1,12, "⒋联动控制"},{MENU_LD_DELAY , 2,12, "⒌模块延时"},{MENU_TIME_SET , 3,12, "⒍时钟调整"}},{{MENU_NO , 0, 0, "数据打印: 消音→退出"}, //数据打印{MENU_PRINT_DATA_FIRE , 1, 0, "⒈火警数据"},{MENU_PRINT_DATA_TROUBLE,2, 0, "⒉故障数据"},{MENU_PRINTER_CHECK , 3, 0, "⒊打印机自检"},{MENU_PRINT_SET , 1,12, "⒋打印设置"}},};/***********************************等待按键******************** **************/void WaitKey(void){uint32 time;time = RTCFlag;WhichKey = KEY_NONE;while(!EscFlag){if(RTCFlag - time >= EDIT_TIME)EscFlag = TRUE;if(WhichKey != KEY_NONE){KeySound(300); //按键音return;}}}/*********************************显示多级菜单**********************************/void MenuEdit(){uint32 i,j=0;uint32 oldid;j = KeyTab[MenuID].ShowLevel;if(WhichKey == KEY_ESC || WhichKey == KEY_OK){ClearScreen();for(i=0;i<KeyTab[MenuNextID].MaxItems+1;i++) ShowString(MenuEditShow[j][i].Lin,MenuEditShow[j] [i].Column,MenuEditShow[j][i].Pdata,0); //初始化显示oldid =0;//没有原先选择的项}else{if(WhichKey == KEY_UP)oldid = KeyTab[MenuNextID].PressDown;elseoldid = KeyTab[MenuNextID].PressUp;//指示原先的项}for(i=1;i<KeyTab[MenuNextID].MaxItems+1;i++){if(MenuEditShow[j][i].Id == oldid)ShowString(MenuEditShow[j][i].Lin,MenuEditShow[j][i].Column,MenuEditShow[j][i].Pdata,0); //正常显示原先的项else{if(MenuEditShow[j][i].Id == MenuNextID)ShowString(MenuEditShow[j][i].Lin,MenuEditShow[j][i].Column,MenuEditShow[j][i].Pdata,1); //反显当前选择的项}}WhichKey = KEY_NONE;}/******************************系统编程************************* ******/uint32 Edit(void){struct KeyTabStruct NowKeyTab; //指示当前的菜单值uint32 escflag = FALSE;ResetFlag = FALSE;ChangeFlag = FALSE;EscFlag = FALSE;MenuID = MENU_EDIT;NowKeyTab = KeyTab[MenuID];MenuNextID = NowKeyTab.PressOk;(*NowKeyTab.CurrentOperate)(); //显示主菜单do{if(WhichKey == KEY_NONE)WaitKey(); //等待按键switch(WhichKey){case KEY_ESC : if(NowKeyTab.PressEsc != MENU_NO) {MenuID =NowKeyTab.PressEsc;MenuNextID =NowKeyTab.MenuIndex;NowKeyTab = KeyTab[MenuID];NowKeyTab.PressOk =MenuNextID;(*NowKeyTab.CurrentOperate)(); //显示当前菜单}elseescflag =TRUE; //退出编程状态break;case KEY_OK : if(NowKeyTab.PressOk != MENU_NO) {MenuID =NowKeyTab.PressOk;NowKeyTab = KeyTab[MenuID];MenuNextID =NowKeyTab.PressOk;}(*NowKeyTab.CurrentOperate)(); //执行当前按键的操作break;case KEY_UP : if((MenuNextID != MENU_NO) && (KeyTab[MenuNextID].PressUp != MENU_NO)){NowKeyTab.PressOk =KeyTab[MenuNextID].PressUp;MenuNextID = KeyTab[MenuNextID].PressUp;(*NowKeyTab.CurrentOperate)(); //执行当前按键的操作}break;case KEY_DOWN: if((MenuNextID != MENU_NO) && (KeyTab[MenuNextID].PressDown != MENU_NO)){NowKeyTab.PressOk =KeyTab[MenuNextID].PressDown;MenuNextID = KeyTab[MenuNextID].PressDown;(*NowKeyTab.CurrentOperate)(); //执行当前按键的操作}break;case KEY_RESET: ResetFlag = TRUE;break;default : break;}}while(!ResetFlag && !EscFlag && !escflag);if(ChangeFlag && !EscFlag && !ResetFlag) EditDataChange();if(ResetFlag)return SYS_RESET;else{return 0;}}关于这个菜单的说明:1.我用的是ARM处理器,所以51的时候把const改成code,uint32改成unsign ed char。

菜单

菜单
break;
case(VK_ENTER):
returnቤተ መጻሕፍቲ ባይዱ1);
break;
case(VK_UP):
return(2);
break;
case(VK_DOWN):
return(3);
break;
}
}
unsigned char Change_Value(unsigned char temp2)
TMenu * pMenu = (TMenu *)arg;
char key;
if (pMenu) {
key = pMenu->EventArg;
OnSelectMainMenu(key - '1');
DrawMenu(pMenu);
}
return 0;
}
void InitMenu()
case 0:
TextOut(0, 1, "室内调整开始 ");
tempin=Change_Value(tempin);
TextOut(0, 1, "室内调整完毕");
Delay_1(300000);
break;
case 1:
TextOut(0, 1, "室外调整开始 ");
tempout=Change_Value(tempout);
uchar keycrstate ; / / 按下“回车”键时转向的状态索引号
uchar keybackstate ; / / 按下“退回”键时转向的状态索引号
void ( 3 currentoperate) ( ) ; / / 当前状态应该执行的

单片机汇编语言下LCD多级菜单的一种实现方法

单片机汇编语言下LCD多级菜单的一种实现方法
的 DB ~ B 0 D 7相 连 , 1 P. 0与 E 口相 连 ,P . 11与 R W 口 相 连 , 1 / P. 2与 R S
口相连 。S 7 2 T 9 0包 含 基本 指 令集 和 扩 展 指 令 集 , 于 篇 幅 这 里 不 作 介 L D i: C L E A 4 MS; 光 标 的 画 面 初 始 限 C jN l L A LD L Y 0 带 绍 , 细 功 能 可查 阅 S 7 2 详 T 9 0中文 使 用 手 册 。 MOV H A. 30
魁射》0 肆m s

1 硬 件 设 计
11 单 片机 选 型 . S C 9 5 RD 是 宏 晶 公 司 生 产 的 低 电 压 、 高 性 能 的 单 片 机 , T 8C 8 + 与 MC 一 1产 品 指 令 系 统 完 全兼 容 。工 作 频率 在 0 一 0 z之 间 可 选 , S5 Hz 8MH
为 了 使 L D 正 常 工 作 ,在 系 统 上 电 时 必 须 对 S 7 2 C T 9 0进 行 初 始 化 . 程 如 图 2所 示 流
匕 警殳 j
疆霹 阡 薨


xR£S r 瓿 一 > 蹴
拄髓字 0 f Cj l - I
越 稚 1 0 ¥ u 0
f 摘 要 】 文 介 绍 了通 过 汇编 语 言在 L D 液 晶 显 示屏 上 实 现 多级 嵌 套 菜 单 的 一 种 方 法 , 出 了一 个 结 构 紧凑 、 本 C 给 实用 的 程 序 模 型 。 【 键 词 】 片机 ; 关 单 多级 菜单 ;T 9 0 S 7 2
O 引 言 近 年 来 , 单 片 机 系 统 中 L D 的 使 用 越 来 越 普 及 , 使 得 在 基 于 在 C 这

LCD12864 多级菜单

LCD12864 多级菜单
Lcd_Write_Data(mode); Lcd_Write_Data(mode); } } Lcd_Write_Cmd(0x36); //写完数据,开图形显示 }
searchMenu.subMenus = malloc(sizeof(&searchMenu)*6); searchMenu.subMenus[0] = searchMenu.subMenus[1] = searchMenu.subMenus[2] = searchMenu.subMenus[3] = searchMenu.subMenus[4] = searchMenu.subMenus[5] = NULL; searchMenu.func = malloc(sizeof(&printf)*6); searchMenu.func[0] = searchMenu.func[2] = searchMenu.func[2] = searchMenu.func[3] = searchMenu.func[4] = searchMenu.func[5] = NULL; searchMenu.parent = &MainMenu;//上一级菜单是MainMenu.进入查询 子菜单后按返回键,将会显示这个菜单 项
Lcd_Write_Data(*s); s++; } Lcd_Write_Cmd(0x36); //返回图形模式 }
void highlight(uchar x,uchar y,uchar width,u8 mode)
//反
白,X值为0-7,Y值为0-3,width为行反白格数
{
uchar i,j,flag=0x00;
break; } case 8://向下 if(currentMenu->selected == currentMenu->itemCount-1) break; else { currentMenu->selected++; if(currentMenu->selected>currentMenu->range_to) {

液晶12864分级菜单思想

液晶12864分级菜单思想

液晶12864 分级菜单编程思想喜欢单片机的人,想必对液晶12864应该不会陌生。

对于单片机来说,如果用于显示,12864是个不错的选择,编程既简单,而资源消耗又符合单片机的使用要求,是理想的选择。

下面就我做有关单片机的一点心得分享一下我在编写液晶12864的一点思想,希望能个喜欢这些东西的同志们有所启发。

以下是我项目中分级菜单的源文件:(一个12864的五级菜单)/**************************************分级菜单***************************************/#include"STC15F2K.H"#include"KEY.H"#include"LCD.H"#include"LIST.H"#include"YINGY.H"#include"HCSR04.H"#include"HONGW.H"#include "PCF8563.H"/**************************************变量定义***************************************/uchar wendT=30; //温度上限bit fg=0;uchar key = 0; //键值获得//uchar keyq = 0; //子菜单项标志uchar flagk = 0;uint flag = 0; //菜单标志bit flag_ms = 0; //智能模式和安全模式标志位uchar timeflag=0; //时间设置标志位uchar shi=7,fen=0,miao=0; //闹钟标志位uchar ms_h1=6,ms_m1=0,ms_h2=22,ms_m2=0; //时间标志位bit bing_nao = 0; //闹钟开启标志位uchar code l1[] = "年";uchar code l2[] = "月";uchar code l3[] = " ";uchar code l4[] = "时";uchar code l5[] = "分";uchar code l6[] = " ";uchar code l7[] = ":";uchar code l8[] = "为";/**************************************函数声明**************************************/void fenjcd();void yiji_menu();void erji_menu();void sanjims_menu();void sanjiqt_menu();void xiug_time(); //时间修改void ms_back();void qt_back();void siji_nao();void nao_time();void ms_time();void wenduT();/**************************************总菜单**************************************/void fenjcd(){yiji_menu();erji_menu();sanjims_menu();sanjiqt_menu();xiug_time(); //时间修改ms_back();qt_back();siji_nao();nao_time();ms_time();}/**************************************一级菜单**************************************/void yiji_menu(){key=getKey();if(flag==0){if(key==1||IR_code==0x45) //进入功能选择页面{write_com(0x01);write(0x81,lis2);write(0x90,lis21);write(0x88,lis23);write(0x98,lis25);write_com(0x0c);flagk = 1;flag = 1;key = 0;IR_code=0;}}if(flag == 1){if(key == 1||IR_code==0x45) //返回正常页面{write_com(0x01);write(0x82,lis1);write(0x90,lcd_date_H);write(0x88,lisk1);write(0x98,lcd_T);write(0x9c,lcd_H);write_com(0x0c);flag = 0;flagk = 0;key = 0;IR_code=0;}}}/**************************************二级菜单**************************************/void erji_menu(){if(flag==1){if(key==2||IR_code==0x40) //菜单选项加1{keyq++; //功能设置选择中if(keyq == 1){write(0x90,lis20);write(0x88,lis24);write(0x98,lis25);}else if(keyq == 2){write(0x90,lis20);write(0x88,lis23);write(0x98,lis26);}IR_code=0;if(keyq>=3) keyq = 0;if(keyq == 0){write(0x98,lis25);write(0x90,lis21);write(0x88,lis23);}}if(key==4||IR_code==0x47) //进入选中页面{if(keyq == 0) //进入时间设置页面{flag = 20; //时间设置编码write_com(0x01);write(0x82,lis30);write(0x90,lisk0);write(0x89,lisk1);write_num(0x90,year_1);//LCD显示write_num(0x91,time.year);write_num(0x93,time.month);write_num(0x95,time.day);write_num(0x89,time.hour);write_num(0x8b,time.minute);write_num(0x8d,time.second);keyq = 0;key=0;IR_code=0;}if(keyq == 1) //进入模式设置页面{flag=21;write_com(0x01);write(0x82,lis31);write(0x90,lis311);write(0x88,lis312);keyq = 0;key=0;IR_code=0;}if(keyq == 2) //进入其它设置页面{flag=22;write_com(0x01);write(0x82,lis32);write(0x90,lis321);write(0x88,lis322);write(0x98,lis324);keyq = 0;key=0;IR_code=0;}}}}/**************************************三级菜单**************************************///三级模式void sanjims_menu(){if(flag == 21) //模式选择{if(key==2||IR_code==0x40) //菜单选项加1{keyq++; //模式选择中if(keyq == 1){write(0x90,lis310);write(0x88,lis313);}IR_code=0;if(keyq>=2) keyq = 0;if(keyq == 0){write(0x88,lis312);write(0x90,lis311);}}if(key==4||IR_code==0x47) //进入选中页面{if(keyq == 0) //开启智能模式{flag = 210; //智能模式编码flag_ms = 0;write_com(0x01);write(0x82,lis1);write(0x90,lis430);write(0x88,lis432);write(0x99,lis433);keyq = 0;key = 0;IR_code=0;}if(keyq == 1) //开启安全模式{flag = 211; //安全模式编码flag_ms = 1;write_com(0x01);write(0x82,lis1);write(0x88,lis431);keyq = 0;key=0;IR_code=0;}}}if(flag == 21) //返回功能设置页面{if(key == 1||IR_code==0x45){write_com(0x01);write(0x81,lis2);write(0x90,lis21);write(0x88,lis23);write(0x98,lis25);write_com(0x0c);flag = 1;key=0;IR_code=0;}}}//三级其它void sanjiqt_menu(){if(flag == 22) //其它设置选择{if(key==2||IR_code==0x40) //菜单选项加1{keyq++; //其它设置项选择中if(keyq == 1){write(0x90,lis320);write(0x88,lis323);write(0x98,lis324);}else if(keyq == 2){write(0x90,lis320);write(0x88,lis322);write(0x98,lis325);}IR_code=0;if(keyq>=3) keyq = 0;if(keyq == 0){write(0x98,lis324);write(0x90,lis321);write(0x88,lis322);}}if(key==4||IR_code==0x47) //进入选中页面{if(keyq == 0) //进入闹钟设置{flag = 220; //闹钟设置编码write_com(0x01);write(0x82,lis40);write(0x90,lis401);write(0x88,lis402);keyq = 0;key = 0;IR_code=0;}if(keyq == 1) //进入温度上限设置**{flag = 221; //温度上限设置write_com(0x01);write(0x81,lis41);write(0x88,lis410);write_com(0x0c);keyq = 0;key = 0;IR_code=0;}if(keyq == 2) //进入遥控器解码{flag = 222; //遥控解码编码write_com(0x01);write(0x82,lis42);write(0x90,lis420);write(0x98,lis421);keyq = 0;key=0;IR_code=0;}}}if(flag == 22) //返回功能设置页面{if(key == 1||IR_code==0x45){write_com(0x01);write(0x81,lis2);write(0x90,lis21);write(0x88,lis23);write(0x98,lis25);write_com(0x0c);flag = 1;key=0;IR_code=0;}}}/*******************************************时间设置********************************************/void xiug_time(){if(flag==20){if(key == 1||IR_code==0x45){if(timeflag == 0) //秒{write_com(0x0f);write_num(0x8d,time.second);write(0x8c,l5);}else if(timeflag == 1) //分{write_com(0x0f);write_num(0x8b,time.minute);write(0x8a,l4);}else if(timeflag == 2) //时{write_com(0x0f);write_num(0x89,time.hour);write(0x88,l6);}else if(timeflag == 3) //天{write_com(0x0f);write_num(0x95,time.day);write(0x94,l2);}else if(timeflag == 4) //月{write_com(0x0f);write_num(0x93,time.month);write(0x92,l1);}else if(timeflag == 5) //年{write_com(0x0f);write_num(0x91,time.year);write_num(0x90,year_1);}timeflag++;IR_code=0;if(timeflag>6)timeflag = 0;}if(key == 3||IR_code==0x15) //数值加1{if(timeflag == 1) //秒{time.second++;if(time.second>=60)time.second=0;write_num(0x8d,time.second);write(0x8c,l5);}else if(timeflag == 2) //分{time.minute++;if(time.minute>=60)time.minute=0;write_num(0x8b,time.minute);write(0x8a,l4);}else if(timeflag == 3) //时{time.hour++;if(time.hour>=24) time.hour=0;write_num(0x89,time.hour);write(0x88,l6);}else if(timeflag == 4) //天{time.day++;if(time.day>=31)time.day=1;write_num(0x95,time.day);write(0x94,l2);}else if(timeflag == 5) //月{time.month++;if(time.month>=13)time.month=1;write_num(0x93,time.month);write(0x92,l1);}else if(timeflag == 6) //年{time.year++;write_num(0x91,time.year);write_num(0x90,year_1);}IR_code=0;}if(key==4||IR_code==0x47) //返回正常显示页面{settime();write_com(0x01);write(0x82,lis1);write(0x90,lisk0);write(0x88,lisk1);write(0x98,lcd_T);write(0x9c,lcd_H);time_lcd();write_com(0x0c);flag = 0;flagk=0;timeflag = 0;key = 0;IR_code=0;}}}/******************************************* 模式选定返回设置********************************************/ void ms_back(){if(flag==211&&(key==1||IR_code==0x45)){write_com(0x01);write(0x82,lis31);write(0x90,lis311);write(0x88,lis312);write_com(0x0c);flag=21;key=0;IR_code=0;}}/********************************************** 温度上限设置**********************************************/ void wenduT(){if(flag==221){if(fg==0){write_num(0x8d,wendT);write(0x8c,l8);write_com(0x0c);}if(key == 3||IR_code==0x15) //数值加1{fg=1;wendT++;write_com(0x0f);write_num(0x8d,wendT);write(0x8c,l8);key=0;IR_code=0;}if(IR_code==0x07) //数值加1{fg=1;wendT--;write_com(0x0f);write_num(0x8d,wendT);write(0x8c,l8);key=0;IR_code=0;}}if(key==4||IR_code==0x47) //返回正常显示页面{write_com(0x01);write(0x82,lis1);write(0x90,lisk0);write(0x88,lisk1);write(0x98,lcd_T);write(0x9c,lcd_H);time_lcd();write_com(0x0c);flag = 0;flagk = 0;timeflag = 0;key = 0;fg=0;IR_code=0;} IR_code=0;}/*******************************************其它选项选定返回设置********************************************/void qt_back(){if((flag==221||flag==222||flag==220)&&(key==1||IR_code==0x45)){write_com(0x01);write(0x82,lis32);write(0x90,lis321);write(0x88,lis322);write(0x98,lis324);write_com(0x0c);flag=22;key=0;IR_code=0;}}/*******************************************闹钟选择设定********************************************/void siji_nao(){if(flag == 220) //闹钟选择{if(key==2||IR_code==0x40) //菜单选项加1{keyq++; //闹钟选择中if(keyq == 1){write(0x90,lis400);write(0x88,lis403);}IR_code=0;if(keyq>=2) keyq = 0;if(keyq == 0){write(0x88,lis402);write(0x90,lis401);}}if(key==4||IR_code==0x47) //进入选中页面{if(keyq == 0) //关闭闹钟{flag = 2200;bing_nao =0;write_com(0x01);write(0x82,lis40);write(0x88,lis405);keyq = 0;key = 0;IR_code=0;}if(keyq == 1) //开并设置闹钟{flag = 2201;bing_nao =1;write_com(0x01);write(0x82,lis40);write(0x90,lis404);write(0x89,lisk1);write_num(0x89,shi);write_num(0x8b,fen);write_num(0x8d,miao);keyq = 0;key=0;IR_code=0;}}}if(flag == 2200) //返回闹钟选择页面{if(key == 1||IR_code==0x45){write_com(0x01);write(0x82,lis40);write(0x90,lis401);write(0x88,lis402);write_com(0x0c);flag = 220;key=0;IR_code=0;}}}/*******************************************闹钟定时********************************************/void nao_time(){if(flag==2201){{if(key == 1||IR_code==0x45){if(timeflag == 0) //秒{write_com(0x0f);write_num(0x8d,miao);write(0x8c,l5);}else if(timeflag == 1) //分{write_com(0x0f);write_num(0x8b,fen);write(0x8a,l4);}else if(timeflag == 2) //时{write_com(0x0f);write_num(0x89,shi);write(0x88,l6);}timeflag++;IR_code=0;if(timeflag>3)timeflag = 0;}if(key == 3||IR_code==0x15) //数值加1{if(timeflag == 1) //秒{miao++;if(miao>=60)miao=0;write_num(0x8d,miao);write(0x8c,l5);}else if(timeflag == 2) //分{fen++;if(fen>=60)fen=0;write_num(0x8b,fen);write(0x8a,l4);}else if(timeflag == 3) //时{shi++;if(shi>=24)shi=0;write_num(0x89,shi);write(0x88,l6);}IR_code=0;}if(key==4||IR_code==0x47) //返回正常显示页面{write_com(0x01);write(0x82,lis1);write(0x90,lisk0);write(0x88,lisk1);write(0x98,lcd_T);write(0x9c,lcd_H);time_lcd();write_com(0x0c);flag = 0;flagk = 0;timeflag = 0;key = 0;IR_code=0;}}}}/*******************************************智能模式时间定时********************************************/void ms_time(){if(flag==210){{if(key == 1||IR_code==0x45){if(timeflag == 0) //分2{write_com(0x0f);write_num(0x9d,ms_m2);write(0x9c,l4);}else if(timeflag == 1) //时2{write_com(0x0f);write_num(0x9b,ms_h2);write(0x9a,l3);}else if(timeflag == 2) //分1{write_com(0x0f);write_num(0x8d,ms_m1);write(0x8c,l4);}else if(timeflag == 3) //时1{write_com(0x0f);write_num(0x8b,ms_h1);write(0x8a,l7);}timeflag++;IR_code=0;if(timeflag>4)timeflag = 0;}if(key == 3||IR_code==0x15) //数值加1 {if(timeflag == 1) //分2{ms_m2++;if(ms_m2>=60)ms_m2=0;write_num(0x9d,ms_m2);write(0x9c,l4);}else if(timeflag == 2) //时2{ms_h2++;if(ms_h2>=24)ms_h2=0;write_num(0x9b,ms_h2);write(0x9a,l3);}else if(timeflag == 3) //分1{ms_m1++;if(ms_m1>=60)ms_m1=0;write_num(0x8d,ms_m1);write(0x8c,l4);}else if(timeflag == 4) //时1{ms_h1++;if(ms_h1>=24)ms_h1=0;write_num(0x8b,ms_h1);write(0x8a,l7);}IR_code=0;}if(key==4||IR_code==0x47) //返回正常显示页面{write_com(0x01);write(0x82,lis1);write(0x90,lisk0);write(0x88,lisk1);write(0x98,lcd_T);write(0x9c,lcd_H);time_lcd();write_com(0x0c);flag = 0;flagk=0;timeflag = 0;key = 0;IR_code=0;}}}}。

液晶显示多级汉字菜单的方法及电路

液晶显示多级汉字菜单的方法及电路

液晶显示多级汉字菜单的方法及电路关键字:液晶显示多级汉字菜单的方法摘要:以8031单片机控制MGLS-240128液晶显示器为例,介绍利用CCDOS 中的汉字库(HZK16)实现多级汉字菜单显示的方法。

当显示内容改变时,不需要更改程序,只要更改菜单参数即可显示。

关键词:液晶显示器;MGLS-240128;汉字库;多级菜单1. 引言目前常用的小型显示器有LCD和LED ,LED显示器只能显示数字和有限个英文字符,不能显示汉字,显示内容不直观,操作人员只能根据约定格式了解显示内容。

而LCD则可显示各种汉字和图形,能实现中文菜单显示,便于操作,并且功耗低。

因此LCD得到广泛应用。

用LCD显示汉字时,一般采用自制汉字模和汉字编码,当显示内容较多时,字模库容量很大,汉字的编码亦很难记住,给编程造成困难,当显示内容改变时,字模库也要作相应变化,工作量大。

这里介绍一种直接利用CCDOS中的汉字库(HZK16)显示汉字多级菜单的方法。

将HZK16和菜单内容固化在EPROM中,从而方便地实现了多级汉字菜单的显示,充分发挥了LCD的优点。

2. MGLS-240128显示模块简介及接口电路本文使用的显示模块是MGLS-240128,它的点阵数是240×128,如显示16×16点阵的汉字,可显示8行,每行15个字。

MGLS-240128模块内藏HD61830控制器,模块的电原理框图如图1所示。

有时在菜单显示中,显示的页数很多。

为了便于在EPROM中定位,在计算机中编辑菜单时,应在每页菜单前加pxx:其中p表示一页开始,xx为该页序号,冒号表示以下为该页的内容。

回车可换行到下一行并进入中文编辑状态输入,需要显示的内容。

每页分8行,每行15个汉字或字符(包括空格)。

在编辑的文件中,每行结尾有回车、换行符。

这样,每一页菜单中,pxx以ASCII码形式存放,每个汉字以机器内码形式存放,每个机器内码占两字节。

一种单片机多级菜单的模块化设计方法

一种单片机多级菜单的模块化设计方法

一种单片机多级菜单的模块化设计方法引言在单片机设计中,往往需要在显示屏上显示多级操作菜单,每级菜单都有一些菜单项和对应的按键操作,以及为响应各种操作而执行的后续处理程序。

参考文献以函数指针为结构元素,把整个菜单结构拉伸成一个结构数组,内部包含了全部菜单项。

这种方法没有将菜单项数据与功能函数分开设计,而把菜单项数据写在功能函数中,当菜单项数据需要改变时,必须修改功能函数,这在很大程度上限制了程序的通用性,不利于程序的维护。

参考文献在前者的基础上略加改进,在原结构体中增加了菜单项显示文字和按键复用标识,这使得结构体较为庞大,且菜单项的文字内容非常固定,保存在EEPROM 中,无法灵活改变显示内容和位置。

参考文献引入Windows 系统下的窗口和消息机制实现多级菜单设计,该方法需要维护堆栈、消息队列和窗口定时器等,设计过于复杂。

本文旨在提供一个轻量级的单片机多级菜单实现方法,以较少的系统资源消耗和简单方便的方法完成菜单设计。

考虑到菜单程序需要具备3 个基本要素:一是每个菜单窗口要显示的内容;二是每个窗口对应的按键定义与响应;三是窗口内菜单项之间切换和窗口之间的切换机制。

因此,将菜单分为菜单窗口模块和键盘处理模块两部分,独立进行设计。

1 菜单窗口模块设计菜单窗口模块主要功能是按照菜单窗口切换机制,实时完成窗口的显示控制。

1.1 菜单窗口切换机制菜单窗口切换机制包括两点:一是不同窗口之间切换效果的实现;二是窗口内的同级菜单项之间滚动切换效果的实现。

为实现上述功能,定义了两个结构体MenuState 和MenuItems。

MenuState 定义如下:MenuState 是一个与窗口跳转和窗口显示有关的结构体数组,用于全局调度各窗口之间的切换。

其中,CurIndex 是窗口的索引值,用来标识当前窗口。

UpIndex、DnIndex、BackIndex 用来标识当有上页、下页、返回按键操作时,。

单片机C语言中LCD菜单的方法实现

单片机C语言中LCD菜单的方法实现
page 1
1995-2006 Tsinghua Tongfang Optical Disc Co., Ltd. All rights reserve d. 2006 年第 1 期 陆 铮等 : 单片机 C 语言下 L CD 多级菜单的一种实现方法 ,4 ,6 ,8 ,0 , ( 3 Modif yPoint) } , / 第一层 {5 / ,6 ,1 ,0 ,0 , ( 3 Cancel) } , / 第一层 {7 / … … ,0 ,0 ,0 ,0 , ( 3 Disab le) } , {54 void Get Keylnp ut (void) { ?51 ? 测点各方面的设置或查询 , 可通过 “向上” 向下” 、 “ 、 “回退” 确认 ” 个键或遥控器来实现对菜单的选 “ 、 4 择 。具体功能 : “向上” : 在本层菜 单的项目中向上移动进行 键 选择 ; “向下” : 在本层菜单的项目中向下移动进行 键 选择 ; “回退” : 取消本层的菜单设置 , 返回上层菜 键 单; “确认” : 确 认本层的菜单设置 , 进入下级菜 键 单。 可根据用户在菜单中的选择项对测点进行 某些 设置 ,或者进行某些特殊的显示 ,例如对某个测点的 实时曲线显示等 。 2 程序设计 }; KeyFuncIndex = Key Tab[ KeyFuncIndex ] . KeyCrState ; 根据需求 ,首先建立一个结构 ,并定义一个结构 变量 Kbd TabSt ruct 。结构 变量就是把多个不同类 型的变量结合在一起形成的一个组合型变量 , 构成 一个结构 的各个变量称为结构元素 。该结构中共有 6 个结构元素 ,分别是 5 个字符型和 1 个指针变量 , 5 个字符型变量分别为当前及各个按键的索引号 , State ; case 0xd0 :/ / 向上键 ,找出新的菜单状态编号 也就是操作的状态号 , 最后 1 个指针变量指向需执 行函数 。这样就可以做一 个结构数组 , 在结构数组 里为每一个菜单项编制一个单独的函数 , 并根据菜 单的 嵌套顺序排好本菜单项的索引号 ,以及本级菜 单项的上、 下卷动的索引号和上 、 下级菜单的索引号。 具体程序如下所述 : t ypedef st ruct { State ; State ; uchar KeyStateIndex ; / 当前状态索引号 / uchar KeyDnState ; / 按下 / “向下” 键时转向的状态索引号 uchar KeyUpState ; / 按下 / “向上” 键时转向的状态索引号 uchar KeyCrState ; / 按下 / “回车” 键时转向的状态索引号 uchar KeyBackState ; / 按下 / “ 退回” 键时转向的状态索引号 功能操作 void ( 3 CurrentOperate) ( ) ; / / 当前状态应该执行的 # define SIZE - O F KE YBD - M ENU 55 / 菜单总长度 / ,5 ,7 ,52 ,0 , ( 3 Set Clo seDown) } , / 第一层 {6 / ,53 ,53 ,0 ,1 , ( 3 OkSet CloseDown1) } , {52 ,52 ,52 ,0 ,1 , ( 3 OkSet CloseDo wn2) } , {53 switch ( stat us &0xf0) { … … bre ak ; … … break ; … … break ; … … break ; case 0 ; urn ; / 错误的处理 ret / break ; } case 0xe0 :/ / 回车键 ,找出新的菜单状 态编号 case 0xb0 :/ / 向下键 ,找出新的菜单状态编号 case 0x70 :/ / 回退键 ,找出新的菜单状态编号 } Kbd TabSt ruct ; } 3 结语 Kbd TabSt ruct code Key Tab[ SIZE - O F - KE YBD - MENU ] = { ,0 ,0 ,1 ,0 , ( 3 MainJob1) } , {0

一种易于移植的单片机液晶显示多级菜单设计

一种易于移植的单片机液晶显示多级菜单设计

单 的核心部分是 一个不依赖具体硬件和菜单 内容 的通用 的窗 口引擎。研 究和应 用表 明, 菜单设 计具有结构简 单、 该 使用 方便 、 用 占 资源少 以及 易于移植等特点。最后给 出一个在 F D 2 6 晶模块 上使 用此方法的应用案例。 , Y 18 4液 关 键词
中图分类号
s s ms y t .Ho e e ,g n rl L ip a n e in i a l t i c mp iae e w v r e e a CD d s ly me u d s s i l bt o l td,a d d e o a e t e p r b l y h rfr h o lx t n g te c n o s n th v h t i t ,t ee oe t e c mpe i i o a i y d v lp n d s se man e a c d t e c s l n r a e . I hs p p rwe i t d c h i d w a d me s g c a ims o id w e eo me ta y tm it n n e a h o tae ic e s d n t i a e n r u e t e w n o n s a e me h s fW n o s n n o n Op r n y tm ,a d d sg l lv lme u h o e o h n sau ie l i d w e gn h c o sn t e e d o p c i a d r e  ̄i g S s e n e i amu t e e n .T e c r ft eme u i n v ma n o n i e w ih d e o p n n s i ch wae n i w d e f r a d t e c n e to n . R s a c d a p iain s o a eme u d s n h st e c aa tr f i l t cu e a yt s ,l t e o r e n h o tn f me u e e h a p l t h w t t h n e i a h h ce so mpe sr tr ,e u e i l r s u c r n c o h t g r s u s o te c n u t n,p r b e a d s n n te e d o e p p rwe p e e ta p l ain e a l n i g i h Y 2 6 C d l . o s mp i o o t l o o .I h n ft a r s n n a p i t x mp e r nn n t e F D1 8 4 L D mo ue a n h e c o u
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

单片机C语言下LCD多级菜单的一种实现方法(转)2012-1-10 00:45阅读(1)
单片机菜单程序
#include
#include
#define SIZE_OF_KEYBD_MENU 20 //菜单长度
uchar KeyFuncIndex=0;
//uchar KeyFuncIndexNew=0;
void (*KeyFuncPtr)(); //按键功能指针
typedef struct
{
uchar KeyStateIndex; //当前状态索引号
uchar KeyDnState; //按下"向下"键时转向的状态索引号
uchar KeyUpState; //按下"向上"键时转向的状态索引号
uchar KeyCrState; //按下"回车"键时转向的状态索引号
void (*CurrentOperate)(); //当前状态应该执行的功能操作
} KbdTabStruct;
KbdTabStruct code KeyTab[SIZE_OF_KEYBD_MENU]=
{
{ 0, 0, 0, 1,(*DummyJob)},//顶层
{ 1, 2, 0, 3,(*DspUserInfo)},//第二层
{ 2, 1, 1, 9,(*DspServiceInfo)}, //第二层
{ 3, 0, 0, 1,(*DspVoltInfo)},//第三层>>DspUserInfo的展开
{ 4, 0, 0, 1,(*DspCurrInfo)},//第三层>>DspUserInfo的展开
{ 5, 0, 0, 1,(*DspFreqInfo)},//第三层>>DspUserInfo的展开
{ 6, 0, 0, 1,(*DspCableInfo)},//第三层>>DspUserInfo的展开...........
{ 9, 0, 0, 1,(*DspSetVoltLevel)}//第三层>>DspServiceInfo的展

..........
};
void GetKeyInput(void)
{
uchar KeyValue;
KeyValue=P1&0x07; //去掉高5bit
delay(50000);
switch(KeyValue)
{
case 1: //回车键,找出新的菜单状态编号
{
KeyFuncIndex=KeyTab[KeyFuncIndex].KeyCrState;
break;
}
case 2: //向上键,找出新的菜单状态编号
{
KeyFuncIndex=KeyTab[KeyFuncIndex].KeyUpState; break;
}
case 4: //向下键,找出新的菜单状态编号
{
KeyFuncIndex=KeyTab[KeyFuncIndex].KeyDnState; break;
}
default: //按键错误的处理
......
break;
}
KeyFuncPtr=KeyTab[KeyFuncIndex].CurrentOperate; (*KeyFuncPtr)();//执行当前按键的操作
}
//其中KeyTab的设计颇费尽心机。

相关文档
最新文档