12864液晶多级菜单设计

合集下载

由LCD12864初探嵌入式菜单设计(完全资料)

由LCD12864初探嵌入式菜单设计(完全资料)

1、位操作 向 LCD12864 这种二值屏幕,我们习惯于用 1 个字节表示连续的 8 个点,1 对应对应位被点亮,0 表示不
亮,所以对图形的操作最基本的手段就是位操作。 复习下,常用的位操作,假设 Dis 表示某一个现存地址的内容 Dis = Dis~ 黑白颠倒 Dis &= ~(1<<n) 第 n 处被擦去, Dis |= (1<<n) 第 n 处被画了一个点 Dis ^= (1<<n) 如果 n 处是亮的,就变被擦掉;如果 n 处是空白的,就被点亮…… …… 差不多就这些
default: TempData |= (1 << BX);
}
setY(X);
500361 sendDataToLCD(TempData); ll648 } om/ba 特别说明一下,关于贪食蛇范例的问题,这篇文章里面只会简单得提及一下。 idu.c 作为嵌入式系统开发的一个范例,我会另外开一个帖子详细说明开发过程。 i.ba 这个范例将作为介绍嵌入式系统开发方法的一个很好的例子,用于解释一个系统和一段表示您调通了某一 ://h 个功能的代码之间有什么区别,同时也将介绍嵌入式开发系统的几种模式(超级循环、调度器),顺便侃一
PDF 文件使用 "pdfFactory Pro" 试用版本创建
首先,我们从最基本的数学算法说起。 如果我们使用公式 y = kx + b 来作为绘图的依据,那么就需要分 3 种情况:水平直线,斜率为 0;垂直直
硬件平台:AVR Mega8 级 LCD: 不带字库的 12864 软件平台:ICC 规范: 符合基本的 C 编程规范
3、何时开始正文 其实,本文应该算是计算机图形学的一个具体分支,所以,计算机图形学的基本要求就是本文的基本要求, 考虑到各位兄弟的胃口,我就多罗嗦下。

旋转编码器控制12864液晶多级菜单显示

旋转编码器控制12864液晶多级菜单显示

(5)、工作电流:2.0mAmax
5、接口说明
管 管脚 电平 脚 号
1 VSS 0V
2 VDD 5.0V
3 V0
说明
逻辑电源地。 逻辑电源正。 LCD 驱动电压,应用时在 VEE 与 V0 之间加一 10K 可调电阻。
4 D/I H/L
5 R/W H/L
6
E H.H/L
7 DB0 H/L
8 DB1 H/L
Line 0 1/0 1/0 1/0 1/0 …………
1/0 1/0 1/0 DB0
Line 1 1/0 1/0 1/0 1/0 …………
1/0 1/0 1/0 DB1
Line 2 1/0 1/0 1/0 1/0 ………… X=0
1/0 1/0 1/0 DB2
Line 3 1/0 1/0 1/0 1/0 …………
(4)、输入电压:Vee~Vdd
(5)、工作温度
:0~55℃(常温) / -20~70℃(宽温)
(6)、保存温度
:-10~65℃
4、电气特性
(1)、输入高电平
:3.5Vmin
(2)、输入低电平(Vil):0.55Vmax
(3)、输出高电平( ):3.75Vmin
(4)、输出低电平(Vol):1.0Vmax
(1)、显示开/关设置
L
L
L
L
H
H
H
H
H H/L
功能:设置屏幕显示开/关。 DB0=H,开显示;DB0=L,关显示。不影响显示 RAM(DD RAM)中的内容。
(2)、设置显示起始行
L
L
H
H
行地址(0~63)
功能:执行该命令后,所设置的行将显示在屏幕的第一行。显示起始行是由 Z 地址计数 器控制的,该命令自动将 A0-A5 位地址送入 Z 地址计数器,起始地址可以是 0-63 范围 内任意一行。Z 地址计数器具有循环计数功能,用于显示行扫描同步,当扫描完一行后 自动加一。

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

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

第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组成驱动控制系统。

电子信息工程专业毕业设计--基于51单片机的12864液晶显示器的设计和研究

电子信息工程专业毕业设计--基于51单片机的12864液晶显示器的设计和研究

目录设计总说明 (I)INTRODUCTION (II)1 绪论 (1)1.1课题背景及研究意义 (1)1.2课题研究的主要内容 (1)1.3国内外发展状况与存在问题 (1)2 总体方案设计与论述 (2)2.1 系统需求分析 (2)2.2 系统总体方案设计 (2)2.2.1 设计方案论证 (2)2.2.2总体结构框图 (3)3系统单元模块设计 (3)3.1系统硬件示意图 (3)3.2主控芯片(STC89C52模块)[5] (4)3.3 时钟控制模块[13] (6)3.3.1 DS1302简介 (6)3.3.2引脚及功能表 (7)3.3.3工作原理 (7)3.3.4 DS1302电路设计图[9] (8)3.4 温度控制模块 (8)3.5 12864接口电路模块 (9)3.6 按键电路模块 (9)3.7 电源电路模块 (10)3.8 印制电路板[9] (10)4系统整体调试与结果分析 (11)4.1 系统总体程序流程介绍 (11)4.2 按键程序设计 (13)4.3 12864驱动程序设计[15] (14)4.3.1 ST7920芯片介绍[14] (14)4.3.2 ST7920驱动程序设计 (17)4.4 12864应用程序设计 (20)4.4.1 文字显示程序设计 (20)4.4.2 点、线显示程序设计 (22)4.4.3 图形、图片显示程序设计 (23)4.5 菜单程序设计 (26)5设计调试及进一步研究 (28)5.1 系统测试 (28)5.1.1 软件调试 (28)5.1.2 硬件调试 (29)5.2 进一步研究的工作 (30)6总结 (30)鸣谢................................................................................................................................ 错误!未定义书签。

msp430单片机12864二级菜单

msp430单片机12864二级菜单

#include <msp430x14x.h>#define uchar unsigned char#define uint unsigned int#define LCD_data P5DIR=0XFF //数据口输出#define LCD_CMDOUT P3DIR|=0xe0 //P3口的高三位设置为输出#define LCD_RS_LOW P3OUT &= ~BIT7 //RS=0#define LCD_RS_HIGH P3OUT |=BIT7 //RS=1#define LCD_RW_LOW P3OUT &= ~BIT6 //RW=0#define LCD_RW_HIGH P3OUT |=BIT6 //RW=1#define LCD_EN_LOW P3OUT &= ~BIT5 //EN=0#define LCD_EN_HIGH P3OUT |=BIT5 //EN=1uchar k=0,flag=0,flag1=0;uchar dis1_[] = {"系统初始化. "};uchar dis2_[] = {"系统初始化.. "};uchar dis3_[] = {"系统初始化... "};uchar dis4_[] = {" 按选择键开始! "};uchar dis1[] = {"手1:手机设定"}; //一级菜单1uchar dis2[] = {"机2:管理器"}; //一级菜单2uchar dis3[] = {"菜3:通话"}; //一级菜单3uchar dis4[] = {"单4:信息功能"}; //一级菜单5uchar dis5[] = {"手5:文件管理"}; //一级菜单7uchar dis6[] = {"机6:通讯录"}; //一级菜单8uchar dis7[] = {"菜"}; //一级菜单8uchar dis8[] = {"单"}; //一级菜单8uchar dis1_1[] = {"手1:时间和日期"}; //一级菜单1下的子菜单1 uchar dis2_1[] = {"机2:语言"}; //一级菜单1下的子菜单2 uchar dis3_1[] = {"设3:语音控制"}; //一级菜单1下的子菜单3 uchar dis4_1[] = {"定4:关闭无线电"}; //一级菜单1下的子菜单4uchar dis1_2[] = {"管1:闹铃"}; //一级菜单2下的子菜单1 uchar dis2_2[] = {"理2:视频电话"}; //一级菜单2下的子菜单2 uchar dis3_2[] = {"器3:日历"}; //一级菜单2下的子菜单3 uchar dis4_2[] = {" 4:任务"}; //一级菜单2下的子菜单4uchar dis1_3[] = {"通1:全部"}; //一级菜单3下的子菜单1 uchar dis2_3[] = {"话2:已接来电"}; //一级菜单3下的子菜单2 uchar dis3_3[] = {" 3:未接来电"}; //一级菜单3下的子菜单3 uchar dis4_3[] = {" 4:已拨电话"}; //一级菜单3下的子菜单4uchar dis1_4[] = {"信1:编写新信息"}; //一级菜单4下的子菜单1uchar dis2_4[] = {"息2:收件箱"}; //一级菜单4下的子菜单2uchar dis3_4[] = {"功3:电子邮件"}; //一级菜单4下的子菜单3uchar dis4_4[] = {"能4:草稿箱"}; //一级菜单4下的子菜单4uchar dis1_5[] = {"文1:相册"}; //一级菜单5下的子菜单1uchar dis2_5[] = {"件2:音乐"}; //一级菜单5下的子菜单2uchar dis3_5[] = {"管3:视频"}; //一级菜单5下的子菜单3uchar dis4_5[] = {"理4:图片"}; //一级菜单5下的子菜单4uchar dis1_6[] = {"通1:快速拨号"}; //一级菜单6下的子菜单1uchar dis2_6[] = {"讯2: 我的名片"}; //一级菜单6下的子菜单2uchar dis3_6[] = {"录3: 组群"}; //一级菜单6下的子菜单3uchar dis4_6[] = {" 4:特定号码"}; //一级菜单6下的子菜单4void delay_1ms(uint x){uint i,j;for(j=0;j<x;j++)for(i=0;i<113;i++);}void write_cmd(uchar cmd)//写指令数据到LCD :RS=L,RW=L,E=高脉冲,D0-D7=指令码{LCD_RS_LOW ;LCD_RW_LOW ;LCD_EN_LOW ;P5OUT = cmd;delay_1ms(1);LCD_EN_HIGH;delay_1ms(1);LCD_EN_LOW;}void write_dat(uchar dat)//写显示数据到LCD :RS=H,RW=L,E=高脉冲,D0-D7=数据。

