ATmega32 发表于 2007-6-10 20:43:22

傻孩子**电子菜单移植AVRGCC PROGMEM

傻孩子大人电子菜单移植AVRGCC PROGMEM

http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=457580&bbs_page_no=1&bbs_id=1000





/************************************menu.h**************************************/

#ifndef   __MENU_H__

#define   __MENU_H__

#include <avr/pgmspace.h>



typedef struct MenuItem_t   

{

    uint8_t Size;

    uint8_t * Str;

    void (*Sub)(void);

    struct MenuItem_t * Child;

    struct MenuItem_t * Parent;

}MenuItem_t;





#define MENU(A)                                A##Menu

#define MENU_STR(A,B)                        A##B##Str

#define MENU_SIZE(A)                        A##Size       

#define MENU_STR_DEF(A,B,C)                const char        MENU_STR(A,B)[] PROGMEM=C

#define MENU_STR_EXT(A,B)                extern char MENU_STR(A,B)[]

#define MENU_ITEM(A,B,C,D,E)                {MENU_SIZE(A),(uint8_t *)MENU_STR(A,B),C,( MenuItem_t * )D,( MenuItem_t * )E}

#define NULL_SUB                         (void (*)(void))0

#define NULL_MENU                        (MenuItem_t *)0       

#define MENU_SUB_DEF(A,B)\

void A##B##Sub(void)

#define MENU_SUB_EXT(A,B)\

extern void A##B##Sub(void)

#define MENU_SUB(A,B)   A##B##Sub

#define MENU_ARRAY_DEF(A,B)\

const MenuItem_t A PROGMEM =

#define MENU_ARRAY_EXT(A)\

extern const MenuItem_t A[]







#ifdef IN_MENU_C





#endif







#ifndef IN_MENU_C



extern const MenuItem_t MainMenu[];



#endif





#endif //__MENU_H__















/************************************menu.c**************************************/



#include "menu.h"

#define IN_MENU_C





/*******************************TimerMenu 选单**********************************/

#define TimerMenuSize        4

MENU_STR_DEF(TimerMenu,0,"1.显示时间");

MENU_STR_DEF(TimerMenu,1,"2.时钟调整:时");

MENU_STR_DEF(TimerMenu,2,"3.时钟调整:分");

MENU_STR_DEF(TimerMenu,3,"4.时钟调整:秒");



MENU_SUB_DEF(TimerMenu,0){/******用户函数******/}

MENU_SUB_DEF(TimerMenu,1){/******用户函数******/}

MENU_SUB_DEF(TimerMenu,2){/******用户函数******/}

MENU_SUB_DEF(TimerMenu,3){/******用户函数******/}



MENU_ARRAY_DEF(TimerMenu,TimerMenuSize)

{

/**********选单名*****序号******功能函数*********子选单********** 父选单********/

MENU_ITEM(TimerMenu,        0,                MENU_SUB(TimerMenu,0),                NULL_MENU,                MainMenu),

MENU_ITEM(TimerMenu,        1,                MENU_SUB(TimerMenu,1),                NULL_MENU,                MainMenu),

MENU_ITEM(TimerMenu,        2,                MENU_SUB(TimerMenu,2),                NULL_MENU,                MainMenu),

MENU_ITEM(TimerMenu,        3,                MENU_SUB(TimerMenu,3),                NULL_MENU,                MainMenu),

};











/*******************************CapMenu 选单**********************************/

#define CapMenuSize        1

MENU_STR_DEF(CapMenu,0,"0.显示频率");



MENU_SUB_DEF(CapMenu,0){/******用户函数******/}



MENU_ARRAY_DEF(CapMenu,CapMenuSize)

{

/**********选单名*****序号******功能函数*********子选单********** 父选单********/

MENU_ITEM(CapMenu,        0,                MENU_SUB(CapMenu,0),                NULL_MENU,                MainMenu),

};











/*******************************SongMenu 选单**********************************/

#define SongMenuSize        1

MENU_STR_DEF(SongMenu,0,"Song选单0");



MENU_SUB_DEF(SongMenu,0){/******用户函数******/}



MENU_ARRAY_DEF(SongMenu,SongMenuSize)

{

/**********选单名*****序号******功能函数*********子选单********** 父选单********/

MENU_ITEM(SongMenu,        0,        MENU_SUB(SongMenu,0),                NULL_MENU,                MainMenu),

};











/*******************************MainMenu 选单**********************************/

#define MainMenuSize        9

MENU_STR_DEF(MainMenu,0,"主选单TIMER");

MENU_STR_DEF(MainMenu,1,"主选单CAP");

MENU_STR_DEF(MainMenu,2,"主选单Song");

MENU_STR_DEF(MainMenu,3,"主选单3");

MENU_STR_DEF(MainMenu,4,"主选单4");

MENU_STR_DEF(MainMenu,5,"主选单5");

MENU_STR_DEF(MainMenu,6,"主选单6");

MENU_STR_DEF(MainMenu,7,"主选单7");

MENU_STR_DEF(MainMenu,8,"主选单8");





MENU_ARRAY_DEF(MainMenu,MainMenuSize)

