当前位置:文档之家› (完整版)单片机多级菜单编程实现

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

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

单片机多级菜单编程实现

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

INT8U *MenuHlp; //菜单帮助字符串

#endif

struct 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, Down

MenuID, 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

0;

//没有原先选择的项

}else{

if(WhichKey == KEY_UP)

oldid = KeyTab[MenuNextID].PressDown;

else

oldid = KeyTab

[MenuNextID].PressUp;

//指示原先的项

for(i=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)

(); //显示当前菜单

}else

escflag =

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。

2.在网上的资料中,结构体数组是存在RAM中的,我把它放在也flash中了,然后再定义一个

结构体变量,就样就可以省很多RAM,比较适合51.

3.在网上资料中,因为保存了原来的选择,当你离开编程状态重新进行后,会发现选择上会

是原来进行的顺序,我改动之后,退出上一级菜单还是你选的那一项,但重新进入后就是第

一个指定项。

4.增加UP和DOWN显示,可以反显最新选定的选项,正常显示原来的选项。

基于状态机的LCD多级菜单设计方案

基于状态机的LCD多级菜单设计方案 1概述 液晶显示器(Liquid Crystal Display,LCD)由于其体积和功耗等因素,非常适合嵌入式环境的使用。近年来,随着微处理器性能的提高,嵌入式系统实现的功能越来越强大,产生的数据量也越来越大。相对应地,需要显示的数据量也随之增大。嵌入式环境下使用LCD 显示器,由于条件限制,体积较小,且显示的内容有限。而且,传统的LCD显示模式总是不加选择地显示所有监控的信息,在监控的信息量非常庞大时会导致不能及时显示用户所需求的信息。多级菜单显示则是将信息分类显示的一种显示方式,该方式根据用户的选择,对显示信息加以筛选并分级显示,这样既保证用户获取其所需的信息,又能保障信息显示的实时性。 2多级菜单的结构 设计多级菜单的目的在于将需要显示的信息分门归类,方便用户筛选。所以在设计菜单时需要根据整个系统的功能和要求来设定菜单的级数,以及各级子菜单的个数。整个多级菜单的拓扑结构为树型结构,主菜单为根节点,子菜单为枝节点,最后一级菜单为叶节点,如图1所示。 图1多级菜单的结构图 3多级菜单的程序设计 3.1循环方式 循环方式的设计思路:预先定义一个包含6个结构元素的结构体、5个字符型和1个指针型。第1个字符变量存放当前界面的索引号;第2个字符变量存放按下down(向下)键时需要跳转到的索引号;第3个字符变量存放按下up(向上)键时需要跳转到的索引号;第4个字符变量存放按下enter(进入)键时需要跳转的索引号;第5个字符变量存放按下esc(退出)键时需要跳转的索引号;第6个变量为函数指针变量,存放当前索引号下需要执行的函数的入口地址。

单片机4个按键菜单

单片机4个按键菜单 #include “main.h”void PWM_Ctrl(signed char i) //脉冲宽度设置{} void OpenTime_Ctrl(signed char i) //开时间设置{} void CloseTime_Ctrl(signed char i) //关时间设置{} void ClearData(signed char i) //清除数据{} void NullMenu(signed char i) //空操作{ ;} struct MenuItem{ void (*Display)(void); //显示函数void (*Subs)(signed char i); //节点函数struct MenuItem *ChildrenMenus; //子菜单struct MenuItem *ParentMenus; //母菜单}; //本文共计2 级菜单 struct MenuItem SetMenu[4]; //设置键子菜单struct MenuItem StartMenu; //开始菜单struct MenuItem (*MenuPoint) = &StartMenu;struct MenuItem (*last_MenuPoint) = &StartMenu; struct MenuItem SetMenu[4] ={ // Display Subs ChildrenMenus ParentMenus { Display_S0, PWM_Ctrl, &SetMenu[1], &StartMenu}, { Display_S1, OpenTime_Ctrl, &SetMenu[2], &StartMenu}, { Display_S2, CloseTime_Ctrl, &SetMenu[3], &StartMenu}, { Display_S3, ClearData, &StartMenu, &StartMenu},}; struct MenuItem StartMenu ={ Display_Count, NullMenu, &SetMenu[0], &StartMenu}; void Data_manage(void){; } void Key_Handle(void){ unsigned char key; signed char i = 0; if (key_value == 0) { return; } key = key_value; key_value = 0; switch (key) { case KEY_START:

单片机多级菜单编程实现

单片机多级菜单编程实现 单片机多级菜单编程实现(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_EN INT8U *MenuHlp; //菜单帮助字符串

#endif struct 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, Down

12864并行多级菜单程序

#include "includes.h" u8 key=0,hua; extern u32 Second; extern u32 minite,hour,day,k,month,year,shan; u8 xingqi[]={"一二三四五六日"}; u8 ModeFlag=0,wei=0;//液晶界面选择 int main(void) { u8 PasswordIndex=0;//密码数组索引 u8 Password[4]={" "};//存储密码数组 BSP_Init();//初始化外部资源 ModeFlag=0; while(1) { //////////////////////////////////////// 界面一////////////////////////////////// if(ModeFlag==0) { LCD12864_Waddr(1,3); LCD12864_WPoss(0,"WELCOME!"); LCD12864_Waddr(2,2); LCD12864_WPoss(0,"--欢迎使用--"); Delay_1ms(8000); LCD12864_Clear(); } //////////////////////////////////////// 界面二////////////////////////////////// // ModeFlag=0; ///// 改 while(ModeFlag==0) //进入登录界面 { LCD12864_Waddr(1,1); LCD12864_WPoss(0,"请输入登陆密码:"); LCD12864_Waddr(2,3); //LCD12864_WPoss(0," "); LCD12864_Waddr(3,1); LCD12864_WPoss(0,"密码为四位数字"); LCD12864_Waddr(4,1); LCD12864_WPoss(0,"删除*");

单片机课程设计(菜单页面)

《单片机技术》课程设计说明书 题目 系部: 学生姓名: 指导教师:职称 专业: 班级: 完成时间:

摘要 随着现代化的脚步,市场经济的不断完善,信息技术日益发展,信息量的掌握决定了一个人事业的成败。21世纪其实无疑不是信息的时代。信息技术的迅猛发展已对我们的生产方式、生活方式、学习方式及思维方式产生了深远的影响,也带动了信息显示技术的发展。 其中液晶显示屏被广泛应用于各种不同的领域,包括手机、膝上型电脑、笔记本电脑、电脑监视器、大屏幕电视以及数字广告屏,液晶显示在我们的生活中随处可见,同时,人们也可根据自己的需求选择显示出想要显示的内容。近年来,同样应用广泛的菜单选择系统也离不开显示技术。通过显示屏,使得具有单层或多层菜单选择功的操作系统更加简洁、优化、便于操作。本设计通过汉字液晶显示器122232来显示出一个具有两级菜单选择功能的小系统。设计以模拟生活中常见的多功能检测器为例,详细分析了单片机在本设计中的应用原理,并分块给出了整个系统的硬件以及软件编程思路,使得整个设计清晰简洁地阐明了单片机小系统在生活中的广泛应用。因此本课题的研究具有重要的现实意义。 关键词:显示单片机液晶显示器菜单选择

Abstract With the pace of the modernization, the economy market continues to improve. The information technology is improved day by day, so controlling the amount of information determines one’s success or failure. In fact, the 21st century is certainly the information age. The rapid development of the information technology has made a deeply effect in our lifestyle, learning style and thinking style, and at the same time, it has helped to improve the information display technology. Among that, Liquid crystal display is widely used in a variety of areas, including mobile phones, laptop computers, notebook computers, computer monitors, large screen TV and digital advertising screens. Liquid crystal display applies everywhere in our lives, at the same time, we can control the content which we want to display in the screen according our needing. In recent years, the menus chose system which also very popular in people’s life is also rely on the display system. The displays made the menus system more simple and clean. This design simulates the popular menus system in our life. Having analyzed the working theory of the SCM before designed, it tells us the thoughts of the hardware and software designs. This makes the design more compact and pellucid to display the SCM’s use in our life. So the subject of this research has an important practical significance. Keywords:display SCM l iquid crystal display menus-chose

单片机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; //去掉高5bit delay(50000); switch(KeyValue) { case 1: //回车键,找出新的菜单状态编号 { KeyFuncIndex=KeyTab[KeyFuncIndex].KeyCrState;

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来实现中文菜单操会更加简便。

LCD12864 多级菜单

首先定义一个菜单结构 typedef struct menu//定义一个菜单 { u8 range_from,range_to; //当前显示的项开始及结束序号 u8 itemCount;//项目总数 u8 selected;//当前选择项 u8 *menuItems[17];//菜单项目 struct menu **subMenus;//子菜单 struct menu *parent;//上级菜单,如果是顶级则为null void (**func)();//选择相应项按确定键后执行的函数 }Menu; Menu MainMenu = { //定义主菜单 0,3,4,0,//默认显示0-3项,总共4项,当前选择第0项 { "设置1 \x10", "设置2 \x10", "输入指令发送", "查询\x10" } }; Menu searchMenu = {//查询菜单 0,3,6,0, { "记帐记录明细", "未采集记录数", "设备机号", "本机IP地址", "记录空间大小", "软件版本" } }; Menu *currentMenu;//当前的菜单 用于显示菜单项 void display(u8 line) //显示菜单项并设置选中的项反白{ int i; line = 3-(currentMenu->range_to-line); Lcd_Fill(0x00); for(i = 0;i<4;i++) {

Lcd_Disp(i+1,0,currentMenu->menuItems[i+currentMenu->range_from]); } highlight(0,line,8,255);//反白显示指定行 } void func(void) { printf("hello\r\n"); } 初始化菜单: void initMenu() { MainMenu.subMenus = malloc(sizeof(&MainMenu)*4); MainMenu.subMenus[0] = NULL;//第1到3项没有子菜单置null,选择后程序会调用func中相应项中的函数 MainMenu.subMenus[1] = NULL; MainMenu.subMenus[2] = NULL; MainMenu.subMenus[3] = &searchMenu;//第四项查询有子菜单 MainMenu.func = malloc(sizeof(&func)*4); MainMenu.func[0] = NULL; MainMenu.func[1] = NULL; MainMenu.func[2] = &func;//当选择了并按了确定,会执行func函数 MainMenu.func[3] = NULL; MainMenu.parent = NULL;//表示是顶级菜单 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.进入查询子菜单后按返回键,将会显示这个菜单项 currentMenu = &MainMenu; } main

