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

📄 z12864.c

📁 51单片机Proteus仿真多级菜单实现
💻 C
字号:


//[字符图象输出文件=hzk.c]
//[字体名称=宋体]
//[字体大小=16]
//[字节方向=垂直]
//[字位顺序=从低到高]

#include <reg51.h>
#include <math.h>
#include <hzk.c>


#define UP 0xfe
#define DOWN 0xfd
#define LEFT 0xfb
#define RIGHT 0xf7
#define ESC 0xdf
#define ENTER 0xef

#define BLACK   1
#define WHITE	0


#define MENU_BACK_COLOR  WHITE   //定义菜单系统当中的背景色 
#define MENU_FONT_COLOR  BLACK   //定义菜单系统当中的文字色 
#define MENU_SELE_COLOR   BLACK//定义菜单系统当中被选择的菜单项背景色 
#define MENU_SELF_COLOR    WHITE //定义菜单系统当中被选择的菜单项文字色 


#define Y_WIDTH_MENU 16
#define Dis_Menu_Num  4


#define	 Dis_X_MAX   127
#define  Dis_Y_MAX	  64
#define Key  P1

 unsigned char First_Index_old=0xff ;
 unsigned char y_Index_old=0xff	 ;


code unsigned char Menu_String01[]={"绘点"}; 
code unsigned char Menu_String02[]={"绘直线"}; 
code unsigned char Menu_String03[]={"绘矩形"}; 
code unsigned char Menu_String04[]={"字符显示"}; 
code unsigned char Menu_String05[]={"帮助"}; 

code unsigned char Menu_String06[]={"单个西文字符"};
code unsigned char Menu_String07[]={"西文字符串"}; 
code unsigned char Menu_String08[]={"中文字符"}; 
code unsigned char Menu_String09[]={"返回"}; 


 code unsigned char Menu_List01_Config[]={5}; 
code unsigned char Menu_List02_Config[]={4}; 



code unsigned char *Menu_List01[]=// 
{
(unsigned char *)Menu_List01_Config,
(unsigned char *)Menu_String01, 
(unsigned char *)Menu_String02,
(unsigned char *)Menu_String03, 
(unsigned char *)Menu_String04,
(unsigned char *)Menu_String05
}; 
code unsigned char *Menu_List02[]=// 
{
(unsigned char *)Menu_List02_Config,
(unsigned char *)Menu_String06, 
(unsigned char *)Menu_String07,
(unsigned char *)Menu_String08, 
(unsigned char *)Menu_String09
}; 