{

/**********选单名*****序号******功能函数*********子选单********** 父选单********/

MENU_ITEM(MainMenu,                0,                NULL_SUB,                TimerMenu,                NULL_MENU),

MENU_ITEM(MainMenu,                1,                NULL_SUB,                CapMenu,                NULL_MENU),

MENU_ITEM(MainMenu,                2,                NULL_SUB,                SongMenu,                NULL_MENU),

MENU_ITEM(MainMenu,                3,                NULL_SUB,                NULL_MENU,                NULL_MENU),

MENU_ITEM(MainMenu,                4,                NULL_SUB,                NULL_MENU,                NULL_MENU),

MENU_ITEM(MainMenu,                5,                NULL_SUB,                NULL_MENU,                NULL_MENU),

MENU_ITEM(MainMenu,                6,                NULL_SUB,                NULL_MENU,                NULL_MENU),

MENU_ITEM(MainMenu,                7,                NULL_SUB,                NULL_MENU,                NULL_MENU),

MENU_ITEM(MainMenu,                8,                NULL_SUB,                NULL_MENU,                NULL_MENU),

};

傻孩子:关于那个标题……我很: - -b   非常感谢大家支持……

lanshuitianxia 发表于 2007-6-10 21:08:48

"傻孩子大人电子"是什么啊

ATmega32 发表于 2007-6-10 21:11:23

傻孩子大人发在论坛电子菜单



http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=457580&bbs_page_no=1&bbs_id=1000

lanshuitianxia 发表于 2007-6-10 21:23:51

哦,明白了,原来是这样啊!谢谢楼主你的例程,收下了。可以在12864上使用吗?

lanshuitianxia 发表于 2007-6-10 21:26:56

可以用的啊,有机会试试。

Gorgon_Meducer 发表于 2007-6-10 23:35:29

关于大家讨论的菜单技术,实际上是一种面向对象的技术:

回忆一下,什么是面向对象,就是把数据和处理数据的函数(方法)封装在一起。

我们把菜单信息(显示字符,菜单项位置等等)和处理该菜单的动作函数放在同一个结构体中,实际上就是一种面向对象。

这样做的实例其实还有很多。

参考下面的结构

switch (Number)

{

    case XXX:

      FunctionA()

      break;

    case XXX:

      FunctionB();

      break;

    ....

}

如果我们把XXX和对应的函数封装在同一个结构体中,就是消息地图了……抛砖引玉
-----此内容被Gorgon Meducer于2007-06-10,23:37:37编辑过

erxun 发表于 2007-6-11 08:05:19

好东西.老板下任务,开发一个监测装置,需要显示东西很多,看来,哈哈~~~~~顶啊

ibq3100 发表于 2008-3-2 01:05:41

有谁应用过 Gorgon Meducer 傻孩子 编写的菜单函数,要占用多少的RAM???
512够吗??

lofeng 发表于 2008-3-2 10:38:05

好东西 多谢

Gorgon_Meducer 发表于 2008-3-2 15:27:36

如果你的RAM不够大,建议不要使用结构体构建菜单,使用switch case是明智之举。
如果坚持使用结构体作为菜单项,那么ICC里面可以把菜单数组放到flash中,同时,将字符串也放到flash中(通过在Compiler Option->Target中的String in FLASH only)。这样可以节省不少RAM空间。

ba_wang_mao 发表于 2008-5-17 10:41:25

傻孩子,
 (1)、如果操作菜单时只是弹出一个小窗口,背景画面也照常运行和显示,菜单程序该怎么设计呀!

Gorgon_Meducer 发表于 2008-5-17 10:48:16

这样的程序实际上要求你的显示系统必须支持双缓冲。
    方法是这样的,首先建立一个缓冲区,然后将菜单背后的内容按照菜
单覆盖的顺序,逆序绘制在缓冲区中(最上层的最后绘制)。最后将缓冲
区刷新到LCD上。如果觉得刷新工作量太大,可以使用“脏矩阵”技术。

ba_wang_mao 发表于 2008-5-17 16:30:58

谢谢傻孩子。

ba_wang_mao 发表于 2008-5-17 16:38:27

傻孩子,
 我看了AVR网站上的所有菜单程序,菜单操作部分全部是死循环:即死等按键直到退出菜单。
 也就是说,进入菜单操作过程时,主程序中的其它程序就无法执行了(因为在原地死等)。


 如何设计一个如下的菜单操作程序
while (1)
{
      子程序1;
      按键扫描程序;
      菜单操作程序;
   子程序2; 
}
即每次都顺序执行,当扫描到按键后,即执行《菜单操作程序》

kangkang 发表于 2009-11-16 19:25:07

学习了

hpdell 发表于 2010-3-27 15:50:36

不错!!!!!!!!!

hongyancl 发表于 2010-3-27 17:14:54

dddddddddddddddddddddddd

keilc 发表于 2011-3-8 13:48:40

mark!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

522yt 发表于 2011-3-20 18:16:23

顶。正在用。

chenguanghua 发表于 2011-11-6 16:02:25

学习了

souching 发表于 2011-11-7 11:54:29

mark

ljt80158015 发表于 2014-1-4 13:07:19

sub 中的按键如何处理?

hamipeter 发表于 2014-1-7 17:54:57

好帖,顶一下

天行者 发表于 2014-6-17 12:48:18

好贴,顶一下。

天行者 发表于 2014-6-17 16:07:29

收藏了,

hfjydq 发表于 2014-6-20 13:15:21

傻孩子源码在哪
页: [1]
查看完整版本: 傻孩子**电子菜单移植AVRGCC PROGMEM