单片机人机界面设计

************************************************************************* 独立按键与菜单显示系统的设计 **************************************************************************** 引言: 通过按键和LCD液晶显示组成的人机界面是电子产品设计的常用的人机交互方式,如果能够将复杂且耗时的按键驱动、液晶驱动、菜单维护等工作从系统中分离出来并提供完备的功能,对于减少资源占用提高系统实时性、简化系统设计具有重要的意义。本文以设计一套包含按键置数、菜单滚动、动态显示变量、系统状态发送等功能的最小化的单片机系统,并且以此为契机探讨按键和显示程序设计中应当注意的种种问题和程序的优化设计。 一、独立设计按键和显示系统的意义 人机交互界面就是是人与计算机之间传递、交换信息的媒介和对话接口,是计算机系统的重要组成部分。按键驱动和液晶显示部分是很多电子设计采取的交互手段,它的好处是接口简便、成本低。实际上多数的设计中按键和液晶的响应控制不需要有很高的实时性,按键程序通常都包含100ms左右的消抖延时,液晶显示时只要刷屏速度大于150ms(60HZ)肉眼是看不出分别的,但这段时间相对于实时系统来说是一个很长的,如果和系统混合在一起编译运行将占用很大的存储和运行开销。能够将按键和显示部分从应用系统中剥离出来对于提高开发效率完备程序设计都有很高的价值,特别的对于电子竞赛短时间内需要完成完整的功能设计的情况都有重要的意义。 从系统应用的角度看不同的系统对于按键的处理和显示的功能都是很类似的,比如按键输入一个数据、屏幕的特定位置显示一个变量、菜单上下滚动选中其中的某一行等等。一个只有三个按键的系统输入一个变量时需要很多的中间变量,还要配合按键扫描、变量数据上下限判断、液晶屏显示当前值、标记显示当前正在输入的位等一系列的功能函数调用步骤才能完成,然而最后系统所关心的只是输入变量的值是多少。不难看出将按键与显示部分分离出来不仅简化应用系统的设计而且可以大幅提高系统实时处理能力。 设计一个完整的按键菜单液晶模块对于初学者来说也并不是一件容易的事,通常在很熟悉编译环境和语言的前提下要完整编写这些代码也需要几个星期甚至更长的时间,重复编写这些功能不仅耗时而且没有必要。本设计中带有一个简单的单片机系统完全实现按键和显

