最近开始接触工控领域了。以前没有接触过显示屏跳转的代码,自己精简整理了一下了,可以作为一个菜单界面的显示模板使用。
1)模板介绍
^1 硬件:
[1]6个按键:向上按键、向下按键、确认按键、返回按键、+键、-键
[2]显示屏UC1701
^2 大致功能(以确认键为例):
按返回键------进入主菜单界面
主菜单界面有4条命令行
确认键按下-----提示输入密码
密码正确后按下确认键----进入基本设置的子界面
再按确认—进入终端界面
点击确认—保存数据
2) 代码解析:
[1] 列表结构体及初始化,初始化涵盖了所有主表子表的内容,
通过按键功能来进入不同的索引号,从而可以跳转置不同的界面
struct ListOption{
uint8_t ListNum; //菜单选项所属菜单表号
uint8_t EnterIndex; //选项进入索引号
uint8_t CancelIndex; //选项退出索引号
uint8_t Word[17]; //菜单选项文字描述数组
uint8_t WordNum; //菜单选项描述文字个数
};
struct ListOption sListOption[OPTIONMETE_t] = {
/* 表号,进入索引号 返回所应号 文字 文字数量*/
{0, 4,18,"基本设置 ",4}, //0 ListHeadIndex = 0
{0,16,18,"反馈设置 ",4}, //1
{0, 8,18,"高级设置 ",4}, //2
{0,60,18,"故障诊断 ",4}, //3
{1,OPTIONMETE_t-1,0," ",0}, //4 ListHeadIndex = 4
{1,OPTIONMETE_t-1,0," 请输入基本密码",7}, //5
{1,OPTIONMETE_t-1,0," ",0}, //6
{1,OPTIONMETE_t-1,0," ",0}, //7
{2,OPTIONMETE_t-1,0,"高级一 ",3}, //8 ListHeadIndex = 8
{2,OPTIONMETE_t-1,0,"高级二 ",3}, //9
{2,OPTIONMETE_t-1,0,"高级三 ",3}, //10
{2,OPTIONMETE_t-1,0,"高级四 ",3}, //11
{2,OPTIONMETE_t-1,0,"高级五 ",3}, //12
{3,16, 0,"基本一 ",3}, //13
{3,OPTIONMETE_t-1,0,"基本二 ",3}, //14
{3,OPTIONMETE_t-1,0,"基本三 ",3}, //15
{4,OPTIONMETE_t-1,13,"基本一一 ",4}, //16
{4,OPTIONMETE_t-1,13,"基本一二 ",4}, //17
};
[2]统计各表单的起始、结束地址和该表单总共有多少行数据
#define MENU_LEVEL 5 //当前菜单表个数
// 菜单表分类数组
uint8_t Level_t[MENU_LEVEL][3] = {
// 开始索引号 结束索引号 选项数目
{0,3,4},
{4,7,4},
{8,12,5},
{13,15,3},
{16,17,2},
};
[3]通过不同按键响应不同功能
void KeyAction(uint8_t Keycode)
{
switch(Keycode)
{
case Return_value: //返回
******
User_MenuCancelOption();
******
case Up_value: //向上按键
User_MenuUpOneOption();
break;
case Down_value: //向下按键
User_MenuDownOneOption();
break;
case Enter_value: //确认按键
User_MenuEnterOption();
break;
case Add_value: //+键
User_MenuAddOption();
break;
case Subtract_value: //-键
User_MenuSubtractOption();
break;
default: break;
}
}
[4]响应完对应功能后需要刷新屏幕,让屏幕更新显示
这里说明下代码里分了两种更新:
(1)菜单页面更新,也ListOption结构体中,当前命令值NowSelectIndex 的EnterIndex参数 != (OPTIONMETE_t-1)的更新
(2)终端更新(无子目录的更新),就是NowSelectIndex 的EnterIndex参数 == (OPTIONMETE_t-1)的更新
/*
* breif:菜单刷新界面显示
*
*/
void user_dis_list(void)
{
uint8_t NowList_Line_Num = 0;
uint8_t i = 0;
uint8_t temp_num[11];
if(ListHeadIndex > OPTIONMETE_t)//每个表单的第一个头索引号
{
return ;
}
//清屏幕
clear_screen();
//当前表单的项目数
NowList_Line_Num = Level_t[sListOption[ListHeadIndex].ListNum][2];
//step1:显示菜单界面/以及反选(当前选择的行)
while(( i < NowList_Line_Num)&&(i < 4))
{
if(NowSelectLine == 1+i){
//显示选中的行
display_row_16x16(1+i, 1, sListOption[ListHeadIndex+i].WordNum, sListOption[ListHeadIndex+i].Word);
}
else{
display_row_16x16(1+i, 1, 0, sListOption[ListHeadIndex+i].Word);
}
i++;
}
//step2:菜单界面中,后半段显示界面
//0~4 ,8
if((NowSelectIndex >= 0 && NowSelectIndex < 4)||(NowSelectIndex == 13)){
display_row_16x16(NowSelectLine,6,0,"进入?");
}
else if((NowSelectIndex >= 4)&&(NowSelectIndex <= 7)){
}
else if(NowSelectIndex == 9){
}
else if(NowSelectIndex == 10){
}
....
}
/*
* breif:处理终端函数的要处理的事件
*
*/
static void User_FunctionAction(void)
{
switch (LastSelectIndex) //根据进入前的索引判断具体函数
{
case 4: display_row_16x16(4,1,0," 密码错误 "); Delay_ms(200); break;
case 5: display_row_16x16(4,1,0," 密码错误 "); Delay_ms(200); break;
case 6: display_row_16x16(4,1,0," 密码错误 "); Delay_ms(200); break;
case 7: display_row_16x16(4,1,0," 密码错误 "); Delay_ms(200); break;
case 16:
display_row_16x16(NowSelectLine,5,0," 已存 "); Delay_ms(200);
display_row_16x16(NowSelectLine,5,0," "); Delay_ms(200);
display_row_16x16(NowSelectLine,5,0," 已存 ");
break;
default:
break;
}
if( NowSelectIndex == OPTIONMETE_t-1)
{
NowSelectIndex = LastSelectIndex; //显示按下确定键之前的画面
}
user_dis_list();
}
驱动代码已上传