lusson 发表于 2009-5-1 09:30:25

大家讨论下基于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索引

void_c 发表于 2009-5-1 10:00:50

楼上好啊,这么快就用上STM32了。
反而我开始弄51了。

菜单只是当初学单片机时写过一点,至今再没弄过。

个人倾向于把Node和NodeList区分开来。
由Node可以访问父NodeList和子NodeList,
由NodeList可以访问本级菜单所有Node。

以上只是想法,未实现过。

lusson 发表于 2009-5-1 10:11:44

我也是被逼的没办法,还好STM32带有很丰富的库,虽然听说效率不高,但对新手来说还是很不错的

我上面的程序应该不成熟,但项目时间太紧,先把功能实现了再来优化吧.

eiglxl 发表于 2009-5-1 10:33:57

过段时间我也要弄LCD的菜单系统了,向楼上的学习。

gongxd 发表于 2009-5-1 14:00:53

我写的菜单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)},
};

sevens 发表于 2009-5-19 16:23:20

LZ 可不可以给个汇编的程序看看

我在弄4*4的1602显示

郁闷的是,我只能显示一位数字,个位数,就不知道怎么移到十位数上去

希望LZ指点一下

GESHW 发表于 2009-5-25 09:58:27

我正在搞 LCD界面的程序 算法,用液晶实现一个人机交互的菜单

1.菜单要求有3到4级;

2.每级用上,下,回车键,返回键 来选择,反白显示;

3.在最底层菜单调用相关程序实现一定的功能,程序中的参数可通过按键来变化;

      各位如果有好的算法,请不吝赐教,大家一起来讨论!

seawind319 发表于 2009-5-25 13:28:37

标记下

max0147 发表于 2009-5-25 13:40:43

mark

wangff2531 发表于 2009-5-25 15:46:15

mark

ksniper 发表于 2009-5-26 11:03:11

学习下

443799600 发表于 2009-5-26 16:12:20

mark。

unsv 发表于 2009-6-5 23:46:54

网络上最流行的做法是用结构体的函数指针就是楼主弄得那样!

一般来说 这种菜单的可移植性比较不好!!

可移植性好的菜单又比较复杂 容易 出错!

以前写的 随便粘贴点好像是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},
};

unsv 发表于 2009-6-5 23:49:11

4楼的方法好,俺不喜欢反白!麻烦

bad_fpga 发表于 2009-6-5 23:52:52

mark

shamork 发表于 2009-6-6 08:25:34

mark 等高手现身

gongxd 发表于 2009-8-2 12:10:18

附源代码和例子

名称: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)},
};

jchqxl 发表于 2009-8-2 13:51:28

谢谢

sange 发表于 2009-8-5 18:16:09

mark

simone 发表于 2009-8-8 13:11:31

mark

maomao2126 发表于 2009-8-11 12:39:24

mark.有时间学习一下!

MoMo_avr 发表于 2009-8-14 15:40:39

数据结构关键啊。。。

lffpga 发表于 2009-8-26 23:46:39

过几天就用。谢谢。

McuPlayer 发表于 2009-8-27 00:47:08

【1楼】 void_c 上官金虹一统江湖
个人倾向于把Node和NodeList区分开来。
=====================================================
认同此法,仿照Windows的MenuItem和SubMenu的处理方法。
实现的多级菜单,更容易维护。

zwc58 发表于 2009-8-27 08:35:04

谢谢共享。

xczxwy 发表于 2009-8-27 09:48:35

我也传一个写的很详细的菜单设计,让菜单资源全部集中到这个帖子里吧
点击此处下载 ourdev_475138.rar(文件大小:1.61M) (原文件名:一个占用内存极少的菜单系统的实现.rar)

bygood 发表于 2009-10-8 19:21:10

多谢楼上几位了,马克!

song1km 发表于 2009-10-8 19:30:29

标。。。。。个记

asdasd 发表于 2009-10-8 19:35:44

太好了

oldmen 发表于 2009-10-8 19:52:14

mark

alexmayer 发表于 2009-10-9 14:37:04

好东西

smtgg 发表于 2009-10-9 15:44:33

有时间学习一下

yzlyear 发表于 2009-10-16 10:42:55

mark

mao001 发表于 2009-10-16 11:10:48

参考过论坛上以前一个LCD程序,但是显示变量时候觉得不是很方便

chenfzg 发表于 2010-2-22 23:45:05

学习下!

lv998127 发表于 2010-2-23 00:30:12

强哦

eduhf_123 发表于 2010-2-23 00:51:37

MARK GUI

wukaka 发表于 2010-4-17 19:55:30

MARK

david168 发表于 2010-4-30 23:57:03

留个脚印

MCU678 发表于 2010-5-1 02:46:48

MARK

AIHHLI 发表于 2010-5-1 07:36:49

标记。

lv998127 发表于 2010-5-1 09:54:41

LCD的菜单函数,标记!

huchengxtu 发表于 2010-5-1 11:32:34

学习菜单制作

benlippen 发表于 2010-5-1 13:59:35

mark.有时间学习一下!

SeaBear 发表于 2010-5-11 21:24:50

怎在学习,谢提供了

czhxp 发表于 2010-5-11 23:01:31

mark LCD GUI

hpjx1987 发表于 2010-5-12 15:34:46

学习一下,mark。。

anjiyou 发表于 2010-5-27 08:47:49

刚学,有点看不懂呀

726bf 发表于 2010-5-27 09:36:48

mark

younge 发表于 2010-5-27 12:52:38

高手们讨论都是点阵液晶的吧?呵呵,我捣鼓了个字符2004液晶的人机交互,内存消耗不到40byte。可惜这些天要做毕设,没时间找出来整理

zuceyige 发表于 2010-6-27 10:16:21

mark

fedora10 发表于 2010-6-29 10:05:40

mark

amazing030 发表于 2010-6-29 10:39:57

MARK

xdpj 发表于 2010-6-29 16:14:43

几号,备用。

cctv02 发表于 2011-1-29 23:20:10

很强标记下备用

czhaii 发表于 2011-1-31 04:38:22

积分混了不少了
业余的路过

Sullivan 发表于 2011-1-31 07:44:29

m

alexliu0915 发表于 2011-1-31 11:12:41

mark

skywym 发表于 2011-2-14 15:38:03

留记号,学习

winkle 发表于 2011-2-14 18:54:10

MARK GUI

updown 发表于 2011-2-14 22:00:27

remind

zhenhuah 发表于 2011-2-14 22:17:40

mark

downtoearth 发表于 2011-2-14 22:40:57

mark

CSU_David 发表于 2011-2-18 11:07:51

学习...

amazing030 发表于 2011-2-18 17:01:12

我也来秀下我的菜单界面
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行
字体和任意位置显示字符和图形及反显,费了不少时间。

MPV2011 发表于 2011-2-18 18:40:56

我的做得很蓝

hzxin 发表于 2011-2-20 09:09:36

正在学习中。

ERDTxiduoduo 发表于 2011-2-20 11:15:49

MARK

beiyunhe 发表于 2011-2-22 21:32:49

mark 好资料

cbmjd 发表于 2011-3-6 23:50:57

mark

hailin0716 发表于 2011-3-9 09:17:44

谢谢楼主

zhlrl 发表于 2011-3-23 10:47:43

谢谢楼主

kingjason2009 发表于 2011-3-28 11:35:17

现在正在搞一个128*64的菜单程序,以前虽然也搞过一个类似的,但是当时用的方法比较繁琐,想找一个管理各级菜单的好方法,学习了!

haolaishi 发表于 2011-8-4 18:36:17

这么好的东西,一定得顶起!

q2616444 发表于 2011-8-4 22:11:29

MARK

cumtgao 发表于 2011-8-5 09:20:40

传惠那个菜单很不错,学习中。

ijlc1314 发表于 2011-8-5 09:33:10

mark,虽然现在用不到

lcmdw 发表于 2011-8-5 09:36:40

mark

downtoearth 发表于 2011-8-5 10:32:47

mark

cyh19820818 发表于 2011-8-5 12:14:26

mark

yunduanmanbu06 发表于 2011-8-26 14:34:03

踩一下

lucya 发表于 2011-9-7 21:13:08

开始接触菜单界面。

qwaszxqw 发表于 2011-9-8 07:50:40

绝对是菜单的好帖子

z421868436 发表于 2011-9-8 10:36:02

标记备用

xifengxia 发表于 2011-9-8 12:53:58

标记,学习了

zhangyuanfeng 发表于 2011-9-8 12:58:25

标记下

wwqq 发表于 2012-10-26 13:49:59

好东西,顶起来!

jqfsjt 发表于 2012-10-26 20:05:18

留个脚印。

hamipeter 发表于 2012-10-26 21:08:17

void_c 发表于 2009-5-1 10:00
楼上好啊,这么快就用上STM32了。
反而我开始弄51了。



支持一下!

songjie 发表于 2012-12-19 21:24:41

mark!!!慢慢看

wadz365 发表于 2012-12-20 09:12:36

学习学习

hamipeter 发表于 2012-12-20 18:05:04

gongxd 发表于 2009-5-1 14:00
我写的菜单51下调试通过
点击此处下载 ourdev_441304.rar(文件大小:3K) (原文件名:菜单ok1.rar)



标记下!!

ruhuadexinkong 发表于 2012-12-22 15:44:34

顶一下!                     

qijun 发表于 2012-12-26 05:09:09


顶一下!

未来电子 发表于 2012-12-26 23:46:19

很好不错在这里先收着

danpianjibb 发表于 2012-12-27 17:31:18

帮顶一下
页: [1]
查看完整版本: 大家讨论下基于LCD的菜单函数的编写,有我最近正在写的一个