一种在单片机便于修改的多级菜单及程序思路

【回到大虾单片机电子网首页】 【回到精华帖子首页】 标题标题::一种在单片机便于修改的多级菜单及程序思路 关键关键字字: 编号:606 大大虾论坛虾论坛文章文章文章编编号:210132 发发表时间时间::2004-2-18 1:12:07 访问访问访问次次数:826 文章文章类类型:经验交流 作者作者::zzwj5120/id:18030 跟帖作者跟帖作者::清风徐徐,倾云之恋,gegegegeda ,jye ,Oldkey , 本页地址地址::https://www.doczj.com/doc/5b2889453.html,/bibis/lookgood.asp?lookid=606 一种在单片机便于修改的多片机便于修改的多级级菜单及程序思路及程序思路((17561756字字)zzwj51202004zzwj51202004--2-18 1:12:07[15918 1:12:07[159次次] 完全用数据结构的方法建立多级菜单,网上有现成的例子,但不便于修改和维护。 这里给出另一个思路,不但完全可行,而且嵌入其它代码及修改控制都十分方便。 //三级菜单定义 extern char menu_stay[3]; //menu_stay[0]: 存放第1级菜单所选菜单项 extern char menu_number[3]; //menu_number[0]: 第1级菜单菜单项总数 extern char menu_grade; //menu_grade:当前所处菜单级 //code 常量定义 //第1级菜单菜单项数目为3 code char list_0x1[] = {0x02,0x03, 0x03}; //第1级菜单菜单项X-〉下级菜单数目 code char list_1x2[] = {0x05, 0x03}; //第1级菜单菜单项1-〉下级菜单数目 code char list_2x2[] = {0x02, 0x04, 0x03}; //第1级菜单菜单项2-〉下级菜单数目 code char list_3x2[] = {0x02, 0x04, 0x03}; //第1级菜单菜单项3-〉下级菜单数目 code char list_4x2[] = {0x02, 0x04, 0x03}; //第1级菜单菜单项4-〉下级菜单数目 code char Menu_new[] = {"NEW"}; code char Menu_open[] = {"OPEN"}; code char Menu_save[] = {"SAVE"}; 处于当前菜单级时需要读取当前选项对应下级菜单菜单项总数,可设定菜单项总数为0 表示下一级已经没有菜单了。 菜单背景可用BMP图形显示,在LCD或VFD上,通过工具条按钮 或上下按键滚屏,最多可以显示255*255*255个菜单项。 按键操作只改变参数menu_stay[0~3]和menu_grade,控制并不复杂。 相关帖子>>>: 一种在单片机便于修改的多片机便于修改的多级级菜单及程序思路 及程序思路 真行...(...(00字)清风徐徐徐徐[[6次]20042004--2-18 10:19:10 18 10:19:10 (0 (0字字)倾云之云之恋恋[6次]20042004--2-18 8:16:12 18 8:16:12 不错,收藏收藏[[一种在单片机便于修改的多片机便于修改的多级级菜单及程序思路及程序思路](](](00字)gegegegeda[10gegegegeda[10次次]20042004--2-18 8:30:2818 8:30:28 是个办法!!!!((0字)jye[6jye[6次次]20042004--2-18 8:39:12 18 8:39:12 不错的法子的法子。。(0字)Oldkey[6Oldkey[6次次]20042004--2-18 8:46:15 18 8:46:15 页码,1/1一种在单片机便于修改的多级菜单及程序思路[2009-9-16] 2009-9-16https://www.doczj.com/doc/5b2889453.html,/bibis/lookgood.asp?lookid=606

