51单片机实现多级液晶显示中文菜单
单片机系统中液晶显示多级菜单的软硬件设计

第17卷第1期2003年02月 华 东 船 舶 工 业 学 院 学 报(自然科学版)Journal of East China Shipbuilding Institute (Natural Science Edition ) Vo1117No 11Feb.2003文章编号:1006-1088(2003)01-0086-04单片机系统中液晶显示多级菜单的软硬件设计唐 炜,卢道华,顾金凤(华东船舶工业学院机械系,江苏镇江,212003)摘 要:以8031单片机控制GXM -12864液晶显示器为例,通过建立小字库,结合具体实例介绍了实现多级菜单显示的方法。
当菜单显示内容改变时,只需修改相应参数,而不修改程序。
文中提及的硬件电路和软件设计通用性较强,具有更一般的实际意义。
关键词:单片机;液晶显示器;接口;多级菜单中图分类号:TP311 文献标识码:A0 引 言在单片机系统中,常用的小型显示器有L ED 和LCD 两种,L ED 显示器只能显示数字和少量字符,用户须根据系统设计时所约定的格式来了解系统的运行状况或进行操作,而点阵图形式LCD 不仅体积小、超薄、功耗低,而且能显示汉字、图形、表格及曲线等,其界面友好,它常被用在仪器设备中作为显示终端或人机接口等,特别适合于我国具有自主知识产权产品的开发,应用前景十分广阔。
因此,要采用菜单驱动的工作方式来控制仪器设备的运行,在LCD 上如何实现多级菜单的显示也就成为必须要解决的问题。
本文在建立中、西文小字库的基础上,介绍了单片机与LCD 间的硬件接口电路以及实现多级菜单的软件设计方法,具有较强的通用性。
1 GXM -12864显示模块简介图1 CXM -12864液晶模块电路框图Fig.1 The structure of GXM -12864LCD GXM -12864显示模块是南京国显电子公司推出的一款集控制、驱动、显示于一体的图形点阵式LCD产品,其点阵数为128(列)×64(行),内部使用一片行驱动器HD61203和两片列驱动器HD61202组成驱动控制系统。
单片机汇编语言下LCD多级菜单的一种实现方法

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

51单片机YM12864汉字图形点阵液晶显示模块­本文以AT89C51单片机控制使用比较普遍的YM12864液晶显示器为基础,介绍了一种采用分页原理实现多级中文菜单操作的方法。
给出了YM12864主要技术参数、显示特性和核心的程序。
设计的中文菜单具有一定的通用性,只需更改其中的菜单项即可将此设计应用到家电、仪器仪表等设备上,为操作者提供友好方便的中文操作界面。
51单片机YM12864汉字图形点阵液晶显示模块-_典型应用电路图。
目前小型的显示器主要有LCD和LED,LED显示器只能显示数字和有限个英文字符,不能显示汉字,显示内容不直观,操作人员只能根据约定格式了解显示内容。
而LCD则可显示各种汉字和图形,尤其能实现中文菜单显示,为操作者提供方便友好的操作界面,并且功耗低,因此LCD得到广泛应用。
而现在市面上带中文字库的LCD比比皆是,价格适中,且大部分具有与MUC统一的标准接口,为使用LCD实现中文菜单操作提供了很大的方便。
相信更多的电子产品在提升性能的同时,设计更加人性化的中文菜单交互界面,将会使产品具有更广阔的前景。
二、YM12864液晶显示模块简介YM12864汉字图形点阵液晶显示模块,可显示汉字及图形,内置8192个中文汉字(16X16点阵)、128个字符(8X16点阵)及64X256点阵显示RAM(GDRAM)。
主要技术参数和显示特性:电源:VDD 3.3V~+5V(内置升压电路,无需负压)显示内容:128列×64行与MCU接口:8位或4位并行/3位串行多种软件功能:光标显示、画面移位、自定义字符、睡眠模式等。
其引脚功能为通用20脚LCD接口,用户指令集也为通用128*64LCD用户指令集,相关资料很容易获取。
因其内置中文字库,省去了自己造字库的工作量,而只需写入相应的汉字和字符内码即可显示所需要的汉字和字符,这在许多程序开发软件中很容易实现,如:WAVE、KEIL等。
单片机C语言下LCD多级菜单的一种实现方法

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

