1602多级菜单程序超经典.
单片机多级菜单编程实现

单片机多级菜单编程实现单片机多级菜单编程实现(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。
ms430DA程序 键盘输入 1602显示程序

#ifndef __1602_h__#define __1602_h__#include "main.h"void Delay_5ms();void Check_Busy();void Write_Cmd(uchar cmd);void Write_Dat(uchar dat);extern void Init_LcdPort();extern void Init_Lcd();extern void Print_String(uchar *str,uchar addr);#endif/**************************************************************************** 文件名:adc12.c编写者:czhang描述:ADC12模块程序。
用于14xx系列。
MCLK:DCO ACLK:32.768kHz版本:2005-4 V1.0*****************************************************************************/ #include "adc12.h"#define adc_rate0 0.6103515625 //定义ADC转换的倍率#define adc_rate1 6.103515625extern uchar start_dac;extern uint adc_temp;uint adc_value=0;unsigned char Wait=0; //等待转换结束的标志位0:没有结束;1:结束unsigned int AdMem[16]; //转换结果缓冲区#define AD_CI 10unsigned char AdCi=AD_CI; //单通道或者序列多次转换的转换次数#define DUO_CI 0 //0:单通道或者序列单次转换1:单通道或者序列多次转换/**************************************************************************** 初始化****************************************************************************/ void Adc12Init(){ADC12CTL0 &= ~ENC; //使AD模块处于初始状态ADC12CTL0 = MSC+REFON+REF2_5V+SHT0_15+SHT1_15; //使用内部2.5V参考电压,使用采样保持器。
一种易于移植的单片机液晶显示多级菜单设计

一种易于移植的单片机液晶显示多级菜单设计王勇【摘要】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位单片机系统通常可用资源较少,速度相对较慢,一般不适合部署操作系统,更谈不上图形引擎了。
-菜单程序设计word版

菜单程序设计菜单程序设计2010年12月05日星期日下午09:52菜单程序设计一、菜单菜单的基本作用:菜单的基本类型:几个常用术语:--菜单条出现在窗体标题的下面,包含每个菜单的标题。
--菜单包含命令列表或子菜单名。
--菜单中列出的每一项。
--从某个菜单项分支出来的另外的一个菜单。
具有子菜单的菜单项右边带有一个三角符号标志。
--分隔条是在菜单项之间的一条水平直线,用于修饰菜单。
--弹出式菜单是另一种形式的菜单,在按下鼠标右键时出现,它是一个上下文相关的菜单。
使用菜单编辑器可以为应用程序创建自定义菜单并定义其属性,利用这个编辑器,可以建立下拉式菜单,最多可达6层。
启动菜单编辑器的方法有4种(先选中一个窗体,使之为活动窗体):使用菜单"工具"/"菜单编辑器";启动后,弹出菜单设计窗口。
菜单编辑器窗口分为三个部分:数据区、编辑区和菜单项显示区。
1、数据区用来输入或修改菜单项、设置属性。
其中:隔线。
可在该文本框中输入数值,这个值用来在帮助文件(用HelpFile属性设置)中查找相应的帮助主题。
用来确定菜单或菜单项是否出现或在什么位置出现。
该列表有4个选项:0-None菜单项不显示2、编辑区共有7个按钮。
3、菜单项显示区(菜单列表)位于菜单设计窗口的下部,输入的菜单项在这里显示出来,并通过内缩符号(…)表明菜单项的层次。
条形光标所在的菜单项是"当前菜单项"。
说明:菜单项是一个总的名称,包括4个方面的内容:菜单名(菜单标题)、菜单命令、分隔线和子菜单。
内缩符号由4个点组成,它表明菜单项所在的层次,一个内缩符号(4个点)表示一层,两个内缩符号(8个点)表示两层…最多20个点,即5个内缩符号,它后面的菜单项为第六层。
如果一个菜单项前面没有内缩符号,则该菜单为菜单名,即菜单的第一层。
隔线。
下面通过一个简单的例子说明菜单程序设计的基本方法和步骤。
例1根据题意,可以将菜单分为3个主菜单项,分别为"计算加、减"、"计算乘、除"和"清除与退出",它们各有两个子菜单,即:"计算加、减"的子菜单项:加、减"计算乘、除"的子菜单项:乘、除"清除与退出"的子菜单项:清除、退出另外,为了输入和显示,再建立两个文本框(输入数据)和四个标签。
(完整版)单片机多级菜单编程实现

单片机多级菜单编程实现单片机多级菜单编程实现(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。
LCD12864菜单程序

一起来学LCD12864菜单程序(包含完整程序)一起来学LCD12864菜单程序(包含完整程序)/*-------------------------------------------项目名:家电中央控制系统工程程序名:显示MCU总体程序编写人:杜洋初写时间:2005年9月5日晚20时程序功能:实现液晶、语音部分的人机对话和总线的通信实现方法:用中断实现总线接收CPU说明:89S5212MHZ晶振接口说明:(详见初定义)信息说明:修改日志:NO.1--------------------------------------------*/;----------------------------------------初定义LCDDAT EQU P2RS EQU P3.5RW EQU P3.6E EQU P3.7REDLED EQU P3.4BACKLED EQU P3.1PLAY EQU P1.7STOPIN EQU P3.0LIN EQU P3.2SPDAT EQU P1XX2 EQU P0.0LT_RAM EQU 30HLR_RAM EQU 40HSP_RAM EQU 20HDIS1_RAM EQU 50HDIS2_RAM EQU 70HDIS3_RAM EQU 60HDIS4_RAM EQU 80HRR1 EQU 26HRR3 EQU 21HRR4 EQU 22HT0_RAM EQU 23HQR3_RAM EQU 24HQR2_RAM EQU 25HLCDDISPLAY EQU 26H ;菜单显示移位寄存器MENU_RAM EQU 27H;菜单位置寄存器ONOFFLCD EQU 28H;-------------------------------------程序入口ORG 0000HJMP LCD_STARTORG 0003HJMP LIN_INT0ORG 000BHJMP LED_T0ORG 0030H;--------------------------------------主程序开始LCD_START br>SETB PLAYMOV T0_RAM,#250MOV TMOD,#01HSETB ET0MOV TL0,#0B0H ;50MS 定时初值(T0计时用)MOV TH0,#3CH ;50MS定时初值CLR IT0SETB EX0SETB TR0SETB EAMOV DPTR,#TAB_0CALL START_LCD;-----自检程序CALL DL1SMOV MENU_RAM,#00HMOV DPTR,#TAB_HCALL START_LCDCLR LCDDISPLAY;--------------------------------------主循环体程序LCD_LOOP br>JB ONOFFLCD,DISPLAY_PROLCD_LOOP_1br>JMP LCD_LOOP;---------------------------- 菜单显示处理DISPLAY_PRO br>MOV A,MENU_RAMMOV DPTR,#MENUTAB_HOSTRLC AJMP @A+DPTRMENUNEXT br>CALL START_LCDCLR LCDDISPLAYCLR ONOFFLCDJMP LCD_LOOP;-------------------------MENUTAB_HOST:JMP HOST_H ;主菜单JMP HOST_1 ; 1,控制JMP HOST_2 ; 2,设置JMP HOST_3 ; 3,智能JMP HOST_4 ; 4,帮助<。
u8g2多级菜单原理

u8g2多级菜单原理u8g2是一款优秀的、高度可定制的微型图形库,适用于嵌入式系统和其他资源有限的平台。
它提供了许多功能强大的绘图函数,方便开发者进行图形界面的设计和实现。
其中,多级菜单是u8g2库中的一个重要功能,它可以帮助开发者设计复杂的菜单系统。
多级菜单的原理主要包括以下几个方面:菜单结构的定义、菜单项的创建和显示、菜单项的选择和操作。
首先,菜单结构的定义是多级菜单的基础。
开发者可以通过定义一组嵌套的菜单项来构建一个菜单树结构。
每个菜单项都包含一个名称和相应的操作函数,用于响应用户的选择和操作。
菜单项还可以有子菜单,从而构成多级菜单的结构。
可以用类似下面的代码定义一个简单的菜单结构:```typedef struct{const char *name; //菜单项名称void (*action)(void); //菜单项操作函数struct MenuItem *submenu; //子菜单} MenuItem;```其次,菜单项的创建和显示是实现多级菜单的关键。
在u8g2库中,可以使用绘图函数来创建和显示菜单项。
开发者可以根据菜单结构逐级创建菜单项,并使用u8g2库提供的函数进行绘制。
例如,可以使用`u8g2_DrawStr()`函数绘制菜单项的名称,使用`u8g2_DrawFrame()`函数绘制菜单项的边框等。
同时,还可以使用`u8g2_SendBuffer()`函数将绘制的菜单项显示在屏幕上。
可以用类似下面的代码创建和显示一个简单的菜单项:```void drawMenuItem(const char *name, bool selected){if(selected){u8g2_DrawBox(0, 0, 128, 16);u8g2_SetDrawColor(0);}else{u8g2_DrawFrame(0, 0, 128, 16);u8g2_SetDrawColor(1);}u8g2_DrawStr(2, 12, name);}void drawMenu(const MenuItem *menu, int selectedItem) {for(int i = 0; i < menuCount; i++){drawMenuItem(menu[i].name, i == selectedItem);}u8g2_SendBuffer();}```最后,菜单项的选择和操作是多级菜单的核心功能。
制作WINDOWS标准菜单方法(下拉菜单和右键多级菜单)

tMsAddItem(ControlHandle,menuItemNo,submenuItemNo,menuText)-----创建菜单项tMsGetItem(ControlHandle,menuItemNo,submenuItemNo)-----获取用户选择菜单tMsDisplayControl(ControlHandle,X,Y,Width,Height,Return)-----显示菜单函数1、执行界面预览,如图5.1和图5.2所示图5.1下拉列表菜单执行效果图5.2右键弹出式菜单执行效果2、程序的流程图如图5.3所示图5.3范例程序流程图3、操作步骤:1)新建一个文件,并调入外部函数tMsControls.u32的相关扩展函数:tMsAddItem(ControlHandle,menuItemNo,submenuItemNo,menuText)tMsGetItem(ControlHan dle,menuItemNo,submenuItemNo)tMsDisplayControl(ControlHandle,X,Y,Width,Height,Return)2)设置屏幕大小和背景3)创建中文下拉式菜单,程序流程如图5.4图5.4创建中文下拉式菜单程序流程我们知道,如果我们把文件File的属性Properties的“menubar”Options选上,如图5.5所示,则程序的运行窗口将出现一个“File”的下拉菜单,如果我们要制作全中文的菜单,当然要想办法把它“擦除”掉,而“File”下拉菜单是系统默认的,因此我们也建立一个和它同名的“File”下拉菜单,这样系统就认为这个“File”下拉菜单是用户所创建,理所当然我们可以用擦除图标把它擦除掉拉。
其它的步骤请看图5.4。
图5.5File文件的属性Properties范例设置4)创建下拉列表菜单和鼠标右键响应菜单。
(1)在计算图标“creatmenu”里写入如下程序代码:----下列代码创建弹出式菜单的句柄:----下列代码创建弹出式菜单的菜单选项列表:tMsAddItem(popupHandle,1,0,作者介绍)tMsAddItem(popupHandle,2,0,联系作者)tMsAddItem(popupHandle,3,0,-)----在选项2和选项3之间创建一条分隔线tMsAddItem(popupHandle,4,0,软件说明)tMsAddItem(popupHandle,5,0,软件教程)tMsAddItem(popupHandle,6,0,-)----在选项5和选项7之间创建一条分隔线tMsAddItem(popupHandle,7,0,退出系统)----下列代码为软件教程菜单项创建两个分隔开的子菜单选项,如不需要子菜单,可----以省略tMsAddItem(popupHandle,5,3,Director)----下列代码创建下拉列表式菜单的句柄:----下列代码创建下拉列表式菜单的菜单选项列表:tMsAddItem(droplisthandle,2,0,---------------------------)tMsAddItem(droplisthandle,3,0,郁金香BBS)tMsAddItem(droplisthandle,4,0,清音飞扬)tMsAddItem(droplisthandle,5,0,魔岩工作室)----下列代码是显示下拉列表式菜单tMsDisplayControl(droplisthandle,17,80,50,50,0)----下列代码在鼠标右键点击处,弹出一个前边设定好的弹出式菜单,----并将用户反馈(即用户所选择的菜单项)返回给变量popresult:popresult:=tMsDisplayControl(popupHandle,CursorX,CursorY,100,120,1)----下面是当用户选择弹出式菜单执行的相关操作的代码:ifpopresult=退出系统thenQuit()-----这里只是“退出系统”操作代码的样式范本图5.6右键响应弹出菜单的永久条件交互而另一个“Continue”交互“GO”就是下拉列表菜单的相关操作,计算图标的代码如下: ----将用户反馈(即用户所选择的菜单项)返回给变量DropReturnVar:DropReturnVar:=tMsGetItem(droplisthandle,0,0)----下面是当用户选择菜单后执行相关操作的代码,只是简单显示一个交互消息框而已。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
定义全局变量
**********************************************************************************************/
#define LCD_EN (1<<PA3) //0x08 portA3 out
#define LCD_DATA ((1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7)) //0xf0 portA4/5/6/7 out .
#define LCD_BUSY (1<<PA7) //测忙位
函数说明
-------------------------------------------------------------------ቤተ መጻሕፍቲ ባይዱ-------------------------*/
void LCD_init(void); //液晶初始化函数
void LCD_en_write(void); //液晶使能函数
void LCD_wait_Ready(void); //判断忙函数
void LCD_write_command(unsigned char command,unsigned char mang,unsigned char mingdata); //写命令或数据
void LCD_set_xy (unsigned char x, unsigned char y); //写显示坐标
LCD引脚定义
------------------------------------------------------------------------------------------
1602pin 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
地Vcc VL Rs Rw En D0 D1 D2 D3 D4 D5 D6 D7灯+灯-
#defineDS1302_PORT PORTC
#defineDS1302_DDR DDRC
#defineDS1302_PIN PINC
#defineT_CLK PC0
#defineT_IO PC1
#defineT_RST PC2
/******************************************************************** */
头文件
------------------------------------------------------------------------------------------*/
#include <avr/io.h>
/*-----------------------------------------------------------------------------------------
void v_Setdd1302(unsigned char ucAddr,unsigned char pSecDa); //写某一位的时钟
/*************************************************************************************************
进制转换
************************************************************************************************/
yy[6]=(buffer3[0]>>4)+'0';
yy[7]=(buffer3[0]&0x0f)+'0';
}
void Hex_to_LCD_day(char* P) //日期BCD码转换成字符写入缓冲区
{
zz[0]=(buffer3[6]>>4)+'0';
zz[1]=(buffer3[6]&0x0f)+'0';
volatile unsigned char key_value=0; //存储键值的变量
volatile unsigned char screen_status=0; //菜单状态变量
// 0 1 2 3 4 5 6
static char buffer3[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //秒分时日月星期年
/*********************************************************************/
/*实时时钟模块时钟芯片型号:DS1302 */
/*********************************************************************/
zz[3]=(buffer3[4]>>4)+'0';
zz[4]=(buffer3[4]&0x0f)+'0';
zz[6]=(buffer3[3]>>4)+'0';
zz[7]=(buffer3[3]&0x0f)+'0';
}
/*--------------------------------------------------------------------------------------------
void LCD_write_struutg(unsigned char X,unsigned char Y,unsigned char *s,unsigned char i);
void delay_nus(unsigned int n); //微妙延时8M不准
void delay_nms(unsigned int n); //毫秒延时8M是准确
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s); //字符串写入
void LCD_write_single(unsigned char X,unsigned char Y,unsigned char *s); //写入数组的单个原数
//********************************************************* // 80 82 84 86 88 8a 8c
static char yy[]={" : : "}; // 0 3 6
//小时分钟秒小时分钟秒
static char zz[]={" / / "}; // 0 3 6
void menu_17(void);
void key_Init(void); //键盘初始化
unsigned char keysao(void); //键盘扫描函数
unsigned char key_pan(void); //判断是否有键按下
void key_process(void); //菜单处理
#define LCD_RW_DDR DDRA
#define LCD_RS_PORT PORTA
#define LCD_RS_DDR DDRA
#define LCD_DATA_PORT PORTA
#define LCD_DATA_DDR DDRA
#define LCD_DATA_PIN PINA
#define key_PORT PORTB
void menu_0(void);
void menu_1(void);
void menu_2(void);
void menu_3(void);
void menu_4(void);
void menu_5(void);
void menu_6(void);
void menu_7(void);
void menu_8(void);
| | | | | | |
M16 PA1 PA2 PA3 PA4 PA5 PA6 PA7
*****************************************************************************************/
/*------------------------------------------------------------------------------------------
时钟:外部8000000hz
建立日期: 2006-11-18
最后修改日期:
*****************************************************************************************/
/*---------------------------------------------------------------------------------------
/*************************************************************************************
项目: 1602液晶显示实验+键盘+菜单+DS1302