51单片机控制LCD12864液晶屏显示图形菜单

51单片机控制LCD12864液晶屏显示图形 菜单 想了很久,每次做菜单都受限于12864字符模式的各种限制,比如字体大小,不能显示图标等等,没有任 何效果,这次就来个彻底的解脱,写一个单函数就能完 成所有功能的函数,只需要2个图片就能完成任意菜单内容的菜单,可以有2的8次方=256个选择结果,应该能满足所有的要求了吧?菜单的内容就是图片的内容, 因此可以显示任意大小的图形文字混合的菜单条目,比 如使用字符模式,一屏只能显示4行菜单(64/16=4),且只能显示汉字和字符等,显示位置等等的都受限,而 这个方法可以显示比如12*12(64/12=5行)的字符,8*8(64/8=8行)的字符,甚至不是字符,可以是图标+文字+任意其他的图像,只要是图片能显示的,都可以。。哈哈,比较复杂,现在只写了一少半,预期能够提供多种 显示效果,希望我能完成。。。。 void Lcd_Draw_BmpMenu(UINT8 *pMenu,UINT8 *pTitleBmp,UINT8 *pMenuBmp) { /*使用2张图片作为纯图形菜单来选择和操作,返回被 选择的项,pMenu是一个指向菜单的各种参数的结构体

的指针,pTitleBmp指向作为菜单标题的一张图片,pMenuBmp指向作为菜单内容的图片(液晶的控制芯片是ST7920) yx-->;>; | \|/ */ xdata struct { //除非另有说明x坐标均为大列的坐标,一个大列是16个像素,一行共有8大列数据 //========= 以下是入参基本参数,一旦确定,最好不要随意更改 ====== UINT8 Title_x;//标题图片在屏幕上的显示起始位置X UINT8 Title_y;//标题图片在屏幕上的显示起始位置Y UINT8 Title_Len_x;//标题图片的宽 UINT8 Title_Len_y;//标题图片的高 UINT8 Menu_x;//菜单在屏幕上的显示起始位置X UINT8 Menu_y;//菜单在屏幕上的显示起始位置Y UINT8 Menu_End_y;//菜单在屏幕上的显示结束位置Y UINT8 Menu_Bmp_x;//菜单图片的宽 UINT8 Menu_Bmp_y;//菜单图片的高 UINT8 Menu_Item_Height;//每一菜单项的高度(像素为单位)

嵌入式系统多级菜单的巧妙设计方法

嵌入式系统多级菜单的巧妙设计方法 typedef struct { uchar KeyStateIndex ; / / 当前状态索引号 uchar KeyDnState ; / / 按下“向下”键时转向的状态索引号 uchar KeyUpState ; / / 按下“向上”键时转向的状态索引号 uchar KeyCrState ; / / 按下“回车”键时转向的状态索引号 uchar KeyBackState ; / / 按下“退回”键时转向的状态索引号 void (*CurrentOperate)( ) ; / / 当前状态应该执行的功能操作 } KbdTabSt ruct ; # define SIZE - OF KEYBD - MENU 55 / / 菜单总长度 KbdTabSt ruct code KeyTab[ SIZE - OF - KEYBD - MENU ] = { {0 ,0 ,0 ,1 ,0 , MainJob1 } , //第一层,MainJob1 在后面的实际函数中也要有相同对应的函数{1 ,7 ,2 ,8 ,0 , Dsp Point} , / / 第一层 {2 ,1 ,3 ,8 ,0 , DspCurve}, / / 第一层 {3 ,2 ,4 ,36 ,0 ,Dsp Kout} , / / 第一层 {4 ,3 ,5 ,50 ,0 , DisCloseDown } , / / 第一层 {5 ,4 ,6 ,8 ,0 , ModifyPoint} , / / 第1层,退回时返回到0号任务,进入时进入8号任 // 务,8号任务可以划为第2级菜单了。 {6 ,5 ,7 ,52 ,0 , SetCloseDown } , / / 第1层 {7 ,6 ,1 ,0 ,0 , Cancel} , / / 第1层 … … {52 ,53 ,53 ,0 ,1 , OkSetCloseDown1} , {53 ,52 ,52 ,0 ,1 , OkSetCloseDown2} , {54 ,0 ,0 ,0 ,0 , Disable} , … … } ; void Get Keylnput (void) { switch ( status &0xf0) { case 0xe0 :/ / 回车键,找出新的菜单状态编号 … KeyFuncIndex = KeyTab[ KeyFuncIndex ] . KeyCrState ; … break ; case 0xb0 :/ / 向下键,找出新的菜单状态编号

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

本文由heart1deep贡献 pdf文档可能在WAP端浏览体验不佳。建议您优先选择TXT,或下载源文件到本机查看。 1期 第 2006 年 2 月 工 矿 自 动 化 Indust ry and Mine Auto mation No . 1 Feb. 2006 文章编号 :1671 - 251X ( 2006) 01 - 0050 - 02 单片机 C 语言下 LCD 多级菜单的一种实现方法 陆 1 ,罗 2 铮 嘉 ( 1. 天地科技股份有限公司常州自动化分公司 ,江苏 常州 213015 ; 2. 宁夏煤矿安全监察局 ,宁夏 银川 750001 ) 摘要 : 介绍了在 C 语言环境下 ,在 L CD 液晶显示屏上实现多级嵌套菜单的一种简便方法 , 提出了一个 结构紧凑 、 实用的程序模型 。 关键词 : 液晶显示屏 ; 多级菜单 ; 单片机 ; C 语言 ; L CD 中图分类号 :TP311. 1 文献标识码 :B 0 引言 阵液晶 。 采用图形点阵式液晶显示较之其它显示方式主 要有以下优点 : ( 1) 工作电压低 、 功耗极低 。工作电压仅为 3~ 5 V ,工作电流 ≤10 μA/ cm2 , 特别适用于低功耗的 由于 C 语言的结构性和模块化 ,采用 C 语言编 写的程序容易阅读和维护 , 还有很好的可移植性 。 本文介绍一种用 C 语言实现的 L CD 多级菜单的方 法 ,该方法已成功应用在煤矿安全监测设备上 。 1 硬件环境及 LCD 菜单实现的功能 仪器仪表中 。 ( 2) 液晶显示属被动显示 ,受外界光线干扰小 。 ( 3) 图形点阵式液晶可显示的信息量大 、 分辨 图形点阵式液晶可显示用户自定义的任意符号 和图形 ,并可卷动显示 。它作为单片机系统人机交 互界面的重要组成部分被广泛应用于实时检测和显 示的仪器仪表中 ,例如手机上的显示屏就是图形点 收稿日期 :2005 - 11 - 21 率高 。 ( 4) 不产生电磁干扰 。 ( 5) 可靠性高 ,使用寿命长 。 本文所介绍的 L CD 采用 128 × 点阵的液晶 64 屏 ,因此可显示 16 × 点阵的汉字 4 行 8 列 。菜单 16 为多级嵌套形式 ,最长的有 13 层 , 主要完成对某个 检修 ,还保留了手动方式 ,该方式在正常运行情况下 是不使用的 。 4 结语 系统要运行可靠 , 对其有关设备是否能够安全 运行地检测也是很重要的一环 。因而程序对系统所 涉及的设备都进行了全面监测 , 主要有电动球阀故 障、 出水口电动闸阀故障 、 水位传感器故障 、 水泵启 停时间 、 运行电流 、 电动机温度 、 电动机和水泵轴承 温度 、 出水压力 、 高压柜状态 、 高压柜故障 、 阀门故障 等 ,并视情况进行事故自动处理或报警要求检修 。 本系统中各个机组有 3 种运行选择 : 自动 、 半自 动和手动 。通常情况下按照水位高低和系统时间自 动选择是否开泵 ,同时观察水位变化率从而选择需 要开几台泵 。在半自动方式下 , 一旦该泵的开泵信 号被监测到 ,系统将自动根据当前情况用射流方式 或者真空泵方式来抽真空 , 当真空度达到要求后启 动电 动 机 , 同 时 观 测 出 水 口 处 的 压 力 , 当 其 大 于 5 M Pa时打开出水口处的电动闸阀实施正常排水 。 为了完善系统 ,防止意外情况的发生 ,同时为了便于 由于 PL C 具有良好的抗干扰能力 , 而且编程 、 修改 、 调试都很方便 , 大大缩短了调试时间 , 提高了 系统的自动化程度 , 降低了硬件的复杂程度 。实践 证明该系统运行平稳 , 故障率低 , 基本不需维修 , 降 低了维修费用和电耗 ,取得了较好的经济效益 。 参考文献 : [1] 李世煌 . 水泵设计教程 [ M ] . 北京 : 机械 工业出 版社 , 1990. [2] 周美兰 . PL C 电气控制与组态 [ M ] . 北京 : 科学出版社 , 2003.

单片机的多重菜单设计

工业级 typedef struct { uchar KeyStateIndex ; / / 当前状态索引号 uchar KeyDnState ; / / 按下“向下”键时转向的状态索引号uchar KeyUpState ; / / 按下“向上”键时转向的状态索引号uchar KeyCrState ; / / 按下“回车”键时转向的状态索引号uchar KeyBackState ; / / 按下“退回”键时转向的状态索引号void (*CurrentOperate)( ) ; / / 当前状态应该执行的功能操作}KbdTab ; # define SIZE_OF KEYBD_MENU 55 / / 菜单总长度 KbdTabSt ruct code KeyTab[ SIZE_OF_ KEYBD_MENU ] = { {0 ,0 ,0 ,1 ,0 , MainJob1 } {1 ,7 ,2 ,8 ,0 , Dsp Point} , / / 第一层 {2 ,1 ,3 ,8 ,0 , DspCurve}, / / 第一层 {3 ,2 ,4 ,36 ,0 ,Dsp Kout} , / / 第一层 {4 ,3 ,5 ,50 ,0 , DisCloseDown } , / / 第一层 {5 ,4 ,6 ,8 ,0 , ModifyPoint} , / / 第一层 {6 ,5 ,7 ,52 ,0 , SetCloseDown } , / / 第一层 {7 ,6 ,1 ,0 ,0 , Cancel} , / / 第一层 … … {52 ,53 ,53 ,0 ,1 , OkSetCloseDown1} , {53 ,52 ,52 ,0 ,1 , OkSetCloseDown2} , {54 ,0 ,0 ,0 ,0 , Disable} , … … } ; void Get Keylnput (void) { switch ( status &0xf0) { case 0xe0 :/ / 回车键,找出新的菜单状态编号 … KeyFuncIndex = KeyTab[ KeyFuncIndex ] . KeyCrState ; … break ; case 0xb0 :/ / 向下键,找出新的菜单状态编号 … KeyFuncIndex = KeyTab [ KeyFuncIndex ] . KeyDn2State ; …

相关主题
文本预览
相关文档 最新文档