用51单片机控制led显示汉字,电路中行方向由p0口和p2口完成扫描,由于p0口没有上拉电阻,因此接一个4.7k*8的排阻上拉。
如没有排阻,也可用8个普通的4.7k 1/8w电阻。
为提供负载能力,接16个2n5551的NPN三极管驱动。
列方向则由4—16译码器74LS154完成扫描,它由89C51的P1.0---P1.3控制。
同样,驱动部分则是16个2N5401的三极管完成的。
电路的供电为一片LM7805三端稳压器,耗电电流为100ma左右。
采用一块12*20cm的万能电路板,应当选用质量好些的发光管,(否则有坏点现象,更换起来较麻烦)首先将256个发光管插入电路板,注意插入方向,同时使高度一致,行方向直接焊接起来,列方向则搭桥架空焊接,完成后用万用表测试一下如有不亮的更换掉。
然后找一个电脑硬盘的数据线,截取所需的长度,分别将行,列线引出至电路的相关管脚即可。
原理图为了简洁,故只画出了示意图,行列方向只画出了2个三极管,屏幕只画出4个发光管,实际上发光管为256只,三极管行列方向各16只,一共32只。
焊接过程认真仔细一天时间即可完成全部制作。
将程序编译后烧写入89c51, 插入40pin Ic座,即可看到屏幕轮流显示:“倚天一出宝刀屠龙”。
当然,你可将程序的汉字代码部分更换为您所需要的代码即可显示你所需要的汉字。
程序清单:ORG 00HLOOP: MOV A,#0FFH ;开机初始化,清除画面MOV P0,A ;清除P0口ANL P2,#00 ;清除P2口MOV R2,#200D100MS: MOV R3,#250 ;延时100毫秒DJNZ R3,$DJNZ R2,D100MSMOV 20H,#00H ;取码指针的初值l100: MOV R1,#100 ;每个字的停留时间L16: MOV R6,#16 ;每个字16个码MOV R4,#00H ;扫描指针清零MOV R0,20H ;取码指针存入R0L3: MOV A,R4 ;扫描指针存入AMOV P1,A ;扫描输出INC R4 ;扫描指针加1,扫描下一个MOV A,R0 ;取码指针存入AMOV DPTR,#TABLE ;取数据表的上半部分的代码MOVC A,@A+DPTRMOV P0,A ;输出到P0INC R0 ;取码指针加1,取下一个码。
lCD5110 多级菜单

