您的位置:首页 > 其它

在点阵液晶显示中,一种菜单循环的方法

2009-07-02 09:26 162 查看
本人刚接触这个时间不长,所以把学到的点滴记录下来,以备今后参考。

之前做过一个液晶显示的,因为做的是顺序菜单,没有分叉,所以比较简单,但是现在这个是有分叉的,而且要选择,所以感觉就有点摸不着头脑,下面先看这个菜单的一个小部分,其实总体结构也是这样的。

1

测距记录
2
告警记录
3
时钟设置
要求选中的项要反白显示,下面给出一种在次菜单中循环显示的方法:

uint8 MainMenuDisplay(uint8 MenuNum)
{
uint8 CurrentMenuNum;
uint8 PreMenuNum,i;
// uint8 MenuRow;
// uint8 MenuCol;
uint8 MaxMenuNum;
uint16 TimeoutCnt = 0; //记录超时次数
uint16 code* mmenu_ptr=(uint16 code*)main_menu[0].menu_ptr;
CurrentMenuNum = MenuNum;

Key = 0xff;
MaxMenuNum = main_menu[0].menu_num;
if(CurrentMenuNum > MaxMenuNum)
{
CurrentMenuNum = 0;
}
while((Key!=K_ENTER)&&(Key!=K_ESC))
{
if(ScreenStatus!=SCR_MAIN_MENU) //这部分是显示最初的状态,就是屏幕从上一个屏幕切换到当前屏幕
{
ScreenStatus = SCR_MAIN_MENU;
PreMenuNum = CurrentMenuNum;
LcdClearGBuff(0);
LcdGraphToGBuff((main_menu[0].start_row +PreMenuNum)*16, main_menu[0].start_col*2, 2, 16, MenuShading3Code, PAGE0); // 预置底纹
OSSemPend(SEM_LCD_WR,0);
LcdClearDDRam();
LcdClearGDRAM();
i = (main_menu[0].start_row)*16;
LcdPaintArea(i, main_menu[0].start_col*2, i+15, main_menu[0].start_col*2+1, 0);
LcdGraphOn();
for(i=0;i<MaxMenuNum;i++)
{
LcdWriteStr(1 + i, 1,mmenu_ptr , main_menu[0].menu_max_len);
mmenu_ptr += main_menu[0].menu_max_len;
}
OSSemPostBin(SEM_LCD_WR);
}
TaskCnt[OSRunningTaskID()] = 0;
if(PreMenuNum != CurrentMenuNum)//刷新光标,随着菜单号的改变,不同的选项反白显示,表示选中
{
LcdGraphToGBuff((main_menu[0].start_row +PreMenuNum)*16, main_menu[0].start_col*2, 2, 16, MenuShading3Code, PAGE0);
LcdGraphToGBuff((main_menu[0].start_row +CurrentMenuNum)*16, main_menu[0].start_col*2, 2, 16, MenuShading3Code, PAGE0);
OSSemPend(SEM_LCD_WR,0);
i = (main_menu[0].start_row +PreMenuNum)*16;
LcdPaintArea(i, main_menu[0].start_col*2, i+15, main_menu[0].start_col*2+1, 0);
i = (main_menu[0].start_row +CurrentMenuNum)*16;
LcdPaintArea(i, main_menu[0].start_col*2, i+15, main_menu[0].start_col*2+1, 0);
OSSemPostBin(SEM_LCD_WR);

PreMenuNum = CurrentMenuNum;
}

if(OSQPend(&Key, Q_KeyValue, 8) == OS_Q_TMO)
{
Key = K_NONE;
TimeoutCnt++;
if(TimeoutCnt>50) // 50*8*25ms = 10s
{
OSSemPend(SEM_LCD_WR,0);
LcdClearDDRam();
LcdGraphOff();
OSSemPostBin(SEM_LCD_WR);
Key = K_NONE;
return(0xff); // 取消
}
}
else
{
TimeoutCnt = 0;
}

switch(Key)
{
case K_DOWN:
CurrentMenuNum++;
if(CurrentMenuNum >= MaxMenuNum) CurrentMenuNum = 0;
break;
case K_UP:
CurrentMenuNum--;
if(CurrentMenuNum >=MaxMenuNum) CurrentMenuNum = MaxMenuNum-1;
break;
default:
break;
}
}
OSSemPend(SEM_LCD_WR,0);
LcdGraphOff();
LcdClearDDRamLine(3);
OSSemPostBin(SEM_LCD_WR);
if(Key == K_ESC) //取消则返回上级菜单
{
Key = K_NONE;
return(0xff); // 取消
}
Key = K_NONE;
return(CurrentMenuNum); //回车则返回当前菜单号,进入相应的下一级菜单显示

}

代码的大致结构是这样的:

。。。。

while(条件)

{

刷新内容;

刷新光标;(当菜单号改变的时候,光标永远在当前菜单号上,即当前菜单号反白显示)

检测按键;

(因为按键的不同,菜单号加减)

如果按键式回车,则函数返回当前菜单号,函数跳转到相应菜单号的子函数;

}

这个现实思路还是比较清晰的,先记下这个吧。因为接触的比较少,不知道是否还有比这个更简单吗?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: