⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd多级.c

📁 这是单片机驱动液晶显示器12864和键盘的源代码
💻 C
字号:
/*
最新12864LCD与4*4键盘人机交互界面源程序 0.95版
有朋友问我要源程序,这个源程序是我最近修改过的最新版本的12864与4*4键盘的人机交互界面,我只给出关键交互界面菜单的源程序,至于12864和4*4键盘的驱动,相信大家都有了。
最新版本的使用反白表示选择行,增加了详细的注释。给需要的朋友一个参考。希望朋友们能写出更好的菜单程序。
*/
//----------------------------------------
// 12864M四行多级菜单
// 文件名称12864menu1。c
// 作者 张子墨
// 版本 0.95
// 最后更新2006/12/16
//----------------------------------------

//#include <SST89x5x4.H>
#include <at89s53.h>
#include "12864Driver.c"

#define MENULEVEL 7        //当前菜单表个数
#define OPTIONMETE 29       //当前选项个数,包括一个特别功能选项
//-------------------------------------
//
//  菜单结构定义
//
//-------------------------------------
struct Option
{
 unsigned char KeyLevel;      //菜单选项所属菜单表号
 unsigned char EnterIndex;     //选项进入索引号
 unsigned char CancelIndex;     //选项退出索引号
 unsigned char KeyWord[16];     //菜单选项文字描述数组
 unsigned char WordMete;      	//菜单选项描述文字字节数
};
//-------------------------------------
//
// 具体菜单选项定义,定义一个结构数组
// 存储在编码区,节省内存RAM
//
//-------------------------------------
struct Option code sOption[OPTIONMETE] = {
 {0,9,0,"文本功能",8},      //0
 {0,16,1,"时间功能",8},      //1
 {0,19,2,"温度功能",8},      //2
 {0,OPTIONMETE-1,3,"系统检测",8},   //3
 {0,OPTIONMETE-1,4,"修改密码",8},   //4
 {0,OPTIONMETE-1,5,"帮助说明",8},   //5
 {0,OPTIONMETE-1,6,"作者介绍",8},   //6
 {0,OPTIONMETE-1,7,"系统版本",8},   //7
 {0,OPTIONMETE-1,8,"退出系统",8},   //8

 {1,OPTIONMETE-1,0,"输入显示向导",12},  //9
 {1,OPTIONMETE-1,0,"新建显示文本",12},  //10
 {1,OPTIONMETE-1,0,"文本发送显示",12},  //11
 {1,OPTIONMETE-1,0,"删除已存文本",12},  //12
 {1,14,0,"输入法设定",10},     //13

 {2,OPTIONMETE-1,13,"输入法选择",10},  //14
 {2,OPTIONMETE-1,13,"输入法排序",10},  //15
 {3,OPTIONMETE-1,1,"设定本机时间",12},  //16
 {3,OPTIONMETE-1,1,"发送本机时间",12},  //17
 {3,OPTIONMETE-1,1,"与计算机同步时间",16}, //18

 {4,23,2,"显示当前温度",12},     //19
 {4,OPTIONMETE-1,2,"存储当前温度",12},  //20
 {4,OPTIONMETE-1,2,"显示已存温度",12},  //21
 {4,OPTIONMETE-1,2,"删除已存温度",12},  //22

 {5,25,18,"本机显示",8},      //23
 {5,OPTIONMETE-1,19,"子机显示",8},   //24
 
