LCD单层菜单翻滚的实现

    在很多项目中我们都需要菜单,特别是多层菜单应用比较广泛,但是写一个能够很方便移植的多层菜单非常麻烦,我们这里就先研究一下单层菜单的翻滚的实现方式。
下面就以一个例子来说明此菜单的具体实现方法:
1. 假设本菜单使用在128*64的点阵LCM上。
2. 菜单显示为3行,一行为菜单项目名称。
3. 菜单选择项反白显示。
4. 一个采用5个按键:UP,DOWN,OK,LEFT,RIGHT。及上、下、左、右和确定键。
那么菜单可能产生的效果应该有以下18种情况:
   从上面的图不难看出,8个菜单项,每次显示3项,最多有6种可能,而每一只种又有3种光标显示,所以一共就有18中显示状态。那么如果我们要通过上下按键来实现这几
种菜单的显示,我们就必须找到它们之间的规律。认真看看图,看它们究竟有什么样的规律,开动你的大脑吧!!!!!!!!

下面把它们的规律找出来:

1.横着3项菜单内容相同,只是光标位置不同,所以我们把横着相同的用页表示,一共分为6也Page = 0~5。

2.竖着6项光标相同,一共有3种可能,用Cursor = 0~2表示。

我们把每个菜单Page和Cursor已经这两个参数的和Sum表示出来,那么我们就能完全掌握它们的所有规律的了。。。。。。。。。

我们可以看出Sum相同的菜单,其光标位置是相同的,所以,我们只有控制好Cursor和Page两个变量就可以实现菜单的翻滚了。。。。。。

很多网友不太理解菜单的翻滚方式,这里
特做了两个简单的动画,一个上一直按上键,一个是一直按下键的动画,其他按键方式内同。。。。。。。。。。
 上键
 
 下键
 

有了上面的理论基础,下面的代码实现并不难:

1.定义菜单结构体:

// 菜单参数

typedef struct _MENU_PRMT
{
     uint8 Cursor;             // 光标值(当前光标位置)
     uint8 PageNo;             // 菜单页(显示开始项)
     uint8 Index;             // 菜单索引(当前选择的菜单项)
     uint8 DispNum;             // 显示项数(每页可以现在菜单项)
     uint8 MaxPage;             // 最大页数(最大有多少种显示页) 
} MENU_PRMT; 
extern MENU_PRMT MenuPrmt;
// 菜单执行
typedef struct _MENU_TABLE
{
     uint8 *MenuItem;            // 菜单项目名称
     void (*ItemHook)(void);                    // 要运行的菜单函数
} MENU_TABLE;
2.菜单项定义
MENU_TABLE        MMenu[M_MENU_NUM] =             // 管理菜单
{
       {"1.时间设定      ", App_SetClock},          // 时钟设置
        {"2.系统参数      ", App_SetSysPrmt},        // 参数设置
        {"3.教学参数      ", App_SetTeachPrmt},      // 教学参数

        {"4.下载参数      ", App_DownloadPrmt},      // 下载参数
        {"5.清除存储      ", App_ClearStorage},      // 清除存储
        {"6.校对速度      ", App_ProofSpeed},        // 速度校对
        {"7.退出管理      ", App_ExitMenu},          // 退出管理
        {"8.其他设置      ", App_Other},             // 其他设置
};
//3.初始化菜单参数

/**************************************************************************************
* FunctionName   : AppMenuPrmtInit()
* Description    : 初始化菜单参数
* EntryParameter : None
* ReturnValue    : None
**************************************************************************************/
void AppMenuPrmtInit(void)
{
    MenuPrmt.Cursor  = 0;           // 光标清零
    MenuPrmt.PageNo         = 0;    //        页清零
    MenuPrmt.Index   = 0;           //        索引清零
}

//4.菜单显示设置

/**************************************************************************************
* FunctionName   : App_MenuSet()
* Description    : 设置菜单显示
* EntryParameter : num - 页菜单显示项,page - 最多页数
* ReturnValue    : None
**************************************************************************************/
void App_MenuSet(uint8 num, uint8 page)
{
    MenuPrmt.DispNum = num;   //        页最多显示项目数
    MenuPrmt.MaxPage = page;  //        最多页数
}