unsigned char data Lcd_CurrentX,Lcd_CurrentY,Lcd_Mask;
unsigned char code LeftMask[]={0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80};
unsigned char code RightMask[]={0xff,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f};
unsigned char code Mask1[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char code Mask2[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

//前两位由5个口线决定,见SMG12864说明书 基本操作时序
//Epin—p2.7 R/W—p2.1 cs1—p2.3 cs2—p2.2 RS—p2.0
unsigned char xdata Lcd_Chip1_Cmd_W_Reg _at_ 0x8800;
unsigned char xdata Lcd_Chip2_Cmd_W_Reg _at_ 0x8400;
unsigned char xdata Lcd_Chip1_Data_W_Reg _at_ 0x8900;
unsigned char xdata Lcd_Chip2_Data_W_Reg _at_ 0x8500;
unsigned char xdata Lcd_Chip1_Data_R_Reg _at_ 0x8b00;
unsigned char xdata Lcd_Chip2_Data_R_Reg _at_ 0x8700;
unsigned char xdata Lcd_Chip1_Sta_R_Reg _at_ 0x8a00;
unsigned char xdata Lcd_Chip2_Sta_R_Reg _at_ 0x8600;

#define LCD_CMD_COL  0x40
#define LCD_CMD_PAGE 0xB8
#define LCD_CMD_ON   0x3F
#define LCD_CMD_OFF  0x3E
#define LCD_CMD_STARTLINE 0xC0
#define LCD_LEFT 0
#define LCD_TOP  0
#define LCD_RIGHT 127
#define LCD_BOTTOM 63

//延时子程序
void delay(unsigned int t)
{  unsigned int i,j;
   for(i=0;i<t;i++)
      for(j=0;j<10;j++)
         ;
}

//片1测忙
void lcdwaitidle1(void)
{  while(((Lcd_Chip1_Sta_R_Reg)&0x80)==0x80);
}

//片2测忙
void lcdwaitidle2(void)
{  while(((Lcd_Chip2_Sta_R_Reg)&0x80)==0x80);
}

//写指令代码到片1
void lcdwc1(unsigned char cmdcode)
{  lcdwaitidle1();
   Lcd_Chip1_Cmd_W_Reg=cmdcode;
}

//写指令代码到片2
void lcdwc2(unsigned char cmdcode)
{  lcdwaitidle2();
   Lcd_Chip2_Cmd_W_Reg=cmdcode;
}

//写数据到片1
void lcdwd1(unsigned char dispdata)
{  lcdwaitidle1();
   Lcd_Chip1_Data_W_Reg=dispdata;
}

//写数据到片2
void lcdwd2(unsigned char dispdata)
{  lcdwaitidle2();
   Lcd_Chip2_Data_W_Reg=dispdata;
}

//读片1数据
unsigned char lcdrd1(void)
{  lcdwaitidle1();
   return Lcd_Chip1_Data_R_Reg;
}

//读片2数据
unsigned char lcdrd2(void)
{  lcdwaitidle2();
   return Lcd_Chip2_Data_R_Reg;
}

//写指令代码
void lcdwc(unsigned char cmdcode)
{  if((Lcd_CurrentX)<0x40)
      lcdwc1(cmdcode);
   else
      lcdwc2(cmdcode);
}

//写数据
void lcdwd(unsigned char dispdata)
{  if(Lcd_CurrentX<64)
      lcdwd1(dispdata);
   else
      lcdwd2(dispdata);
}

//内部数据地址指针定位
void lcdpos(void)
{  lcdwc(LCD_CMD_COL|(Lcd_CurrentX&0x3f));      //设置地址列指针
   lcdwc(LCD_CMD_PAGE|((Lcd_CurrentY/8)&0x7));  //设置地址页指针
}

//读数据
unsigned char lcdrd(void)
{  unsigned char i;
   lcdpos();
   if(Lcd_CurrentX<64)
   {  i=lcdrd1();
      i=lcdrd1();        //读两次
   }
   else
   {  i=lcdrd2();
      i=lcdrd2();
   }
   lcdpos();
   return i;
}

//当前坐标移动到下一个点
void lcdcursornext(void)
{  Lcd_CurrentX++;
   if(Lcd_CurrentX>LCD_RIGHT)
   {  Lcd_CurrentX=LCD_LEFT;
      Lcd_CurrentY+=8;
      if(Lcd_CurrentY>LCD_BOTTOM)
         Lcd_CurrentY=LCD_TOP;
   }
}

void displaybyte(unsigned char dispdata)
{  lcdpos();         //内部数据地址指针定位
   lcdwd(dispdata);  //写数据
   lcdcursornext();  //当前坐标移动到下一个点
}

//整屏显示
void lcdfill(unsigned char FillData)
{  for(Lcd_CurrentX=LCD_LEFT,Lcd_CurrentY=LCD_TOP;1;)
   {  displaybyte(FillData);
      if((Lcd_CurrentX==LCD_LEFT)&&(Lcd_CurrentY==LCD_TOP))
         break;
   }
}
/*//填充矩形
void rectfill(signed char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char FillData)
{  for(Lcd_CurrentX=x0,Lcd_CurrentY=y0;1;)
   {  displaybyte( FillData);
      if((Lcd_CurrentX==x1)&&(Lcd_CurrentY==y1))
         break;
   }
}

  */























#include <display.c>
#include <point.c>


 
//=====================================================================//
//函数:void UpDate_Menu(unsigned char First_Index,unsigned char Menu_Index, unsigned char ** Menu_List) 
//描述:刷新整屏菜单显示函数 
//参数:First_Index  当面显示页的第一条菜单号 
//   Menu_Index   当前处于选用的菜单项 
//    Menu_List    菜单资源链表指针 
//返回:无 
//注意:无         
//=====================================================================//
void UpDate_Menu(unsigned char First_Index,unsigned char Menu_Index,unsigned char** Menu_List) 
{ 
 unsigned int y_width,y_Index; 
 unsigned char List_Num,i,x; 
  List_Num = (unsigned int)**Menu_List; 
 y_width = Y_WIDTH_MENU; 
  y_Index = 0; 
  while(First_Index>List_Num) First_Index = List_Num; 
  if(List_Num>Dis_Menu_Num) List_Num = Dis_Menu_Num; 
  if(First_Index_old!=First_Index)             
 { 
  lcdfill(WHITE);         //清屏 
   if(y_Index_old==0xff)              
   { 
   rectfill(0,0,Dis_X_MAX, y_width-1,MENU_SELE_COLOR); 
   i=First_Index+1; 
   put_str_xy(x,y_Index,(unsigned char *)Menu_List[i++],MENU_FONT_COLOR);
   y_Index = y_Index+Y_WIDTH_MENU; 
   for(;i<List_Num+1;i++) 
   { 
   put_str_xy(x,y_Index,(unsigned char *)Menu_List[i],MENU_SELF_COLOR) ;
   y_Index = y_Index+Y_WIDTH_MENU; 
   } 						  
   } 
    else      
   { 
   y_Index_old = Menu_Index-First_Index; 
   rectfill(0,y_Index_old*Y_WIDTH_MENU,Dis_X_MAX, 
      y_Index_old*Y_WIDTH_MENU+Y_WIDTH_MENU-1,WHITE); 
   i=First_Index+1; 
   while(List_Num) 
   { 
    if((i-1)==Menu_Index) put_str_xy(x,y_Index,(unsigned char *)Menu_List[i],MENU_FONT_COLOR);       
   else put_str_xy(x,y_Index,(unsigned char *)Menu_List[i],MENU_SELF_COLOR);
    y_Index = y_Index+Y_WIDTH_MENU; 
    i++; 
	     List_Num--; 
   } 
   } 
   First_Index_old = First_Index;   
 } 
 else              
 { 
   y_Index = y_Index_old-First_Index_old; 
   y_Index = y_Index*Y_WIDTH_MENU; 
   
   rectfill(0,y_Index,Dis_X_MAX, y_Index+Y_WIDTH_MENU-1,MENU_BACK_COLOR); 
   put_str_xy(x,y_Index,(unsigned char *)Menu_List[y_Index_old+1],MENU_SELF_COLOR); 
    y_Index = Menu_Index-First_Index; 
   y_Index = y_Index*Y_WIDTH_MENU; 
	    rectfill(0, y_Index,Dis_X_MAX, y_Index+Y_WIDTH_MENU-1,MENU_SELE_COLOR); 
   put_str_xy(x,y_Index,(unsigned char *)Menu_List[Menu_Index+1],MENU_FONT_COLOR); 
 } 

  y_Index_old = Menu_Index; 
} 


//=====================================================================// 
void Redraw_Menu(unsigned char First_Index,unsigned char Menu_Index,unsigned char** Menu_List) 
{ 
// unsigned char *Menu_Config; 
 //First_Index_old=0xff; 
 UpDate_Menu(First_Index,Menu_Index,Menu_List); 
} 
//=====================================================================// 


//初始化
void lcdreset()
{  lcdwc1(LCD_CMD_ON);
   lcdwc2(LCD_CMD_ON);               //开显示
   lcdwc1(LCD_CMD_STARTLINE);
   lcdwc2(LCD_CMD_STARTLINE); //设置显示初始行
}







//初始化菜单
void Init_Menu (unsigned char* Menu_List)
{
    
  UpDate_Menu(0,0,Menu_List);

}

//=====================================================================// 
//函数:unsigned char GetMLNum(unsigned char ** Menu_List) 
//描述:获取菜单资源的菜单项个数函数 
//参数: Menu_List    菜单资源链表指针 
//返回:菜单项个数 
//注意:无         
//=====================================================================// 

unsigned char GetMLNum(unsigned char **Menu_List) 
{ 
 unsigned char uiTemp; 
  uiTemp = (unsigned char)**Menu_List; 
 return uiTemp-1; 
} 

//=====================================================================// 
//函数:unsigned char GetMLiNum_Page(unsigned char ** Menu_List) 
//描述:获取菜单资源在一屏可以显示的菜单项个数函数 
//参数: Menu_List    菜单资源链表指针 
//返回:菜单项个数 
//注意:无         
//=====================================================	//
unsigned char GetMLiNum_Page(unsigned char** Menu_List) 
{ 
 unsigned char uiTemp; 
 unsigned char *Menu_Config; 
  Menu_Config = (unsigned char *)(Menu_List[0]); 
  uiTemp = *(Menu_Config+3); 
  uiTemp = (Dis_Y_MAX+1)/uiTemp;      // 
 return uiTemp; 
} 


void  Show_DotTest()
{
 unsigned char i;
 lcdfill(WHITE);
 for(i=0;i<100;i++)
 {
  pointxy(i*3,i*i,1);
 }
 }
 
 void Show_LineTest()
 {

   unsigned char uikey,key_flag;
   lcdfill(WHITE);
   for(i=1;i<10;i++)
   {
    linexy(0,0,100,11*i,1);
   }
 }
  void  Show_RectangleTest()
  {
    unsigned char i;
	lcdfill(WHITE);
	for(i=1;i<40;i++)
	{
	  rect(i,i,i*2,i*2,1);
	}
  
  }
 /* void Show_HelpTest(); 
  {
    put_str_xy(0,0,)
  }
  */


main()
 
{
 unsigned char uiKey=0; 
 unsigned char Item_Num,Update_Flag,Enter_Flag=0; 
 unsigned char PageItem_Num; 
 unsigned char First_Index=0,Active_Index=0,Temp_Index=0; 
   
  //  Key_Initial();           //键盘扫描初始化(端口) 
  //  LCD_Init();            //初始化LCD 
  Item_Num = GetMLNum(Menu_List01);      //获取要显示的菜单的菜单项个数 
  PageItem_Num = GetMLiNum_Page((unsigned char **)Menu_List01);//获取显示的菜单的页数 
  Init_Menu((unsigned char**)Menu_List01); 
 while(1) 
 { 
  uiKey = Key;     //获取键值 
  if(uiKey)       //如有键按下则响应 
   { 
   switch(uiKey)     //判断键值进行分支控制界面 
   { 
    case ENTER:    //确定键按下 
     Enter_Flag=1;   //enter flag set 
     break; 
    case DOWN:    //down  向下键按下 
     if(Active_Index<Item_Num)  
     { 
      Active_Index++; 
      if(Temp_Index<PageItem_Num-1) Temp_Index++; 
	      else if(First_Index<Item_Num) First_Index++; 
      Update_Flag = 1; 
     } 
     break; 
    case UP:    //up  向上键按下 
     if(Active_Index>0) 
     { 
      Active_Index--; 
      if(Temp_Index>0) Temp_Index--; 
      else if(First_Index>0) First_Index--; 
      Update_Flag = 1; 
     } 
     break; 
    default:break; 
   } 
   } 
  if(Update_Flag)      //Update_Flag 为1时刷新菜单 
   { 
   UpDate_Menu(First_Index,Active_Index,(unsigned char**)Menu_List01); 
   Update_Flag=0; 
   } 
  if(Enter_Flag)      //有确定键按下时,则进入相应的功能函数 
   { 
   Enter_Flag = 0; 
	   switch(Active_Index) 
   { 
    case 0:      //”绘点”菜单项 
	 Show_DotTest();
	 Redraw_Menu(First_Index,Active_Index,(unsigned char**)Menu_List01); 
     Update_Flag = 1; 
     break;  
    case 1:       //”绘直线”菜单项 
     Show_LineTest(); 
     Redraw_Menu(First_Index,Active_Index,(unsigned char**)Menu_List01); 
     Update_Flag = 1; 
     break;  
    case 2:       //”绘矩形”菜单项 
   Show_RectangleTest(); 
     Redraw_Menu(First_Index,Active_Index,(unsigned char**)Menu_List01); 
     Update_Flag = 1; 
     break; 
    case 3:       //进入二级菜单 
 //    CharTest_Menu(); 
     Redraw_Menu(First_Index,Active_Index,(unsigned char**)Menu_List01); 
     Update_Flag = 1; 
     break;  
    case 4:       //”帮助”菜单项 
    Show_HelpTest(); 
     Redraw_Menu(First_Index,Active_Index,(unsigned char**)Menu_List01); 
     Update_Flag = 1; 
     break; 
    default:break; 
   }  
   } 
       // KeyScan_Service();   //键盘扫描的服务程序,最好在1KHz的定时/时基中断调用 
 } 
} 
 
 

⌨️ 快捷键说明

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