 {6,OPTIONMETE-1,23,"LED 显示",8},   //25
 {6,OPTIONMETE-1,23,"数码管显示",10},  //26
 {6,OPTIONMETE-1,23,"同时显示",8},   //27
 {0,0,0,"",0}        //28
};
//--------------------------------------
//
//  菜单表分类数组
//
//--------------------------------------
unsigned char code Level[MENULEVEL][3] = {
 {0,8,9},         //每层表单对应开始结束索引号以及选项数目
 {9,13,5},
 {14,15,2},
 {16,18,3},
 {19,22,4},
 {23,24,2},
 {25,27,3}
};
unsigned char FirstLineDisIndex = 0;    //屏幕第一行显示的索引号
unsigned char SelectLine = 1;      //当前选择的行
unsigned char SelectIndex = 0;      //当前选定行对应的索引号
unsigned char LastIndex = 0;      //进入功能函数前的索引号,判断具体功能使用
//----------------------------------------
//
//  刷新菜单功能函数
// 函数原形:void DIS12864M (void);
// 没有参数,没有返回值
// 调用方式:void DIS12864M (void);
//
//----------------------------------------
void DIS12864M (void)
{
 unsigned char i,LineMete = Level[sOption[SelectIndex].KeyLevel][2];  //循环量,显示行数
 SentAIns(0x30);               //进入液晶普通指令模式
 SentAIns(0x01);               //清屏
 SetALineReverse (SelectLine);           //填充所需反白
 do                  //分别显示各行菜单项
 {
  SentAIns(0x80);
  for(i=0;i<sOption[FirstLineDisIndex].WordMete;i++)
   SentAData(sOption[FirstLineDisIndex].KeyWord[i]);
  if(--LineMete == 0) break;
  SentAIns(0x90);
  for(i=0;i<sOption[FirstLineDisIndex+1].WordMete;i++)
   SentAData(sOption[FirstLineDisIndex+1].KeyWord[i]);
  if(--LineMete == 0) break;
  SentAIns(0x88);
  for(i=0;i<sOption[FirstLineDisIndex+2].WordMete;i++)
   SentAData(sOption[FirstLineDisIndex+2].KeyWord[i]);
  if(--LineMete == 0) break;
  SentAIns(0x98);
  for(i=0;i<sOption[FirstLineDisIndex+3].WordMete;i++)
   SentAData(sOption[FirstLineDisIndex+3].KeyWord[i]);
 }while(0);
}

//----------------------------------------
//
//  判断当前索引是否是表单第一项功能函数
// 函数原形:bit MenuLevelStart (void);
// 没有参数,返回Bit标志,是第一项返回1,不是返回0
// 调用方式:bit MenuLevelStart (void);
//
//----------------------------------------