由LCD12864初探嵌入式菜单设计(最完整资料)

由LCD12864初探嵌入式菜单设计(最完整资料)
case LCD12864_Graphic_Clear: TempData &= ~(1<<BX); break;
PDF 文件使用 "pdfFactory Pro" 试用版本创建
case LCD12864_Graphic_Not: TempData ^= (1 << BX); break;
//计算出属于哪个字节 //属于该字节的哪个位
2、读取 12864 的数据的时候,一定要注意,E 信号要在一个下降延之后持续拉高,然后才能正常独处数据;
假设直接拉高,的确也能读出数据,但是,等着抓头皮,发帖子“[跪求]大侠帮忙关于 12864——请使用明
确的大标题……”^_^
500361 --------------------------------------------ll648 废话少说(说的不少了),看源代码:
default: TempData |= (1 << BX);
}
setY(X);
500361 sendDataToLCD(TempData); ll648 } om/ba 特别说明一下,关于贪食蛇范例的问题,这篇文章里面只会简单得提及一下。 idu.c 作为嵌入式系统开发的一个范例,我会另外开一个帖子详细说明开发过程。 i.ba 这个范例将作为介绍嵌入式系统开发方法的一个很好的例子,用于解释一个系统和一段表示您调通了某一 ://h 个功能的代码之间有什么区别,同时也将介绍嵌入式开发系统的几种模式(超级循环、调度器),顺便侃一
PDF 文件使用 "pdfFactory Pro" 试用版本创建
储器的访问,其速度显然没有对片内 SRAM 的操作速度要快。如果我们使用那种常用的串行方式来作图(所 谓串行方式作图,就是绘图指令的执行和系统的其他操作时串行的,指令不完成,其它操作就不回被执行), 那么对于一些实时性要求高的系统来说就会造成重大隐患——甚至是不符合要求的;如果开辟一段片内存 储空间和 LCD 的存储器一一对应,在相同的时间段内,花费相同的资源来保持着两个存储空间的一致性, 那么就可以保证实时系统的稳定和可靠,保证画面显示的正常(因为允许跳帧嘛^_^)。这就是我们为什么 需要另外在片内选取一个显示缓冲区的原因。

我的lcd12864菜单大致框架7页word文档

我的lcd12864菜单大致框架7页word文档

我的lcd12864菜单大致框架2019-07-12 00:24:06| 分类:ELECTRONIC | 标签:|字号大中小订阅lcd12864菜单大致框架算是完成了,主要实现了两个功能----反白,翻页。

原本是想做一个多级---起码也得二级----菜单,但有意外的时间安排,故暂且放下。

个人认为比较费脑筋的是反白功能的制作。

首先12864并没有专门为用户准备单行的反白,要么一三行一块反,要么二四一块。

所以得参照前人的方法,即将字符显示与图像显示结合,在需要反白的部分用绘图功能全写上0xff,有自带的异或逻辑能成功反白。

这部分让我摸索了几小时。

其次是这种反白实现之前,得先给原来的图像全清掉,也正是这一步让89c52耗费了不少时间,选项切换间居然要用1s 的时间。

这是不能忍的啊。

所以自己想了一个办法,让图像整体清除换成部分清除。

思路是在选项光标变量Index_P 外再添一记录变量----Index_P_Pre-----以记录上一次选项所在位置,然后在清除图像的时候专门清除Index_P_Pre 对于的图像痕迹,这样就将清屏所需的时间减少了3/4。

好了,这个菜单模块总共用了6KB。

对于64KB的89C52来说还有很多空间,自己也可以放心弄下去。

以后的工作就是整合了。

/*Index_Num 数组元素最大序号Index 数组元素当前序号Index_P 选中项序号Index_P_Pre 上一选中项序号,用于快速清理上次所画下的图案*/#include <reg52.h>#include <intrins.h>#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};#define LCD_data P0 //数据口#define Index_Num 8typedef unsigned char uchar;typedef unsigned int uint;sbit Key1 = P1^0;sbit Key2 = P1^1;sbit LCD_RS = P2^6; //寄存器选择输入cssbit LCD_RW = P2^5; //液晶读/写控制sidsbit LCD_EN = P2^7; //液晶使能控制clksbit LCD_PSB = P3^2; //串/并方式控制sbit LCD_RST = P3^7; //液晶复位端口bdata uchar DataBuf;uint Index,Index_P_Pre;uint Index_P=0;uchar code Weibo[][16]={"hello","呀咦晗昱","weibo","/maixianyu","blog.163","maixianyu@126","123","456","789"};////////////////////////////////////////////// 200usvoid delay(int ms){uchar t;while(ms--){for(t=0; t<20; t++) ;}}////////////////////////////////////////////////////////////////// void Lcd_Write_8bit(uchar msg){uint i;uchar DataBuffer;DataBuffer=msg;for(i=0;i<8;i++){LCD_RW=(bit)(DataBuffer&0x80);LCD_EN=1;_nop_();_nop_();LCD_EN=0;_nop_();_nop_();DataBuffer<<=1;}}/////////////////////////////////////////uchar Lcd_Rec(uint RS){uint i;uchar Data_H,Data_L;LCD_RS=1;if(RS)Lcd_Write_8bit(0xfe);elseLcd_Write_8bit(0xfc);delayNOP();for(i=0;i<8;i++){LCD_EN=1;Data_H=(Data_H<<1)|LCD_RW;LCD_EN=0;}delayNOP();for(i=0;i<8;i++){LCD_EN=1;Data_L=(Data_L<<1)|LCD_RW;LCD_EN=0;}LCD_RS=0;DataBuf=(Data_H<<4)|Data_L;return DataBuf;}/////////////////////////////////////////bit Lcd_Busy(){return Lcd_Rec(0)&0x80;}/////////////////////////////////////////void Lcd_Write(uchar msg,uint dc){ //if dc equals 0,msg is a kind of cmd.while(Lcd_Busy());if(dc==0)DataBuf=0xf8;elseDataBuf=0xfa;delayNOP();LCD_RS=1;Lcd_Write_8bit(DataBuf);delayNOP();DataBuf=msg&0xf0;Lcd_Write_8bit(DataBuf);delayNOP();DataBuf=(msg<<4)&0xf0;Lcd_Write_8bit(DataBuf);LCD_RS=0;}////////////////////////////////////////////////////void Disp_black() //清理上一次画下的痕迹{uchar i,j;Lcd_Write(0x34,0); //写数据时,关闭图形显示if(Index_P_Pre<2){for(i=0+16*Index_P_Pre; i<16+16*Index_P_Pre; i++){Lcd_Write(0x80+i,0);Lcd_Write(0x80,0);for(j=0;j<16;j++)Lcd_Write(0x00,1);}}else{for(i=0+16*(Index_P_Pre-2);i<16+16*(Index_P_Pre-2);i++){Lcd_Write(0x80+i,0);Lcd_Write(0x88,0);for(j=0;j<16;j++)Lcd_Write(0x00,1);}}Lcd_Write(0x36,0); //写完数据,开图形显示}void convertChar(uchar CX) // 反白函数{uchar halfLineCnt, basicBlock,lcdPosX,lcdPosY;// if(f==1)Disp_black(); //清绘图区lcdPosY = 0x80;if (CX == 0){CX = 0x80;halfLineCnt = 16;}else if (CX == 1){CX = 0x80;halfLineCnt = 32;}else if (CX == 2){CX = 0x88;halfLineCnt = 16;}else if (CX == 3){CX = 0x88;halfLineCnt = 32;}lcdPosX = CX;for (; halfLineCnt != 0; halfLineCnt--){basicBlock = 16;Lcd_Write(0x34,0);Lcd_Write(lcdPosY,0);Lcd_Write(lcdPosX,0);Lcd_Write(0x30,0);for (;basicBlock != 0; basicBlock--){if (halfLineCnt > 16){Lcd_Write(0x00,1);}else{Lcd_Write(0xff,1);}}lcdPosY++;}Lcd_Write(0x36,0);Lcd_Write(0x30,0);}///////////////////////////////////////////////////void Lcd_Pos(uchar x,uchar y){uchar pos;if(x==1){x=0x80;}else if(x==2){x=0x90;}else if(x==3){x=0x88;}else if(x==4){x=0x98;}pos=x+y;Lcd_Write(pos,0);}///////////////////////////////////////////void Lcd_Menu(uint Head){uint j,i;uint Index_End=Head+3;// if(Index_End<=Index_Num){for(j=0;Head<=Index_End;Head++,j++){Lcd_Pos(j+1,0);i=0;while(i<15){if(Weibo[Head][i]!=0)Lcd_Write(Weibo[Head][i++],1);else{Lcd_Write(0x20,1);i++;}}delayNOP();}// }}///////////////////////////////////////////void Lcd_Init(void){LCD_PSB=0;LCD_RST=0;LCD_RS=0;LCD_RW=1;LCD_EN=0;delay(2);LCD_RST=1;delay(2);Lcd_Write(0x30,0); //ordinary cmddelay(2);Lcd_Write(0x0c,0); //how to showdelay(2);Lcd_Write(0x01,0); //cleardelay(2);}/////////////////////////////////////////void main(void){Lcd_Init();Key1=1;Lcd_Menu(Index);convertChar(Index_P);while(1){if(Key1==0&&Index>=0){delay(5);if(Key1==0&&Index>=0){if(Index_P==0&&Index>0)Lcd_Menu(--Index);if(Index_P>0){Index_P_Pre=Index_P;convertChar(--Index_P);}}}if(Key2==0&&Index_P<=3){delay(5);if(Key2==0&&Index_P<=3){if(Index_P==3&&Index<(Index_Num-3)) Lcd_Menu(++Index);if(Index_P<3){Index_P_Pre=Index_P;convertChar(++Index_P);}}}}}。

