大家讨论下基于LCD的菜单函数的编写,有我最近正在写的一个
大家讨论下基于LCD的菜单函数的编写.我的情况是12864不带字库LCD,4*4键盘.
以前也做过类似的,不过还是用51汇编做的,现在回头看看很不规范
因为项目时间比较紧,而且用的STM32以前也没用过,本来想用图标来做菜单,想了下还是用文字的方式
一个界面四行四个菜单,反显当前选中菜单,支持滚动菜单,程序肯定还有冗余的地方,不过时间关系没有太多思考
在网上搜了下,找到一些参考,但都不能直接拿来用,于是改了下,下面是我定义的结构体
typedef struct
{
const UCHAR NowMenu; //菜单索引
const UCHAR UpMenu; //向上菜单
const UCHAR DownMenu;//向下菜单
const UCHAR BackMenu;//返回菜单
const UCHAR EnterMenu;//进入菜单
const UCHAR UpMenuGroup; //向上菜单显示
const UCHAR DownMenuGroup; //向下菜单显示
const UCHAR **String; //指向当前菜单字库
const UCHAR EnterProgram;//是否按下确认键后执行程序
void (*Subs)(); //按下确认键后执行的程序
}Menu;
typedef struct
{
UCHAR NowMenu; //当前菜单
UCHAR UpMenu; //向上
UCHAR DownMenu; //向下
UCHAR BackMenu; //返回
UCHAR EnterMenu; //确认
UCHAR MenuGroup; //当前显示菜单
}MenuRam;
主程序如下:
while(1)
{
if(Flag20ms==1)
{
Flag20ms=0;
DivKey(); //读键
}
if(1==FlagKeyDo)//是否按下了一次键
{
FlagKeyDo = 0;
switch(TempKeyValue) //判断键值
{
case UPKEY:{NowMenuStruct.NowMenu=NowMenuStruct.UpMenu;
}break;
case DOWNKEY:{NowMenuStruct.NowMenu=NowMenuStruct.DownMenu;
}break;
case BACKKEY:{NowMenuStruct.NowMenu=NowMenuStruct.BackMenu;
}break;
case ENTERKEY:{
if(MenuStruct.EnterProgram==0)
NowMenuStruct.NowMenu=NowMenuStruct.EnterMenu;
else
(MenuStruct.Subs)();
}break;
default:break;
}
MenuStructInit(); //更新菜单
InitDisplay();
}
}
}
void MenuStructInit(void)
{
UCHAR i;
NowMenuStruct.UpMenu = MenuStruct.UpMenu;
NowMenuStruct.DownMenu = MenuStruct.DownMenu;
NowMenuStruct.BackMenu = MenuStruct.BackMenu;
NowMenuStruct.EnterMenu = MenuStruct.EnterMenu;
if(XCDis()==0xff) //如当前菜单不在显示菜单行列,需更新当前显示菜单,即实现滚屏
{
if(TempKeyValue==DOWNKEY)
for(i=0;i<4;i++)
NowMenuStruct.MenuGroup=MenuStruct.DownMenuGroup;
if(TempKeyValue==UPKEY||TempKeyValue==ENTERKEY||TempKeyValue==BACKKEY)
for(i=0;i<4;i++)
NowMenuStruct.MenuGroup=MenuStruct.UpMenuGroup;
}
}
void InitDisplay(void)
{
WritePicture(MenuStruct].String,2,96,0,16,96); //显示当前界面四个菜单
WritePicture(MenuStruct].String,2,96,2,16,96);
WritePicture(MenuStruct].String,2,96,4,16,96);
WritePicture(MenuStruct].String,2,96,6,16,96);
CovDisplay(XCDis()*2,16,2,96); //反显当前选中菜单
}
UCHAR XCDis(void)
{
UCHAR x;
for(x=0;x<4;x++)
{
if(NowMenuStruct.NowMenu == NowMenuStruct.MenuGroup)
return x;
}
return 0xff;
}
在全局变量中定义菜单
我的一级菜单有7个选项,对应索引为1-7,如下定义:
Menu MenuStruct=
{
{0,0,0,0,0,{0,0,0,0},{0,0,0,0},(const UCHAR **)NONE,0,NULL },
{1,7,2,1,10,{1,2,3,4},{5,6,7,1},(const UCHAR **)FSSet,0,NULL //发送接收设置
},
{2,1,3,2,1,{2,3,4,5},{6,7,1,2},(const UCHAR **)DSet,0,NULL //数据包设置
},
{3,2,4,3,8,{3,4,5,6},{7,1,2,3},(const UCHAR **)ZDCheck,0,NULL //终端信息查询
},
{4,3,5,4,1,{4,5,6,7},{1,2,3,4},(const UCHAR **)TMSet,1,SetTime //时间设置
},
{5,4,6,5,1,{5,6,7,1},{2,3,4,5},(const UCHAR **)DCheck,0,NULL //历史数据查询
},
{6,5,7,6,12,{6,7,1,2},{3,4,5,6},(const UCHAR **)FYZSet,0,NULL //频率阈值设置
},
{7,6,1,7,1,{7,1,2,3},{4,5,6,7},(const UCHAR **)DW,0,NULL //电网噪声仪
},
.......
}
其中10为1的子菜单
8为3的子菜单
12为6的子菜单,其他的有的还没做
再定义
MenuRam NowMenuStruct;
初始化成1索引 楼上好啊,这么快就用上STM32了。
反而我开始弄51了。
菜单只是当初学单片机时写过一点,至今再没弄过。
个人倾向于把Node和NodeList区分开来。
由Node可以访问父NodeList和子NodeList,
由NodeList可以访问本级菜单所有Node。
以上只是想法,未实现过。 我也是被逼的没办法,还好STM32带有很丰富的库,虽然听说效率不高,但对新手来说还是很不错的
我上面的程序应该不成熟,但项目时间太紧,先把功能实现了再来优化吧. 过段时间我也要弄LCD的菜单系统了,向楼上的学习。 我写的菜单51下调试通过
点击此处下载 ourdev_441304.rar(文件大小:3K) (原文件名:菜单ok1.rar)
http://cache.amobbs.com/bbs_upload782111/files_14/ourdev_441305.JPG
(原文件名:IMG_2607_s.JPG)
看看我的就比较用以理解,希望大家批评指正
//菜单按键参数定义
#define MenuKey_Null 0
#define MenuKey_Up 12
#define MenuKey_Down 13
#define MenuKey_Ok 10
#define MenuKey_Cancel 11
//菜单响应函数声明头文件=======================================================================
#include "Menu_Function.h"
//菜单处理函数
extern void MenuFuntion1();
extern void MenuFuntion2();
//菜单资源文件
#include "Menu_res.h"===========================================================================
//菜单条目格式
//{要显示的的菜单文本,子菜单号,功能函数地址)
MenuItemStruct code MenuMain[]={
{"主1 条目1",1,Null},
{"主1 条目2",2,Null},
{"主1 条目3",3,Null},
{"功能函数1",MenuHasFunction,MenuFuntion1},
{"主1 条目5",0,Null},
};
MenuItemStruct code MenuSub1[]={
{"次1 条目1",0,Null},
{"次1 条目2",0,Null},
{"功能函数2",MenuHasFunction,MenuFuntion2},
{"次1 条目4",0,Null},
{"次1 条目5",0,Null},
{"次1 条目6",0,Null},
};
MenuItemStruct code MenuSub2[]={
{"次2 条目1",0,Null},
{"次2 条目2",0,Null},
{"次2 条目3",0,Null},
};
MenuItemStruct code MenuSub3[]={
{"次3 条目1",0,Null},
{"次3 条目2",0,Null},
{"次3 条目3",0,Null},
{"次3 条目4",0,Null},
{"次3 条目5",0,Null},
{"次3 条目6",0,Null},
{"次3 条目7",0,Null},
{"次3 条目8",0,Null},
{"次3 条目9",0,Null},
};
//全部菜单列表
MenuPanelStruct code MenuPanel[]={
{MenuPanelID(MenuMain)},
{MenuPanelID(MenuSub1)},
{MenuPanelID(MenuSub2)},
{MenuPanelID(MenuSub3)},
}; LZ 可不可以给个汇编的程序看看
我在弄4*4的1602显示
郁闷的是,我只能显示一位数字,个位数,就不知道怎么移到十位数上去
希望LZ指点一下 我正在搞 LCD界面的程序 算法,用液晶实现一个人机交互的菜单
1.菜单要求有3到4级;
2.每级用上,下,回车键,返回键 来选择,反白显示;
3.在最底层菜单调用相关程序实现一定的功能,程序中的参数可通过按键来变化;
各位如果有好的算法,请不吝赐教,大家一起来讨论! 标记下 mark mark 学习下 mark。 网络上最流行的做法是用结构体的函数指针就是楼主弄得那样!
一般来说 这种菜单的可移植性比较不好!!
可移植性好的菜单又比较复杂 容易 出错!
以前写的 随便粘贴点好像是3级的
INT8U SeqNum; // 数组Dict_Function中的某个元素在数组Dict_Function中位于第SeqNum位
struct {
INT8U IndexWork;
INT8U IndexUp;
INT8U IndexDown;
INT8U IndexEnter;
INT8U IndexBack;
void (*Ptr)(); // 网络或论文上有些源程序将Ptr命名为CurrentOperate,很显然:命名为CurrentOperate更好一点。
} code Dict_Function[] = {
// IndexWork
// |IndexUp
// | | IndexDown
// | || IndexEnter
// | ||| IndexBack
// | ||| | (*Ptr)()
// | ||| | |
{0, 2, 1, 3, 0, Show_Screen0},
{1, 0, 2, 6, 1, Show_Screen1},
{2, 1, 0, 9, 2, Show_Screen2},
/***********************************/
{3, 5, 4, 12, 0, Show_Screen00},
{4, 3, 5, 13, 0, Show_Screen01},
{5, 4, 3, 14, 0, Show_Screen02},
//-------------------------------
{6, 8, 7, 15, 1, Show_Screen10},
{7, 6, 8, 16, 1, Show_Screen11},
{8, 7, 6, 17, 1, Show_Screen12},
//-------------------------------
{9, 11, 10, 18, 2, Show_Screen20},
{10, 9, 11, 19, 2, Show_Screen21},
{11, 10, 9, 20, 2, Show_Screen22},
/***********************************/
{12, 12, 12, 12, 3, Show_Screen000},
{13, 13, 13, 13, 4, Show_Screen010},
{14, 14, 14, 14, 5, Show_Screen020},
{15, 15, 15, 15, 6, Show_Screen100},
{16, 16, 16, 16, 7, Show_Screen110},
{17, 17, 17, 17, 8, Show_Screen120},
{18, 18, 18, 18, 9, Show_Screen200},
{19, 19, 19, 19, 10, Show_Screen210},
{20, 20, 20, 20, 11, Show_Screen220},
}; 4楼的方法好,俺不喜欢反白!麻烦 mark mark 等高手现身 附源代码和例子
名称:GXD任意层深度菜单 v1.1
特点:可以在液晶LCM上显示最大254层深度的菜单,可以非常方便的使用和移植
作者:中国传惠 TranSmartgongxd@126.com
日期:2009-8-2
历史:
2009-8-2 添加N层菜单功能,修改屏幕参数定义
2009-3-4 初始版本
编译环境:
IDE-Version:
uVision3 V3.33
Copyright (c) Keil Elektronik GmbH / Keil Software, Inc 2006
Tool Version Numbers:
工具链路径:C:\Keil\C51\BIN\
C Compiler: C51.Exe V8.05a
Assembler: A51.Exe
Linker/Locator: BL51.Exe V6.00
Librarian: LIB51.Exe V4.24
Hex Converter: OH51.Exe V2.6
CPU DLL: S8051.DLL V3.06
Dialog DLL: DP51.DLL V2.48b
Target DLL: C:\KEIL\VW_C.DLL
Dialog DLL: TP51.DLL V2.48b
版权声明:
义务:
1.如果您在使用中发现任何BUG,请通知gongxd@126.com,我会及时改正,并给您一份最新的代码
2.请保留本声明
权利:
如果您同意履行上面的义务,您就可以完全免费将代码应用于任何商业非商业用途
但本代码版权归中国传惠gongxd@126.com 所有,否则严禁使用本代码
建议:
如果您作了什么改进希望能通知gongxd@126.com,最好能共享一下,
我也会给您一份 最新 的代码,共同进步嘛
后话:大家都不容易,如果您觉得这东西有点用,就尽情传播吧
点击此处下载 ourdev_466578.rar(文件大小:5K) (原文件名:GXD菜单1.1.rar)
//========================================== 用户配置参数============================
void init_Menu();//菜单初始化
void UpdateMenuPanelkey(unsigned char MenuKeyCode);//菜单按键更新
//菜单按键参数定义 根据实际键码修改
#define MenuKey_Null 0
#define MenuKey_Ok 0x05
#define MenuKey_Cancel 0x06
#define MenuKey_Up 0x07
#define MenuKey_Down 0x08
//===========================屏幕参数配置============
//一屏幕最大显示的行数
#defineScreenHLine 4
//菜单深度,最低1层,最大254层
#defineMenuDeep 1
//菜单条目前面的指示位置列
#defineMenuPointX 0
//菜单条目前面的指示字符
#defineMenuPointASCII '>'
//菜单条目显示的起始列
#defineMenuItemDisplayStartX1
//菜单条目显示的起始行
#defineMenuItemDisplayStartY0
//================================================== 用户配置参数====================
//菜单响应函数声明头文件=======================================================================
#include "Menu_Function.h"
//菜单处理函数
extern void MenuFuntion1();
extern void MenuFuntion2();
//菜单资源文件
#include "Menu_res.h"===========================================================================
//菜单条目格式
//{要显示的的菜单文本,子菜单号,功能函数地址)
MenuItemStruct code MenuMain[]={
{"主1 条目1",1,Null},
{"主1 条目2",2,Null},
{"主1 条目3",3,Null},
{"功能函数1",MenuHasFunction,MenuFuntion1},
{"主1 条目5",0,Null},
};
MenuItemStruct code MenuSub1[]={
{"次1 条目1",0,Null},
{"次1 条目2",0,Null},
{"功能函数2",MenuHasFunction,MenuFuntion2},
{"次1 条目4",0,Null},
{"次1 条目5",0,Null},
{"次1 条目6",0,Null},
};
MenuItemStruct code MenuSub2[]={
{"次2 条目1",0,Null},
{"次2 条目2",0,Null},
{"次2 条目3",0,Null},
};
MenuItemStruct code MenuSub3[]={
{"次3 条目1",0,Null},
{"次3 条目2",0,Null},
{"次3 条目3",0,Null},
{"次3 条目4",0,Null},
{"次3 条目5",0,Null},
{"次3 条目6",0,Null},
{"次3 条目7",0,Null},
{"次3 条目8",0,Null},
{"次3 条目9",0,Null},
};
//全部菜单列表
MenuPanelStruct code MenuPanel[]={
{MenuPanelID(MenuMain)},
{MenuPanelID(MenuSub1)},
{MenuPanelID(MenuSub2)},
{MenuPanelID(MenuSub3)},
}; 谢谢 mark mark mark.有时间学习一下! 数据结构关键啊。。。 过几天就用。谢谢。 【1楼】 void_c 上官金虹一统江湖
个人倾向于把Node和NodeList区分开来。
=====================================================
认同此法,仿照Windows的MenuItem和SubMenu的处理方法。
实现的多级菜单,更容易维护。 谢谢共享。 我也传一个写的很详细的菜单设计,让菜单资源全部集中到这个帖子里吧
点击此处下载 ourdev_475138.rar(文件大小:1.61M) (原文件名:一个占用内存极少的菜单系统的实现.rar) 多谢楼上几位了,马克! 标。。。。。个记 太好了 mark 好东西 有时间学习一下 mark 参考过论坛上以前一个LCD程序,但是显示变量时候觉得不是很方便 学习下! 强哦 MARK GUI MARK 留个脚印 MARK 标记。 LCD的菜单函数,标记! 学习菜单制作 mark.有时间学习一下! 怎在学习,谢提供了 mark LCD GUI 学习一下,mark。。 刚学,有点看不懂呀 mark 高手们讨论都是点阵液晶的吧?呵呵,我捣鼓了个字符2004液晶的人机交互,内存消耗不到40byte。可惜这些天要做毕设,没时间找出来整理 mark mark MARK 几号,备用。 很强标记下备用 积分混了不少了
业余的路过 m mark 留记号,学习 MARK GUI remind mark mark 学习... 我也来秀下我的菜单界面
http://cache.amobbs.com/bbs_upload782111/files_36/ourdev_616909TLZFS7.jpg
(原文件名:1.jpg)
http://cache.amobbs.com/bbs_upload782111/files_36/ourdev_616910US2MWY.jpg
(原文件名:2.jpg)
http://cache.amobbs.com/bbs_upload782111/files_36/ourdev_616911P8RXGW.jpg
(原文件名:3.jpg)
http://cache.amobbs.com/bbs_upload782111/files_36/ourdev_616912QZZ8M1.jpg
(原文件名:4.jpg)
菜单主体是参照傻孩子的程序写的,加入了返回时指向上一级目录、滚动条、按数字选择功能。关键是LCD的驱动难一些,要能显示5行
字体和任意位置显示字符和图形及反显,费了不少时间。 我的做得很蓝 正在学习中。 MARK mark 好资料 mark 谢谢楼主 谢谢楼主 现在正在搞一个128*64的菜单程序,以前虽然也搞过一个类似的,但是当时用的方法比较繁琐,想找一个管理各级菜单的好方法,学习了! 这么好的东西,一定得顶起! MARK 传惠那个菜单很不错,学习中。 mark,虽然现在用不到 mark mark mark 踩一下 开始接触菜单界面。 绝对是菜单的好帖子 标记备用 标记,学习了 标记下 好东西,顶起来! 留个脚印。 void_c 发表于 2009-5-1 10:00
楼上好啊,这么快就用上STM32了。
反而我开始弄51了。
支持一下! mark!!!慢慢看 学习学习 gongxd 发表于 2009-5-1 14:00
我写的菜单51下调试通过
点击此处下载 ourdev_441304.rar(文件大小:3K) (原文件名:菜单ok1.rar)
标记下!! 顶一下!
顶一下! 很好不错在这里先收着 帮顶一下
页:
[1]