bit MenuLevelStart (void)    //判断当前索引是否为当前层第一个选项
{
 unsigned char i = MENULEVEL;
 do
 {
  i--;
  if(SelectIndex == Level[i][0]) return 1;
 }while(i);
 return 0;
}
//----------------------------------------
//
//  判断当前索引是否是表单最后一项功能函数
// 函数原形:bit MenuLevelEnd (void);
// 没有参数,返回Bit标志,是最后一项返回1,不是返回0
// 调用方式:bit MenuLevelEnd (void);
//
//----------------------------------------
bit MenuLevelEnd (void)
{
 unsigned char i = MENULEVEL;
 do
 {
  i--;
  if(SelectIndex == Level[i][1]) return 1;
 }while(i);
 return 0;
}
//----------------------------------------
//
//  菜单上移一项函数
// 函数原形:void MenuUpOneOption (void);
// 没有参数,没有返回值
// 调用方式:void MenuUpOneOption (void);
//
//----------------------------------------
void MenuUpOneOption (void)
{
 if(MenuLevelStart ())         //如果当前为表单第一项
 {
  if(Level[sOption[SelectIndex].KeyLevel][2]>=4)  //并且表单中选项数目大于等于4个
  {
   FirstLineDisIndex = Level[sOption[SelectIndex].KeyLevel][1]-3; //第一行显示索引号为倒数第四项
   SelectIndex = Level[sOption[SelectIndex].KeyLevel][1];   //选择索引为表单最后一项
   SelectLine = 4;             //标记选择行为第四行
   DIS12864M ();             //刷新屏幕显示
  }
  else            //如果选项数目并不大于四个
  {
   SelectIndex = Level[sOption[SelectIndex].KeyLevel][1];   //选择索引为当前表单最后一个
   SelectLine = Level[sOption[SelectIndex].KeyLevel][2];   //显示行表单数目(最后一个) 
   DIS12864M ();             //刷新屏幕显示
  }
 }
 else        //如果当前不是开始索引
 {
  if(SelectLine==1)    //并且已经在屏幕最上边一行
  {
   FirstLineDisIndex--;  //显示索引上移
   SelectIndex--;    //选择索引自减
   SelectLine = 1;    //选择行还是第一行
   DIS12864M ();    //刷新屏幕
  }
  else       //如果不是第一行
  {
   SelectLine--;    //选择行自减
   SelectIndex--;    //选择索引自减
   DIS12864M ();    //刷新屏幕显示
  }
 }
}
//----------------------------------------
//
//  菜单下移一项函数
// 函数原形:void MenuDownOneOption (void);
// 没有参数,没有返回值
// 调用方式:void MenuDownOneOption (void);
//
//----------------------------------------
void MenuDownOneOption (void)
{
 if(MenuLevelEnd ())        //如果当前是表单最后一个索引
 {
  FirstLineDisIndex = Level[sOption[SelectIndex].KeyLevel][0]; //第一行显示索引为表单第一个选项
  SelectIndex = Level[sOption[SelectIndex].KeyLevel][0];   //选择索引为表单第一个选项索引
  SelectLine = 1;             //选择行为第一行
  DIS12864M ();             //刷新显示
 } 
 else           //如果不是最后的索引
 {
  if(SelectLine!=4)       //如果当前不是屏幕最底行
  {
   SelectIndex++;       //选择索引自加
   SelectLine++;       //选择行下移
   SetALineReverse (SelectLine);   //刷新选择行
   DIS12864M ();       //刷新显示
  }
  else          //如果是屏幕最低行
  {
   FirstLineDisIndex++;     //第一行显示下移
   SelectIndex++;       //选择索引自加
   DIS12864M();       //刷新显示
  }
 }
}
//----------------------------------------
//
//  某一项功能函数     实际应该改为实际功能函数
//
//----------------------------------------
void ShutDown (void)
{
 unsigned char code font[] = {"系统关闭"};
 unsigned char i;
 SentAIns(0x01);
 SentAIns(0x92);
 for(i=0;i<8;i++) SentAData(font[i]);
}
void MenuCancelOption(void);
void NoThisFunction (void)
{
 unsigned char code Font[] = {"没有这个功能"};
 unsigned int i,j;
 SentAIns(0x01);
 SentAIns(0x91);
 for(i=0;i<12;i++) SentAData(Font[i]);
 i = 65535;
 j = 10;
 do
 {
  do
  {
   i--;  
  }while(i);
  j--;
 }while(j);
 MenuCancelOption();
}
void TemperatureShow(void)
{
 unsigned char code Font[] = {"测试温度:"};
 unsigned int i,j;
 TempConvert ();
 SentAIns(0x01);
 SentAIns(0x90);
 for(i=0;i<10;i++)  SentAData(Font[i]);
 for(i=0;i<6;i++) SentAData(TempFont[i]);
 i = 65535;
 j = 10;
 do
 {
  do
  {
   i--;  
  }while(i);
  j--;
 }while(j);
 MenuCancelOption();
}
//----------------------------------------
//
//  具体功能散转函数
// 函数原形:void FunctionAction
// 没有参数,没有返回值
// 调用方式:void FunctionAction (void);
//
//----------------------------------------
void FunctionAction (void)
{
 switch (LastIndex)            //根据进入前的索引判断具体函数
 {
  case 8: ShutDown();    break;
  case 5: TemperatureShow();  break;
  default: NoThisFunction(); break;      //如果没有具体操作,显示没有这个功能
 }
}
//----------------------------------------
//
//  进入某项功能函数
// 函数原形:void MenuEnterOption (void);
// 没有参数,没有返回值
// 调用方式:void MenuEnterOption (void);
//
//----------------------------------------
void MenuEnterOption (void)
{
 LastIndex = SelectIndex;           //标记进入前的索引号(以便判断具体功能)
 SelectIndex = sOption[SelectIndex].EnterIndex;      //更新选择索引为之前索引号对应进入索引
 if(SelectIndex != OPTIONMETE-1)          //如果当前索引不是功能选择索引
 {
  FirstLineDisIndex = Level[sOption[SelectIndex].KeyLevel][0]; //第一行显示为进入表单第一项
  SelectLine = 1;             //设定第一行为选择行
  DIS12864M ();             //刷新菜单
 }
 else FunctionAction ();           //如果是功能选择项,进入功能分支判断函数
}
//----------------------------------------
//
//  菜单退出功能函数
// 函数原形:void MenuCancelOption (void);
// 没有参数,没有返回值
// 调用方式:void MenuCancelOption (void);
//
//----------------------------------------
void MenuCancelOption (void)
{
 if(SelectIndex != OPTIONMETE-1)          //如果不是从功能返回
  SelectIndex = sOption[SelectIndex].CancelIndex;     //选择索引为选项返回索引
 else                //如果是从功能返回
  SelectIndex = LastIndex;          //索引等于进入前保存索引
 if(Level[sOption[SelectIndex].KeyLevel][2]>=4)      //如果返回表单选项数目大于4个
 {
  if(SelectIndex > Level[sOption[SelectIndex].KeyLevel][1]-3)  //根据返回选项确定显示首项
  {
   FirstLineDisIndex = Level[sOption[SelectIndex].KeyLevel][1]-3;
   SelectLine = 4-(Level[sOption[SelectIndex].KeyLevel][1]-SelectIndex);
   DIS12864M ();            //刷新显示
  }
  else               //一般显示方式
  {
   FirstLineDisIndex = SelectIndex;       //第一行显示索引
   SelectLine = 1;            //选择第一行
   DIS12864M ();            //刷新菜单
  }
 }
 else                //如果返回表单选项数目不足4个
 {
  FirstLineDisIndex = Level[sOption[SelectIndex].KeyLevel][0];   //第一行显示索引为表单第一项
  SelectLine = SelectIndex - Level[sOption[SelectIndex].KeyLevel][0]+1; //选择行标志为当前选择索引对应行
  DIS12864M ();               //刷新菜单
 }
}
//----------------------------------------
//
//  菜单操作按键处理散转函数
// 函数原形:void KeyCodeAction (unsigned char KeyCode);
// 键码作为参数,没有返回值
// 调用方式:void KeyCodeAction (unsigned char KeyCode);
// 实际使用应根据自己的按键重新编写case项
//
//----------------------------------------
void KeyCodeAction (unsigned char KeyCode)
{
 switch (KeyCode)
 {
  case 'U': MenuUpOneOption();  break;   //如果是向上按键,则菜单向上,以下类似
  case 'D': MenuDownOneOption(); break;
  case 'E': MenuEnterOption();  break;
  case 'C': MenuCancelOption();  break;
  default: break;
 }
}
//----------------------------------------
//
//  菜单更新函数
// 函数原形:void MenuReflash (void);
// 没有参数,没有返回值
// 调用方式:void MenuReflash (void);
// 实际应配合自己的按键编码获取程序使用
//
//----------------------------------------
void MenuReflash (void)
{
 unsigned char Keytemp;       //保存按键编码变量
 Keytemp = GetKeyCode();       //保存按键编码
 if(Keytemp)          //如果按键编码有效
 {
  Keytemp = KeyCodeConvert (Keytemp);   //根据按键编码获取按键说明字母
  KeyCodeAction (Keytemp);     //根据按键说明字母散转
 }
}
void main (void)
{
 LcdInit ();
 Init18b20();
 DIS12864M ();
 while (1) MenuReflash ();
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -