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)----下面是当用户选择菜单后执行相关操作的代码,只是简单显示一个交互消息框而已。
LCD12864多级菜单课程设计
LCD12864多级菜单课程设计一、课程目标知识目标:1. 理解LCD12864液晶显示屏的基本工作原理和接口技术。
2. 掌握多级菜单的设计方法,包括菜单结构、界面布局及跳转逻辑。
3. 学会编写程序代码实现LCD12864多级菜单的显示与操作。
技能目标:1. 能够运用所学知识设计出结构清晰、界面友好的多级菜单界面。
2. 熟练使用相关编程语言和开发工具,完成程序编写和调试。
3. 培养学生的动手操作能力和团队协作能力,提高问题解决能力。
情感态度价值观目标:1. 培养学生对电子技术和编程的兴趣,激发学习热情。
2. 培养学生严谨、细心的学习态度,养成良好的编程习惯。
3. 增强学生的创新意识,鼓励学生敢于尝试、勇于实践。
分析课程性质、学生特点和教学要求,本课程目标旨在帮助学生在掌握LCD12864多级菜单设计的基础上,提高实际操作能力,培养学生的创新思维和团队协作精神。
通过本课程的学习,使学生能够在实际项目中运用所学知识,为我国电子信息产业的发展做出贡献。
同时,注重培养学生的情感态度价值观,使学生在学习过程中形成积极向上的人生态度。
二、教学内容1. LCD12864液晶显示屏原理介绍:包括显示原理、接口技术、指令集等基本知识。
- 教材章节:第三章第二节- 内容列举:LCD12864工作原理、接口类型、指令功能。
2. 多级菜单设计方法:- 教材章节:第五章- 内容列举:菜单结构设计、界面布局、跳转逻辑、操作流程。
3. 编程实现LCD12864多级菜单:- 教材章节:第六章- 内容列举:编程环境搭建、代码编写、程序调试、功能实现。
4. 实例分析与操作:- 教材章节:第七章- 内容列举:典型多级菜单实例、操作方法、优化技巧。
5. 动手实践与团队协作:- 教材章节:第八章- 内容列举:实践任务分配、协作流程、成果展示。
根据课程目标,教学内容分为五个部分,确保学生系统掌握LCD12864多级菜单设计的相关知识。
教学大纲明确指出各部分内容的安排和进度,以及教材对应的章节和具体内容。
手把手教你1602字符型液晶模块使用
手把手教你1602字符型液晶模块使用+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++【1602液晶模块介绍】字符型型液晶是一种用5×7点阵图形来显示字符的液晶显示器,根据显示的容量可以分为1行16个字、2行16个字、2行20个字等,最常用的为2行16个字,即我们马上要学习的1602液晶模块,下面(图1)就是TC1602液晶模块的正面和反面照片。
图1: 1602液晶模块实物照片本站使用带背光的液晶模块TC1602EL ,TC1602EL 采用标准的16脚接口,其引脚功能如下:第1脚:VSS 为电源地,接GND 。
第2脚:VDD 接5V 正电源。
第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。
LCD12864 多级菜单
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) {
多级列表导航菜单的实现方法
多级列表导航菜单的实现方法
多级列表导航菜单的实现方法有多种,以下是一些常见的方法:
1. HTML和CSS:使用HTML和CSS来创建多级列表导航菜单是最基础的方法。
你可以使用嵌套的`<ul>`和`<li>`元素来创建多级列表,然后通过CSS来样式化这些元素,包括设置背景色、字体样式、边框、定位等。
这种方法虽然简单,但是需要手动编写大量的HTML和CSS代码,且可维护性
较差。
2. JavaScript库:有一些JavaScript库可以帮助你快速实现多级列表导航
菜单,如jQuery、Bootstrap等。
这些库提供了丰富的插件和工具,可以
简化菜单的创建和样式化过程。
使用这些库,你可以通过简单的代码实现复杂的多级列表导航菜单。
3. 服务器端编程语言:如果你熟悉服务器端编程语言(如PHP、Python、Java等),你可以使用这些语言来动态生成多级列表导航菜单。
通过从数
据库或其他数据源中获取数据,然后在服务器端生成HTML和CSS代码,
最终将生成的代码发送到客户端浏览器。
这种方法可以实现更复杂的动态功能,如菜单项的增删改查等。
4. 响应式设计框架:一些响应式设计框架(如Bootstrap、Foundation等)也提供了多级列表导航菜单的实现方法。
这些框架使用HTML、CSS和
JavaScript技术,提供了丰富的组件和工具,可以帮助你快速创建具有良好响应式效果的多级列表导航菜单。
总的来说,选择哪种方法实现多级列表导航菜单取决于你的具体需求和技术能力。
你可以根据自己的实际情况选择最适合你的方法。
基于单片机的门禁系统多级菜单设计
基于单片机的门禁系统多级菜单设计王清珍;董健;杨宇【摘要】为了在无线办公门禁系统中实现通过LCD12864显示屏分屏显示多项内容,采用单片机C语言程序设计了多级菜单,应用结构体数组成员的定义,借助按键来改变菜单项的索引号,进行内容的分屏显示及菜单项之间的切换。
在多项显示时,同一屏上显示项处于同一级,涉及的变量少,索引号级数少,系统开支就小。
设计简化,按键实时性好,界面简单,操作方便。
%In order to realize the split screen display of multiterm contents on LCD12864 display screen in the wireless of⁃fice access control system,the multi⁃level menu was designedby means of a C language program of single chip microcomputer. The definition of the structural body array members is used,and the split screen display of multiterm contents and switching be⁃tween menu items are performed with the help of buttons to change the index number of menu items. Split screen display switching between content and menu items is adopted to simplify the design. The system has the advantages of simple design,good real⁃time performance and simple interface,and is easy to operate.【期刊名称】《现代电子技术》【年(卷),期】2015(000)012【总页数】4页(P55-57,61)【关键词】LCD12864;多级菜单;结构体数组成员;切换机制【作者】王清珍;董健;杨宇【作者单位】郑州科技学院信息工程学院,河南郑州 450064;郑州科技学院信息工程学院,河南郑州 450064;郑州科技学院信息工程学院,河南郑州 450064【正文语种】中文【中图分类】TN911-34;TP368.2在门禁系统中采用的显示设备是LCD12864,此设备在系统中仅显示少量的提示信息,能够满足系统显示需求,但是受显屏显示区域的限制,要显示多项内容,需要分屏显示,在显示的内容之间有上下级和平行级关系,这就需要在显示屏上显示多级操作菜单,每一级菜单都有一些菜单项和对应的按键操作,以及响应各种操作而执行的后续处理程序。
PHP的开合式多级菜单程序
PHP的开合式多级菜单程序# --------------------------------------------------------# 数据表的结构 'menu'# --------------------------------------------------------CREATE TABLE menu (menu_id int(11) NOT NULL auto_increment,menu varchar(20) NOT NULL,menu_grade int(11) NOT NULL,menu_superior int(11) NOT NULL,UNIQUE menu_id (menu_id));# -------------------------------------------------#数据表内的内容,根据具体情况⽽定# -------------------------------------------------INSERT INTO menu VALUES( '1', '计算机', '1', '0');INSERT INTO menu VALUES( '2', '编程', '2', '1');INSERT INTO menu VALUES( '3', '⽹络', '2', '1');INSERT INTO menu VALUES( '4', 'PHP与MySql', '3', '2');INSERT INTO menu VALUES( '5', 'C语⾔', '3', '2');INSERT INTO menu VALUES( '6', '⽹页制作', '3', '3');INSERT INTO menu VALUES( '7', 'TCP、IP协议', '3', '3');INSERT INTO menu VALUES( '8', '数学', '1', '0');INSERT INTO menu VALUES( '9', '⾼等数学', '2', '8');INSERT INTO menu VALUES( '10', '线性代数', '3', '9');INSERT INTO menu VALUES( '11', '离散数学', '3', '9');INSERT INTO menu VALUES( '12', '初等数学', '2', '8');INSERT INTO menu VALUES( '13', '⽂学', '1', '0');INSERT INTO menu VALUES( '14', '中国⽂学', '2', '13');INSERT INTO menu VALUES( '15', 'php', '4', '4');INSERT INTO menu VALUES( '16', 'mysql', '4', '4');<?//树型⽬录结构模板程序//菜单⽬录库字段说明://menu_id 菜单项⽬ id//menu 菜单名称//menu_grade 菜单等级 1 为主菜单 2 为⼆级菜单 ........//menu_superior 上⼀级菜单 id 号function my_menu($menu_content,$i,$menu_grade_temp,$menu_superior_temp){global $PHP_SELF;$temp1=$menu_grade_temp+1;$menu_superior_temp_array=split("/",$menu_superior_temp);for ($t=0;$t<$i;$t++){$menu_array=split("/",$menu_content[$t]);If(($menu_array[2]==$menu_grade_temp)&&($menu_array[3]==$menu_superior_temp_array[$menu_grade_temp-1])) {for($p=1;$p<=$menu_grade_temp;$p++){echo ">";} //显⽰⽬录前的等级箭头$temp3=$menu_superior_temp_array;$temp3[$menu_grade_temp]=$menu_array[0];$temp2=implode("/",$temp3);if ($menu_array[0]==$menu_superior_temp_array[$temp1-1]){$temp5=$temp1-1;$temp3[$menu_grade_temp]="";$temp6=implode("/",$temp3);echo "<a href=\"$PHP_SELF?menu_grade_temp=".$temp5."&menu_superior_temp=$temp6\">$menu_array[1]</a><br>";my_menu($menu_content,$i,$temp1,$temp2);}else{$temp3[$menu_grade_temp+1]="";$temp6=implode("/",$temp3);echo "<a href=\"$PHP_SELF?menu_grade_temp=".$temp1."&menu_superior_temp= $temp6\">$menu_array[1]</a><br>";}}}}// 连接 MySql 数据库$db_host="localhost";$db_user="root";$db_password="zmxj";$db_name="joss";mysql_connect($db_host,$db_user,$db_password);mysql_select_db($db_name);//从数据库中取得数据$query_string="select * from menu order by menu_grade";$db_data=mysql_query($query_string);//第⼀次执⾏初始化if ($menu_grade_temp==""){$menu_superior_temp=0;}//将所有的信息读⼊数组,并统计数组个数$i=0;while (list($menu_id,$menu,$menu_grade,$menu_superior)=mysql_fetch_row($db_data)) {$menu_content[$i]=$menu_id."/".$menu."/".$menu_grade."/".$menu_superior;$i++;}my_menu($menu_content,$i,1,$menu_superior_temp);>。
1602菜单
#include<reg52.h>#define uchar unsigned char#define uint unsigned int//音乐按键定义#define M_1 0#define M_2 1#define M_3 2#define M_4 4#define M_5 5#define M_6 6#define M_7 8#define M_8 9//以下是C调中音的音频宏定义#define dao 523 //将“dao”宏定义为中音“1”的频率523Hz #define re 587 //将“re”宏定义为中音“2”的频率587Hz #define mi 659 //将“mi”宏定义为中音“3”的频率659Hz #define fa 698 //将“fa”宏定义为中音“4”的频率698Hz #define sao 784 //将“sao”宏定义为中音“5”的频率784Hz #define la 880 //将“la”宏定义为中音“6”的频率880Hz #define xi 987 //将“xi”宏定义为中音“7”的频率53#define i 1100unsigned char keyval; //定义变量储存按键值sbit sound=P1^2; //将sound位定义为P1.2unsigned int C; //全局变量,储存定时器的定时常数unsigned int f; //全局变量,储存音阶的频率/****1602接口定义****/sbit rs=P2^4;sbit rw=P2^5;//1602的读写选择口sbit en=P2^6;//1602使能信号/****按钮接口定义****/sbit s1=P3^0;//确认sbit s2=P3^1;//下翻页sbit s3=P3^2;//上翻页sbit s4=P3^3;//返回sbit sgnd=P3^7;//按键地线/****变量定义****/uchar num0,kennum;uchar num1;//显示for循环变量uint num2=0;//秒表变量uint num3=6000;uchar num;uchar temp;//矩阵键盘扫描用uchar kennum;uchar qian,bai,shi,ge;uchar flog; //程序执行标志/****数组定义****//*主页面显示*/uchar code table_0[]=" HomePage ";//**num=0**主菜单显示1排uchar code table_01[]=" Dleshan ";//**num=0**主菜单显示2排/*功能1显示*/uchar code table_1[]="1.Stopwatch ";///*功能2显示*/uchar code table_2[]="2.Count down ";///*功能3显示*/uchar code table_3[]="3.Music ";///*功能4显示*/uchar code table_4[]="4.no............";///*功能5显示*/uchar code table_5[]="5.My Student ID ";///*显示功能*/uchar code table_6[]=" Function ";///*显示清屏*/uchar code table_7[]=" ";///*显示我的学号*/uchar code table_8[]="ID:080522019 ";//uchar kenq[2];/****函数声明****/void key_sm();//矩阵扫描void delay(uchar z)//延时子函数{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void wilte_com(uchar);//1602写命令void wilte_data(uchar);//1602写数据void init();//程序主初始uchar ken();//按键(翻页)bit Music();void Output_Sound(void);uchar KeyScan();/**********************************************************************************程序主函数*********************************************************************/void main(){init();EA=1; //开总中断ET0=1; //定时器T0中断允许// ET1=1; //定时器T1中断允许// TR1=1; //定时器T1启动,开始键盘扫描TMOD=0x10; //分别使用定时器T1的模式1,T0的模式0// TH1=(65536-500)/256; //定时器T1的高8位赋初值// TL1=(65536-500)%256; //定时器T1的高8位赋初值while(1){num0=ken(); //读按键值,/********************************************主页面*******************************/if(num==0){/****显示主页面***/wilte_com(0x80);for(num1=0;num1<16;num1++)//让字符表lable1的字符一个一个的累加显示在1602第一行上{wilte_data(table_0[num1]);//1602写数据显示字符表table1的内容delay(5);}wilte_com(0x80+0x40); //显示指针到第二排for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(table_01[num1]);//1602写数据显示字符表table2的内容delay(5);}}/********************************************功能:1*******************************/if(num0==1){/****显示功能界面***/wilte_com(0x80);for(num1=0;num1<16;num1++)//让字符表lable1的字符一个一个的累加显示在1602第一行上{wilte_data(table_6[num1]);//1602写数据显示字符表table1的内容delay(5);}/****显示功能1界面--功能名***/wilte_com(0x80+0x40); //显示指针到第二排for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(table_1[num1]);//1602写数据显示字符表table2的内容delay(5);}/************************确认是否执行相关程序***/if(s1==0)//确认键按下后执行内部语句{delay(3);if(s1==0){while(!s1); //松手检测放开后执行相关程序flog=1;/******更新显示*******/wilte_com(0x80);for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(table_1[num1]);//1602写数据显示字符表table2的内容delay(5);}wilte_com(0x80+0x40); //显示指针到第二排for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(table_7[num1]);//1602写数据显示字符表table2的内容delay(5);}while(flog){num2++;if(num2==9990)num2=0;delay(50); //延时qian=num2/1000;bai=num2%1000/100;shi=num2%100/10;ge=num2%10;wilte_com(0x80+0x40+2);wilte_data(0x30+qian); //显示千位wilte_com(0x80+0x40+3);wilte_data(0x30+bai); //显示百位wilte_com(0x80+0x40+4);wilte_data(0x30+shi); //显示十位wilte_com(0x80+0x40+6);wilte_data(0x30+ge); //显示个位if(s4==0){delay(2);if(s4==0){flog=0;num2=0;}}if(s2==0){delay(2);if(s2==0)while(!s2);}if(s3==0){delay(2);if(s3==0)num2=0;}}}}}/********************************************功能:2*******************************/if(num0==2){/****显示功能界面***/wilte_com(0x80);for(num1=0;num1<16;num1++)//让字符表lable1的字符一个一个的累加显示在1602第一行上{wilte_data(table_6[num1]);//1602写数据显示字符表table1的内容delay(5);}/****显示功能2界面--功能名***/wilte_com(0x80+0x40); //显示指针到第二排for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(table_2[num1]);//1602写数据显示字符表table2的内容delay(5);}/************************确认是否执行相关程序***/if(s1==0)//确认键按下后执行内部语句{delay(2);if(s1==0){while(!s1); //松手检测,放开后执行相关程序flog=1;/******更新显示*******/wilte_com(0x80);for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(table_2[num1]);//1602写数据显示字符表table2的内容delay(5);}wilte_com(0x80+0x40); //显示指针到第二排for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(table_7[num1]);//1602写数据显示字符表table2的内容delay(5);}while(flog){while(kennum!=0){key_sm();if(kennum==2){num3=kenq[1]*1000+kenq[2]*100;kennum=0;}}num3--;if(num3==0)num3=100;delay(50); //延时qian=num3/1000;bai=num3%1000/100;shi=num3%100/10;ge=num3%10;wilte_com(0x80+0x40+2);wilte_data(0x30+qian); //显示千位wilte_com(0x80+0x40+3);wilte_data(0x30+bai); //显示百位wilte_com(0x80+0x40+4);wilte_data(0x30+shi); //显示十位wilte_com(0x80+0x40+6);wilte_data(0x30+ge); //显示个位if(s4==0){delay(2);if(s4==0){flog=0;num3=0;}}if(s2==0){delay(2);if(s2==0)while(!s2);}if(s3==0){delay(2);if(s3==0)num3=100;}}}}}/********************************************功能:3*******************************/if(num0==3){/****显示功能界面***/wilte_com(0x80);for(num1=0;num1<16;num1++)//让字符表lable1的字符一个一个的累加显示在1602第一行上{wilte_data(table_6[num1]);//1602写数据显示字符表table1的内容delay(5);}/****显示功能3界面--功能名***/wilte_com(0x80+0x40); //显示指针到第二排for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(table_3[num1]);//1602写数据显示字符表table2的内容delay(5);}if(s1 == 0){Music();}/************************确认是否执行相关程序***//* if(s1==0)//确认键按下后执行内部语句{delay(5);} */}/********************************************功能:4*******************************/if(num0==4){/****显示功能界面***/wilte_com(0x80);for(num1=0;num1<16;num1++)//让字符表lable1的字符一个一个的累加显示在1602第一行上{wilte_data(table_6[num1]);//1602写数据显示字符表table1的内容delay(5);}/****显示功能4界面--功能名***/wilte_com(0x80+0x40); //显示指针到第二排for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(table_4[num1]);//1602写数据显示字符表table2的内容delay(5);}/************************确认是否执行相关程序***//* if(s1==0)//确认键按下后执行内部语句{delay(3);} */}/********************************************功能:5*******************************/if(num0==5){/****显示功能界面***/wilte_com(0x80);for(num1=0;num1<16;num1++)//让字符表lable1的字符一个一个的累加显示在1602第一行上{wilte_data(table_6[num1]);//1602写数据显示字符表table1的内容delay(5);}/****显示功能5界面--功能名***/wilte_com(0x80+0x40); //显示指针到第二排for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(table_5[num1]);//1602写数据显示字符表table2的内容delay(5);}/************************确认是否执行相关程序***/if(s1==0)//确认键按下后执行内部语句{if(s1==0)//确认键按下后执行内部语句{delay(2);if(s1==0){while(!s1); //松手检测放开后执行相关程序flog=1;/******更新显示*******/while(flog){wilte_com(0x80);for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(table_5[num1]);//1602写数据显示字符表table2的内容delay(5);}wilte_com(0x80+0x40); //显示指针到第二排for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(table_8[num1]);//1602写数据显示字符表table2的内容delay(5);}if(s4==0){delay(2);if(s4==0)flog=0;}}}}}}}}/****************************************************************************** ****按键(翻页)*********************************************************************/uchar ken() // 按键(翻页){if(s2==0){delay(2);if(s2==0){while(!s2);kennum++;if(kennum==6)kennum=1;}}if(s3==0){delay(2);if(s3==0){while(!s2);kennum--;if(kennum==0)kennum=5;}}if(s4==0){delay(2);if(s4==0){while(!s4);kennum=0;}}return kennum; //返回值,确定当前所在页}/****************************************************************************** ****1602写命令*********************************************************************/void wilte_com(uchar com)//1602写命令{rs=0;en=0;P0=com;delay(5);en=1;delay(5);en=0;}/****************************************************************************** ****1602写数据*********************************************************************/void wilte_data(uchar data1)//1602写数据{rs=1;en=0;P0=data1;delay(5);en=1;delay(5);en=0;}void init(){flog=0;/**按键相关初始**/kennum=0; //s2_s3_s4 按键值num=0; //读按键值变量sgnd=0;//给按键端底电平/**1602相关初始**/rw=0;//我只对1602写数据,不读,所以一直给底,en=0;//使能信号初始为底wilte_com(0x38);//1602写命令设置1602显示模式wilte_com(0x0c);//1602写命令开显示,不显示光标wilte_com(0x06);//1602写命令写一个字符,光标和地址加1wilte_com(0x01);//完了防错的kennum=0;}void Display_Music(uchar dis){uchar num1 = 0;uchar code *music_tb[] = {"Pressed dao! ","Pressed re ! ","Pressed mi ! ", "Pressed fa ! ","Pressed sao! ","Pressed la ! ", "Pressed xi ! ","Have no music! "};wilte_com(0x80+0x40); //显示指针到第二排for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(*(music_tb[dis] + num1));//1602写数据显示字符表table2的内容delay(5);}}//电子琴bit Music(void){uchar num = 0;uchar key_num = 0xff;uchar code music_no[] = "Have no music! ";wilte_com(0x80);for(num1=0;num1<16;num1++)//让字符表lable1的字符一个一个的累加显示在1602第一行上{wilte_data(table_3[num1]);//1602写数据显示字符表table1的内容delay(5);}/****显示功能3界面--功能名***/wilte_com(0x80+0x40); //显示指针到第二排for(num1=0;num1<16;num1++)//让字符表lable2的字符一个一个的累加显示在1602第二行上{wilte_data(music_no[num1]);//1602写数据显示字符表table2的内容delay(5);}while(1){key_num = KeyScan();switch(key_num){case M_1: Display_Music(0);f = dao; Output_Sound(); break;case M_2: Display_Music(1);f = re; Output_Sound(); break;case M_3: Display_Music(2);f = mi; Output_Sound(); break;case M_4: Display_Music(3);f = fa; Output_Sound(); break;case M_5: Display_Music(4);f = sao; Output_Sound(); break;case M_6: Display_Music(5);f = la; Output_Sound(); break;case M_7: Display_Music(6);f = xi; Output_Sound(); break;case M_8: Display_Music(7);f = i; Output_Sound(); break;case 15: key_num = 0xff;return 0;default: key_num = 0xff;break;}key_num = 0xff;}}//键盘扫描uchar KeyScan(void)//键盘扫描函数,使用行列反转扫描法{uchar cord_h,cord_l;//行列值uchar key_num = 0xff;P3=0x0f; //行线输出全为0cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{delay(100); //去抖if(cord_h!=0x0f){cord_h=P3&0x0f; //读入列线值P3=cord_h|0xf0; //输出当前列线值cord_l=P3&0xf0; //读入行线值key_num = cord_h + cord_l;goto KEYNUM11;//return(cord_h+cord_l);//键盘最后组合码值并返回}//return(0xff); //否则返回固定值0xffkey_num = 0xff;KEYNUM11:switch(key_num){case 0xee:return 0;//0 按下相应的键显示相对应的码值case 0xde:return 1;//1case 0xbe:return 2;//2case 0x7e:return 3;//3case 0xed:return 4;//4case 0xdd:return 5;//5case 0xbd:return 6;//6case 0x7d:return 7;//7case 0xeb:return 8;//8case 0xdb:return 9;//9case 0xbb:return 10;//acase 0x7b:return 11;//bcase 0xe7:return 12;//ccase 0xd7:return 13;//dcase 0xb7:return 14;//ecase 0x77:return 15;//fdefault: return 0xff;}}/*******************************************函数功能:输出音频入口参数:F******************************************/void Output_Sound(void){C=(46083/f)*10; //计算定时常数TH0=(8192-C)/32; //可证明这是13位计数器TH0高8位的赋初值方法TL0=(8192-C)%32; //可证明这是13位计数器TL0低5位的赋初值方法TR0=1; //开定时T0// delay(); //延时200ms,播放音频P3 = 0XF0;while(0XF0 != P3){P3 = 0XF0;TR0=0; //关闭定时器sound=1; //关闭蜂鸣器Display_Music(7);// keyval=0xff; //播放按键音频后,将按键值更改,停止播放}/**************************************************************函数功能:定时器T0的中断服务子程序,使P3.7引脚输出音频方波**************************************************************/void Time0_serve(void ) interrupt 1 using 1{TH0=(8192-C)/32; //可证明这是13位计数器TH0高8位的赋初值方法TL0=(8192-C)%32; //可证明这是13位计数器TL0低5位的赋初值方法sound=!sound; //将P3.7引脚取反,输出音频方波}/****************************************************************************** ************************************按键扫描******************************************************************************* **********/void key_sm(){uchar a,num;a=5000;P3=0xfe;temp=P3;temp=temp&0xfe;//temp与P3口的值与一下,看看与回来的值是否还等于tempwhile(temp!=0xfe)//如果与回来的徝不等于temp的值,则执行if语句{delay(5);P3=0xfe;temp=P3;temp=temp&0xfe;while(temp!=0xfe){temp=P3;//把P0的值在给temp,当按键松下以后就不会在次进入if语句switch(temp)//把temp的值与语句内部case的值对照。
- 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