//5.菜单显示

/**************************************************************************************
* FunctionName   : App_MenuDisplay()
* Description    : 显示菜单
* EntryParameter : page - 显示页,dispNum - 每一页的显示项,cursor - 光标位置
* ReturnValue    : None
**************************************************************************************/
void App_MenuDisplay(MENU_TABLE *menu, uint8 page, uint8 dispNum, uint8 cursor)
{
    uint8 i;

    for (i=0; i         
    {
        if (cursor == i)
        {
            LCMDisplayStrRvs(0, (i+1)*2, menu[page+i].MenuItem); // 反白显示菜单项
        }
        else
        {
            LCMDisplayStr(0, (i+1)*2, menu[page+i].MenuItem);         // 显示菜单项                
        }
    }
}

//6.菜单翻滚

/**************************************************************************************
* FunctionName   : App_MenuMove()
* Description    : 菜单移动
* EntryParameter : None
* ReturnValue    : 有确认返回0,否则返回1
**************************************************************************************/
uint8 App_MenuMove(uint8 key)
{
    uint8 rValue = 1;

    switch (key) 
    {
        case KV_UP:                            // 向上 
            if (MenuPrmt.Cursor != 0)         // 光标不在顶端
            {
                MenuPrmt.Cursor--;             // 光标上移
            }
            else                               // 光标在顶端
            {
                if (MenuPrmt.PageNo != 0)      // 页面没有到最小
                {
                    MenuPrmt.PageNo--;          // 向上翻
                }
                else
                {
                    MenuPrmt.Cursor = MenuPrmt.DispNum-1;          // 光标到底
                    MenuPrmt.PageNo        = MenuPrmt.MaxPage-1;   // 最后页
                }
            }
            break;

        case KV_DN:                               // 向下
                if (MenuPrmt.Cursor < MenuPrmt.DispNum-1)  // 光标没有到底,移动光标
                {
                    MenuPrmt.Cursor++;           // 光标向下移动
                }
                else                             // 光标到底
                {
                    if (MenuPrmt.PageNo < MenuPrmt.MaxPage-1)    // 页面没有到底,页面移动
                    {
                        MenuPrmt.PageNo++;       // 下翻一页
                    }
                    else                         // 页面和光标都到底,返回开始页
                    {
                        MenuPrmt.Cursor = 0;
                        MenuPrmt.PageNo = 0;
                    }
                }
                break;

        case KV_MD:                   // 确认
            MenuPrmt.Index = MenuPrmt.Cursor + MenuPrmt.PageNo;      // 计算执行项的索引
            rValue = 0;
            break;
        
        default:break;
        } 
        
        return rValue;           // 返回执行索引
}

//7.菜单实现
/**************************************************************************************
* FunctionName   : App_ManageMenu()
* Description    : 管理菜单
* EntryParameter : None
* ReturnValue    : None
**************************************************************************************/
void App_ManageMenu(void)
{
        LCMDisplayStr(0, 0, " -= 管理系统 =- ");       // 菜单标题显示
        App_MenuSet(PAGE_DISP_NUM, M_MENU_NUM-PAGE_DISP_NUM+1);     // 页显示3项,7个菜单项5页显示
        App_MenuDisplay(MMenu, MenuPrmt.PageNo, MenuPrmt.DispNum, MenuPrmt.Cursor); // 显示菜单项

        if (SysPrmt.KeyValue != KV_NO)   // 有按键
        {                                                        
                if (App_MenuMove(SysPrmt.KeyValue) == 0x00)   // 菜单移动
                {
                        LCMClearScreen(LCM_WHITE);            // 清屏
                        MMenu[MenuPrmt.Index].ItemHook();      // 执行相应项
                }

                SysPrmt.KeyValue = KEY_NO;                    // 清除按键值
        }
}

 


 

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值