12864并行多级菜单程序

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,"删除*");LCD12864_Waddr(4,6);LCD12864_WPoss(0,"确定#");key=Key_Scan();//键盘扫描if(key_check==1)//检测是否有按键按下{if(key<='9'&&key>='0')//密码只能是数字{Password[PasswordIndex]=key;//存储输入的密码// LCD12864_WPoss(0," ");//////////////// 改动过++PasswordIndex; //记录输入密码的次数if(PasswordIndex>4) //如果次数超过4次返回重新输入{PasswordIndex=0;//清空索引Password[0]=0;//清空数组Password[1]=0;Password[2]=0;Password[3]=0;LCD12864_Clear();LCD12864_Waddr(3,1);LCD12864_WPoss(0,"密码只能为四位");Delay_1ms(4000);//延时两秒显示LCD12864_Clear(); //延时清空break;}if(PasswordIndex<=4){LCD12864_Waddr(2,3);LCD12864_WPoss(0,Password);//显示输入的密码LCD12864_WPoss(0," ");/// 改}//ModeFlag=10;//进入while(1) 重新开始///// 改}if(key=='#') //确认密码{if(PasswordIndex<4)//密码位数少于4位则返回重新输入{PasswordIndex=0;Password[0]=0;Password[1]=0;Password[2]=0;Password[3]=0;LCD12864_Clear();LCD12864_Waddr(3,1);LCD12864_WPoss(0,"密码只能为四位");Delay_1ms(4000);LCD12864_Clear();break;}if(Password[0]=='1'&&Password[1]=='2'&&Password[2]=='3'&&Password[3]=='4'){//如果输入密码正确则进入计数界面//ModeFlag=2;LCD12864_Clear();//// LCD12864_Waddr(1,5);//// LCD12864_WPoss(0,"00:00");// LCD12864_Waddr(2,4);//// LCD12864_WPoss(0,"2013/01/01");// LCD12864_Waddr(3,4);// LCD12864_WPoss(0,"星期一");//// LCD12864_Waddr(4,6);//// LCD12864_WPoss(0,"返回*");////// Second=0;//计数器清零// minite=0;//计数器清零// hour=0;// day=1;// month=1;}else //如果密码错误重新输入{//ModeFlag=10;//进入while(1) 重新开始LCD12864_Clear();LCD12864_Waddr(3,1);LCD12864_WPoss(0,"密码错误");Delay_1ms(4000);LCD12864_Clear();PasswordIndex=0;Password[0]=0;Password[1]=0;Password[2]=0;Password[3]=0;break;}}if(key=='*')//删除按键{Password[--PasswordIndex]=' ';//删除一位密码LCD12864_Waddr(2,3);LCD12864_WPoss(0,Password);//显示输入的密码LCD12864_WPoss(0," ");if(PasswordIndex<=0){PasswordIndex=0;break;}}key_check=0;LCD12864_Waddr(2,8);LCD12864_WPoss(0," ");}}//////////////////////////////////界面三///////////////////////////////////////////////////while(ModeFlag==2){LCD12864_Waddr(1,1);LCD12864_WPoss(0,"查看时钟");LCD12864_Waddr(1,6);LCD12864_WPoss(0," B向上");LCD12864_Waddr(2,1);LCD12864_WPoss(0,"查看图片");LCD12864_Waddr(2,6);LCD12864_WPoss(0," C向下");LCD12864_Waddr(3,1);LCD12864_WPoss(0,"空文件");LCD12864_Waddr(4,1);LCD12864_WPoss(0,"返回*");LCD12864_Waddr(4,6);LCD12864_WPoss(0,"确定#");key=Key_Scan();//键盘扫描if(key_check==1){key_check=0;if(key=='B'){if(hua>0)hua--;}if(key=='C'){if(hua<2)hua++;}if(hua>2)hua=0;switch(hua){case 0:{convertChar(1,1,10);break;}case 1:{ convertChar(2,1,10);break;}case 2:{convertChar(3,1,10);break;}}if(key=='#'){if(hua==0)ModeFlag=3;if(hua==1)ModeFlag=4;if(hua==2)ModeFlag=5;LCD12864_W (LCD12864_COM,0x30);break;}if(key=='*'){LCD12864_Clear();Delay_1ms(1000);ModeFlag=0;LCD12864_Clear();}}}/////////////////////////////////////////// 界面四//////////////////////////if(ModeFlag==3)//计数界面{///////// Password[ ]=" ";// LCD12864_Waddr(1,1);// LCD12864_WPoss(0," ");LCD12864_Clear();//LCD12864_Waddr(1,5);//LCD12864_WPoss(0,"00:00");LCD12864_Waddr(2,4);//LCD12864_WPoss(0,"2013/01/01");LCD12864_Waddr(3,4);LCD12864_WPoss(0,"星期一");//LCD12864_Waddr(4,6);//LCD12864_WPoss(0,"返回*");//Second=0;//计数器清零minite=0;//计数器清零hour=0;day=1;month=1;while(ModeFlag==3){ if(shan==0) // :以秒为单位进行闪烁{LCD12864_Waddr(1,6);LCD12864_WPoss(0," ");}if(shan!=0){LCD12864_Waddr(1,6);LCD12864_WPoss(0,":");}if(minite<10){LCD12864_Wnum(0,0);LCD12864_Wnum(minite,0);LCD12864_WPoss(0," ");}else{LCD12864_Wnum(minite,0);LCD12864_WPoss(0," ");}LCD12864_Waddr(1,5);if(hour<10){LCD12864_Wnum(0,0);LCD12864_Wnum(hour,0);}if(hour>=10){LCD12864_Waddr(1,5);LCD12864_Wnum(hour,0);}LCD12864_Waddr(2,8);if(day<10){LCD12864_Wnum(0,0);LCD12864_Wnum(day,0);}if(day>=10)LCD12864_Wnum(day,0); LCD12864_Waddr(2,6);if(month<10){LCD12864_WPoss(0,"/");LCD12864_Wnum(0,0);LCD12864_Wnum(month,0);LCD12864_WPoss(0,"/");}if(month>=10){LCD12864_WPoss(0,"/");LCD12864_Wnum(month,0);LCD12864_WPoss(0,"/");}LCD12864_Waddr(3,6);LCD12864_W(LCD12864_DAT,xingqi[k]);LCD12864_W(LCD12864_DAT,xingqi[k+1]);if(day>365)year++;LCD12864_Waddr(2,4);LCD12864_Wnum(year,0);key=Key_Scan();//键盘扫描if(key_check==1){key_check=0;if(key=='A'){ wei++;if(wei==7)wei=1;}switch(wei){case 1:{if(key=='B')hour++;if(hour>0){ if(key=='C')hour--;}convertChar(1,5,2);//写入字节break;}case 2:{if(key=='B')minite++;if(minite>0){ if(key=='C')minite--;}convertChar(1,6,3);break;}case 3:{if(key=='B')year++;if(year>0){ if(key=='C')year--;}convertChar(2,4,4);break;}case 4:{if(key=='B')month++;if(month>1){ if(key=='C')month--;}convertChar(2,6,3);break;}case 5:{if(key=='B')day++;if(day>1){ if(key=='C')day--;}convertChar(2,8,2);break;}case 6:{if(key=='B')k=k+2;convertChar(3,6,2);break;}}if(key=='*'){ModeFlag=2;Delay_1ms(40);LCD12864_Clear();}}}}////////////////////////////////// 界面五////////////////////////////// while(ModeFlag==4){LCD12864_Clear();LCD12864_Waddr(2,3);LCD12864_WPoss(0,"No pictures");LCD12864_Waddr(4,1);LCD12864_WPoss(0,"返回*");key=Key_Scan();//键盘扫描if(key_check==1){key_check=0;if(key=='*'){LCD12864_Clear();Delay_1ms(1000);ModeFlag=2;LCD12864_Clear();}}}///////////////////////////////// 界面六///////////////////////////////// while(ModeFlag==5){LCD12864_Clear();LCD12864_Waddr(2,3);LCD12864_WPoss(0,"啥也没有");LCD12864_Waddr(4,1);LCD12864_WPoss(0,"返回*");key=Key_Scan();//键盘扫描if(key_check==1){key_check=0;if(key=='*'){Delay_1ms(100);ModeFlag=2;LCD12864_Clear();}}}}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
索引号即用户想要执行哪个函数的代号,然后有三个键,用户可以自己定义别的按键,最后一个是函数指针,即索引号对应的函数。然后在定 义一个结构体数组,如下 key_table code table[n]= { {0,2,1,3,(*fun1)}, {1,0,2,4,(*fun2)}, {2,1,0,5,(*fun3)}, {3,0,6,3,(*fun4)}, {4,1,6,4,(*fun5)}, {5,2,6,5,(*fun6)}, {6,0,0,0,(*fun7)}, ............ }; 其中 n 为函数数组大小。下面详细介绍 key_table code table[n]里面的值是怎么确定的。 首先可以先这样定义该数组 key_table code table[n]= { {0,x,y,z,(*fun1)}, {1,x,y,z,(*fun2)}, {2,x,y,z,(*fun3)}, {3,x,y,z,(*fun4)}, {4,x,y,z,(*fun5)}, {5,x,y,z,(*fun6)}, {6,x,y,z,(*fun7)}, ............ }; 其中,x,y,z 是未知数,先不确定,他们对应的是三个键按下要指示的索引值,如果四个键,就有四个未知数,在确定他们之前,必须要了解自己函数执行什么命令。加入开始时 时执行数组里面的第一个即 table[0],而想在此按上键执行函数 fun6,那么 table[0]里面需要这样设置{0,5,y,z,(*fun1) }, 同样,如果希望按下键执行 fun7则需要设置为{0,x,6,z,(*fun1) } , 如果希望按确认键执行 fun3则需要设置为{0,x,y,2,(*fun1) } ; 如果上面三种情况都想要就设置为{0,5,6,2,(*fun1) }. 其它数组元素一次类推。这一步做完了看主程序里面(主要是 while(1)里面) 。 /*******************find index****************************/ switch(key) { case 0x44: break; case 0x24: break; case 0x14: break; default:break; } current_operation_index=table[func_index].current_operation; (*current_operation_index)();// 执行当前操作函数 其中,key 是返回的按键值,这个用户视情况而定, 下面是详细的例子, 主要是以结构体为基础设计的,以12864显示函数代替了用户需要的函数功能,只需要修改相应的函数和索引号,就可以达到任意界面切换了是小弟研究了还久才搞定的,虽然网 上也有这些,但是都不够系统,只有基本的东西,这篇例子希望能够给读者一些有用的东西,仅供参考哦! : #include <reg52.h> #include "fun.h" func_index=table[func_index].down;// 向下翻 func_index=table[func_index].enter;// 回车 func_index=table[func_index].up; // 向上翻
#include "lcd12864.h" #include "delay.h" #define uchar unsigned char sbit keydown=P0^0; sbit keyenter=P0^1; sbit keyup=P0^2; uchar func_index=0; void (*current_operation_index)(); typedef struct { uchar current; uchar up;//向上翻索引号 uchar down;//向下翻索引号 uchar enter;//确认索引号 void (*current_operation)(); } key_table; key_table code table[30]= { {0,3,1,4,(*fun1)},// 第一层,显示【清华大学】 、北京大学、重庆三峡学院、返回 {1,0,2,8,(*fun2)},// 第一层,显示清华大学、 【北京大学】 、重庆三峡学院、返回 {2,1,3,12,(*fun3)},// 第一层,显示清华大学、北京大学、 【重庆三峡学院】 、返回 {3,2,0,25,(*fun4)},// 第一层,显示清华大学、北京大学、重庆三峡学院、 【返回】 {4,7,5,16,(*fun5)},// 第二层,清华大学层下显示【地点】 、创建时间、简介、返回 {5,4,6,17,(*fun6)},// 第二层,清华大学层下显示地点、 【创建时间】 、简介、返回 {6,5,7,18,(*fun7)}, // 第二层,清华大学层下显示地点、创建时间、 【简介】 、返回 {7,6,4,0,(*fun8)},// 第二层,清华大学层下显示地点、创建时间、简介、 【返回】 {8,11,9,19,(*fun9)},// 第二层,北京大学层下显示【历史】 、政治、简介、返回 {9,8,10,20,(*fun10)},// 第二层,北京大学层下显示历史、 【政治】 、简介、返回 {10,9,11,21,(*fun11)}, // 第二层,北京大学层下显示历史、政治、 【简介】 、返回 {11,10,8,1,(*fun12)},// 第二层,北京大学层下显示历史、政治、简介、 【返回】 {12,15,13,22,(*fun13)},// 第二层,重庆三峡学院层下显示【简介】 、最佳院系、最佳实验室、返回 {13,12,14,23,(*fun14)}, // 第二层,重庆三峡学院层下显示简介、 【最佳院系】 、最佳实验室、返回 {14,13,15,24,(*fun15)}, // 第二层,重庆三峡学院层下显示简介、最佳院系、 【最佳实验室】 、返回 {15,14,12,2,(*fun16)}, // 第二层,重庆三峡学院层下显示简介、最佳院系、最佳实验室、 【返回】 {16,16,16,4,(*fun17)}, // 第三层,清华大学地点层 {17,17,17,5,(*fun18)}, // 第三层,清华大学创时间层 {18,18,18,6,(*fun19)}, // 第三层,清华大学简介层 {19,19,19,8,(*fun20)}, // 第三层,北京大学历史层 {20,20,20,9,(*fun21)}, // 第三层,北京大学政治层 {21,21,21,10,(*fun22)}, // 第三层,北京大学简介层 {22,22,22,12,(*fun23)}, // 第三层,重庆三峡学院简介层 {23,23,23,13,(*fun24)}, // 第三层,重庆三峡学院最佳院系层 {24,24,24,14,(*fun25)}, // 第三层,重庆三峡学院最佳实验室层 {25,25,25,0,(*fun26)}, // 第0层 }; void main() { init_lcd(); //初始化 LCD 模块 while(1) { /*******************find index****************************/ if((keyup==0)||(keydown==0)||(keyenter==0)) { delay(10);//消抖 if(keyup==0) { func_index=table[func_index].up; while(!keyup);//松手检测 } if(keydown==0) { func_index=table[func_index].down; while(!keydown); } // 向下翻 // 向上翻
if(keyenter==0) { func_index=table[func_index].enter; while(!keyenter); } init_lcd(); { current_operation_index=table[func_index].current_operation; (*current_operation_index)();// 执行当前操作函数 } } // 确认
12864多级菜单设计
看到网上有个视频,用的是12864做的菜单,很花哨,自己也心痒痒想做一个,收集了 很多关于这方面的东西,但是都是五花八门,没有一个完整的可以共大家参考的程序,所 以决定写偏文章供大家参考,希望读者下去自己优化,改进。有什么不足之处还请多多包涵。好了,废话不多说,直接进入正题吧。 1、首先定义一个机构体如下 typedef struct { uchar current; //当前状态 uchar up;//上键 uchar down;//下键 uchar enter;//确认键 void (*current_operation)(); //当前状态应该执行的功能操作 } key_table;
相关文档
最新文档