void (*KeyFuncPtr)(); //定义按键功能指针
//定义类型
typedef struct
{
unsigned char KeyStateIndex; //当前的状态索引号
unsigned char KeyUp; //按下向上键时的状态索引号
{8,7,6,3,8, (*Menu2_2)}, //第三层菜单 选择第2行,跳到第1行(up),跳到第0行(down),跳到第1层第0行(lift),跳到第2行(Right)
};
//=====================================================================
LCD_DispStringAscii6x8(0, 1, " Menu2-1");
LCD_DispStringAscii6x8(0, 2, " Menu2-2");
}
void Menu2_1(void) //在第2层菜单选中第1个选项
{
LCD_ClrScr(); //清屏
LCD_DispStringAscii6x8(0, 0, " Menu2-0");
} StateTab;
//=====================================================================
//数据结构数组
StateTab code KeyTab[]=
{
{0,2,1,0,3, (*Menu0_0)}, //顶层菜单 索引,上,下,左,右
(*KeyFuncPtr)(); //执行当前的按键操作
基于51单片机的图形液晶显示器汉字显示方法分析

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

单片机多级菜单编程实现单片机多级菜单编程实现(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。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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来实现中文菜单操会更加简便。
三、原理分析
通常的人机交互界面有两种方式,选择菜单和输入参数,为了便于分析,本文使用三级树状菜单结构,如图1所示,来阐述中文菜单的显示原理。
因YM12864满屏能显示四行、每行八个汉字,故将四个选择或参数输入菜单项编为一页,不足一页的补空格。
补空格的目的是为了归一化操作,可大大简化程序。
每一个菜单、参数输入、空格都为固定的八个汉字空间。
图1中顶级菜单1、顶级菜单2、顶级参数输入3、顶级4构成一级菜单,四个菜单项为一页同时显示在液晶屏幕上;一级菜单1-1、一级菜单1-2、一级参数输入1-3、一级空格1-4构成了顶级菜单1下的二级菜单,也组成一页同时显示在液晶屏幕上,三级菜单也是如此。
使用4*4键盘进行操作,其中“0-9”为数字键,“Esc”为删除/返回键,“Down”为向下选择健,“Enter”为确定健,剩余三个按键预留备用,为了不与其他程序的通用寄存器混淆,而使用89C51的第二组通用寄存器R0和R2来记录菜单的页码和行码(光标所在的菜单行)。
现通过按键的功能来分析多级中文菜单的原理。
当按下“Down”键后,光标移动一行(光标所在的行表示此行显示的菜单处于激活状态)行码加1,即(R2)=(R2)+1;当光标已在本级菜单的最后一项,此时按下“Down”键,光标回到本级菜单的首项,行码为0,即(R2)=0。
例如:光标处于二级菜单1-1-1,按下“Down”键,则光标移动到二级菜单1-1-2。
按下“Enter”,分两种情况处理,如为选择菜单,则根据页码和行码的值:R0*4+R2调用下一级子菜单显示,同时将子菜单的页码赋值给R0,得到子菜单的页码,并且使行码R2=0,表示处于此级菜单的首项。
例如:光标处于顶级菜单1,按下“Enter”键,则液晶显示屏上显示一级菜单1-1、一级菜单1-2、一级参数输入1-3、一级空格1-4。
如为参数输入菜单,则进入相应的参数输入对话框。
例如:光标处于参数输入1-3,按下“Enter”健,则液晶显示屏上显示对应的要求输入参数的对话框(一般为数字,为了简化程序,可采用统一的参数输入对话框),此时输入符合要求的参数,再按下“Enter”键,菜单将返回到上一级菜单,同时将输入到YM12864液晶显示器的数据读出,送到相应的单元存储,以备使用。
“Esc”键起到返回上一级菜单和删除参数输入时的错误输入双重功能,程序中只需使用一标志位来区分选择菜单和参数输入菜单即可,同时修改页码和行码值,即R0和R1的值。
例如:液晶屏上显示二级菜单1-1-1、二级菜单1-1-2、二级菜单1-1-3、二级空格1-1-4,此时按下“Esc”键,则返回到一级,屏幕上显示一级菜单1-1、一级菜单1-2、一级参数输入1-3、一级空格1-4。
四、硬件设计
使用89C51的P1口作为液晶显示器的数据口,使用P0口作为键盘扫描端口,当然这些端口也可以使用扩展口,只需在程序的开头修改端口的值便可。
电路图如图1所示。
五、软件设计
重点在于软件的设计,而程序的关键又在于使用了分页的操作方式。
以下为
菜单数据,按页的方式存放,不足一页的补空格。
TABLE00:
DB’顶级菜单1 ‘;第0页,每页为4行
DB’顶级菜单2 ‘
DB ‘顶级参数输入3 ‘
DB ‘’;此为顶级空格4
TABLE10:
DB ‘一级菜单1-1 ‘;第1页
DB ‘一级菜单1-2 ‘DB ‘一级参数输入1-3 ‘
DB ’‘;此为一级空格1-4
TABLE20:
DB ‘一级菜单2-1 ‘;第2页
DB ‘一级参数输入2-2 ‘DB ‘‘;此为一级空格2-3
DB ‘‘;此为一级空格2-4
…………………………
由于篇幅有限,不能将所有的程序都写出,只是将程序的框架列出,其它程序如:按键扫描子程序、YM12864显示子程序可参照其它资料。
实际应用时需要根据具体情况加以补充。
六、结语
本方法设计的多级中文菜单易于实现、可靠性高,并且具有一定的通用性和使用价值,实际应用时根据产品的操作要求修改上述的菜单名称即可。
当某级菜单的项目数有多页时,为方便操作,可增加翻页按键;所有菜单的页数最大为256页,共1024个菜单项,对于一般的系统完全够用。
采用此方法设计的全中文菜单操作的信号发生器曾获得2007年全国大学生电子设计大赛三等奖(江西赛区)。
参考文献
[1]毕万新.单片机原理与接口技术[M].大连理工大学出版社,2005,8.
[2]夏继强,沈德金,邢春香.单片机实验与实践教程[M].北京航空航天大学出版社,2006,5.
[3]高吉祥.全国大学生电子设计竞赛培训系列教程[M].电子工业出版社,2007,5.。