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

📄 main.c

📁 LCD多级菜单显示程序!320*240的LCD显示器!全部调试通过的!
💻 C
字号:
#include <stdio.h>		/* standard I/O .h-file */
#include <reg51f.h>
#include <absacc.h>
#include <main.h>
#include <time.h>
#include "lcd.h"
#include "x5045.h"

unsigned char xdata	LEDState,   //LED灯、液晶背光状态变量
					ArrayLine,	//显示屏变量
					ScrLine,	//反白显示行变量
					JD_ticker,	//接地计时变量(10毫秒)
					Ticker,		//按键等用的计时变量;
					ESCTicker,  //无键按下,关闭背光计数器
					F_back;		//需不需要返回上一级的标志,
							    //0xAA----需要返回
							    //0x55----不需要返回

unsigned char code P_first[][16]=				//一级菜单
{
	" 1、一级菜单1  ",
	" 2、一级菜单2  ",
	" 3、一级菜单3  ",
	" 4、一级菜单4  ",
	" 5、一级菜单5  ",
	" 6、一级菜单6  "
};
unsigned char code second_menu_1[][16]=			//二级子菜单
{
	"1.1二级菜单1  ",
	"1.Ⅱ二级菜单2  ",
	"1.Ⅰ二级菜单3  ",
	" 1、二级菜单4  ",
	"1.5二级菜单5  ",
	" 1.6二级菜单6  ",
	" 1.7二级菜单7  ",
	" 1.8二级菜单8  "
};
unsigned char code second_menu_2[][16]=			//二级子菜单
{
	"2.1 二级菜单1 ",
	"2.2 二级菜单2 ",
	"2.3 二级菜单3 ",
	"2.4 二级菜单4 ",
	"2.5 二级菜单5 ",
	"2.6二级菜单6 ",
	"2.7二级菜单7 ",
	"2.8二级菜单8 "
};
unsigned char code second_menu_3[][16]=			//二级子菜单
{
	"3.1二级子菜单1",
	"3.2二级子菜单2",
	"3.3二级子菜单3",
	"3.4二级子菜单4",
	"3.5二级子菜单5",
	"3.6二级子菜单6",
	"3.7二级子菜单7",
	"3.8二级子菜单8"
};
unsigned char code second_menu_4[][16]=			//二级子菜单
{
	"4.1二级子菜单1",
	"4.2二级子菜单2",
	"4.3二级子菜单3",
	"4.4二级子菜单4",
	"4.5二级子菜单5",
	"4.6二级子菜单6",
	"4.7二级子菜单7",
	"4.8二级子菜单8"
};
unsigned char code second_menu_5[][16]=			//二级子菜单
{
	"5.1二级子菜单1",
	"5.2二级子菜单2",
	"5.3二级子菜单3",
	"5.4二级子菜单4",
	"5.5二级子菜单5"
};
unsigned char code second_menu_6[][16]=			//二级子菜单
{
	"              ",
	"    实验程序  ",
	"  菜单程序调试 ",
	" 				"
};
//*********************************************************
//时子程序
//********************************************************								
void Delay1(time)
unsigned int time;
{
	while(time--);
}
//***********************************************
//键盘识别子程序
//***********************************************
unsigned char GetKey(time)
unsigned char time;
{  	
	unsigned char xdata sec1,sec2,keyvalue;
	sec2=SECOND;
	if(sec1!=sec2)
	{	
		sec1=sec2;
		ESCTicker++;
		if(ESCTicker>10)				//无按键操作60秒后,关闭背光
  	  	{
			ESCTicker = 0;
			LEDState = LEDState&0x7f;
		}
	}

	LED=LEDState;

	if((F_back == 0xaa)&&(LEDState<0x80))
	{	//F_back需不需要返回主屏的标志
		return(ESC);				//60秒内无按键,且不在主屏幕,则返回主屏.
	}
	watchdog();

	keyvalue = KEY_ADDR;			//判键 #define KEY_ADDR XBYTE[0X4000] 读取按键值
	if(keyvalue!=0xff)
	{	
		if(Ticker > time)       	//time按键以后的延时时间
		{
			LEDState=LEDState|0x80;	//有按键点亮背光
			Ticker = 0;				//按键延时计数器清零
			ESCTicker=0;			//背光关闭计时器清零,返回上一级菜单
			return(keyvalue);
		}
		else
		{
			keyvalue = 0xff;
			return(keyvalue);
		}
	}
	else
	{
		Ticker = 0;
		return(0xff);
	 }
  }
//*********************************************************
//一级菜单显示
//*********************************************************
void d_first(void)      //一级菜单显示
{	unsigned char key_value;
	ArrayLine=0;
	ScrLine=0;
	while(1)
	{ 	
		ReverseLine(ScrLine);
	  	PrintStr(0,0,P_first[ArrayLine]);
	  	PrintStr(1,0,P_first[ArrayLine+1]);
		PrintStr(2,0,P_first[ArrayLine+2]);
		PrintStr(3,0,P_first[ArrayLine+3]);
		while(1)
		{	
			key_value=GetKey(12);
			if(key_value!=0xff)		//判断按键是否有键按下 
			break;
		}
		watchdog();
		switch(key_value)
		{	
				/* 当按向上键和加号键时向上移动*/
			case UP:
			case PLUS:
			    if (ArrayLine==0)				//当数组指针在第一行时,只有此时才考虑到最后一行
			    {//ArrayLine 显示屏变量
			    	if (ScrLine<=0)				//如果屏幕指针在第一行则到最后一行
					{   
						ScrLine = 3;			//ScrLine 反白显示行变量
						ArrayLine = ARRAYLINE;	//#define ARRAYLINE 2 一级菜单长度减4
					}
					else						//如果屏幕指针没有在最后一行则向上移动
						ScrLine--; 
				}
				else							//如果数组指针不在第一行
				{
					if (ScrLine<=0)				//如果屏幕指针在第一行,则要向上滚屏
						ArrayLine--;
					else
						ScrLine--;				//如果屏幕指针不在第一行,则向上移动
				}
				break;
			case DOWN:							//向下的逻辑与向上的逻辑相反
			case SUB:
			    if (ArrayLine>=ARRAYLINE)   	//#define ARRAYLINE 2
			    {
			    	if (ScrLine>=3)
					{
						ScrLine = 0;
						ArrayLine = 0;
					}
					else
						ScrLine++;
				}
				else
				{
					if (ScrLine>=3)
						ArrayLine++;
					else
						ScrLine++;
				}
				break;
			case ENTER:
				d_second(ArrayLine+ScrLine);		//进入菜单项对应的二级菜单
				break;
			case ESC:
				InitLcd();
				return;
			}
			}		
	}


//*****************************************************************
//二级子菜单 一
//*****************************************************************
void menu_2_1(void)
{	
	unsigned char temp_array,key_value,temp_scr;
	temp_array = ArrayLine;
	temp_scr = ScrLine;
    ArrayLine=0;
	ScrLine=0;
	while(1)
	{ 	ReverseLine(ScrLine);
	  	PrintStr(0,0,second_menu_1[ArrayLine]);
	  	PrintStr(1,0,second_menu_1[ArrayLine+1]);
		PrintStr(2,0,second_menu_1[ArrayLine+2]);
		PrintStr(3,0,second_menu_1[ArrayLine+3]);

		while(1)
		{	key_value=GetKey(12);
			if(key_value!=0xff)
			 break;
		 }
			switch(key_value)
			{
				/* 当按向上键和加号键时向上移动*/
				case UP:
				case PLUS:
				    if (ArrayLine==0)				//当数组指针在第一行时,只有此时才考虑到最后一行
				    {
				    	if (ScrLine==0)				//如果屏幕指针在第一行则到最后一行
						{
							ScrLine = 3;
							ArrayLine = 4;
						}
						else						//如果屏幕指针没有在最后一行则向上移动
							ScrLine--;
					}
					else							//如果数组指针不在第一行
					{
						if (ScrLine==0)				//如果屏幕指针在第一行,则要向上滚屏
							ArrayLine--;
						else
							ScrLine--;				//如果屏幕指针不在第一行,则向上移动
					}
					break;
				case DOWN:							//向下的逻辑与向上的逻辑相反
				case SUB:
				    if (ArrayLine>=4)
				    {
				    	if (ScrLine>=3)
						{
							ScrLine = 0;
							ArrayLine = 0;
						}
						else
							ScrLine++;
					}
					else
					{
						if (ScrLine>=3)
							ArrayLine++;
						else
							ScrLine++;
					}
					break;
				case ENTER:
				//menu3(ArrayLine+ScrLine);
					break;
				case ESC:
					ScrLine = temp_scr;
					ArrayLine = temp_array;
					return;
			}
			}
}

//*****************************************************************
//二级子菜单 二
//*****************************************************************
void menu_2_2(void)
{	
	unsigned char temp_array,key_value,temp_scr;
	temp_array = ArrayLine;
	temp_scr = ScrLine;
    ArrayLine=0;
	ScrLine=0;
	InitLcd();
	while(1)
	{ 	ReverseLine(ScrLine);
	  	PrintStr(0,0,second_menu_2[ArrayLine]);
	  	PrintStr(1,0,second_menu_2[ArrayLine+1]);
		PrintStr(2,0,second_menu_2[ArrayLine+2]);
		PrintStr(3,0,second_menu_2[ArrayLine+3]);

		while(1)
		{	key_value=GetKey(12);
			if(key_value!=0xff)
			 break;
		 }
			switch(key_value)
			{
				/* 当按向上键和加号键时向上移动*/
				case UP:
				case PLUS:
				    if (ArrayLine==0)				//当数组指针在第一行时,只有此时才考虑到最后一行
				    {
				    	if (ScrLine==0)				//如果屏幕指针在第一行则到最后一行
						{
							ScrLine = 3;
							ArrayLine = 4;
						}
						else						//如果屏幕指针没有在最后一行则向上移动
							ScrLine--;
					}
					else							//如果数组指针不在第一行
					{
						if (ScrLine==0)				//如果屏幕指针在第一行,则要向上滚屏
							ArrayLine--;
						else
							ScrLine--;				//如果屏幕指针不在第一行,则向上移动
					}
					break;
				case DOWN:							//向下的逻辑与向上的逻辑相反
				case SUB:
				    if (ArrayLine>=4)
				    {
				    	if (ScrLine>=3)
						{
							ScrLine = 0;
							ArrayLine = 0;
						}
						else
							ScrLine++;
					}
					else
					{
						if (ScrLine>=3)
							ArrayLine++;
						else
							ScrLine++;
					}
					break;
				case ENTER:
				//menu3(ArrayLine+ScrLine);
					break;
				case ESC:
					ScrLine = temp_scr;
					ArrayLine = temp_array;
					return;
			}
			}
}

void menu_2_3(void){

}
void menu_2_4(void){

}
void menu_2_5(void){

}
void menu_2_6(void){
{	unsigned char temp_array,temp_scr,key_value;
	temp_array = ArrayLine;
	temp_scr = ScrLine;
	ArrayLine=0;
	ScrLine=0;
	InitLcd();
	watchdog();
	while(1)
	{ 	PrintStr(0,0,second_menu_6[ArrayLine]);
	  	PrintStr(1,0,second_menu_6[ArrayLine+1]);
		PrintStr(2,0,second_menu_6[ArrayLine+2]);
		PrintStr(3,0,"                ");
		while(1)
		{	key_value=GetKey(12);
			if(key_value!=0xff)
			 break;
		 }
			switch(key_value)
			{
					case ESC:
					ScrLine = temp_scr;
					ArrayLine = temp_array;
					return;
			}
		}
			
}
}
//************************************************************
//二级菜单
//************************************************************
void d_second(second_num)
unsigned char second_num;
{	
	switch(second_num)
	{	case 0:		
			menu_2_1();						
			break;
		case 1:
			menu_2_2();			
			break;	
		case 2:
			menu_2_3();			
			break;
		case 3:
			menu_2_4();			
			break;
		case 4:
			menu_2_5();		
			break;
		case 5:
			menu_2_6();		
			break;
	}
}
//*****************************************************************
//主屏显示
//*****************************************************************
void welcome(void)
{	unsigned char xdata key_value,secb,seca,temp[9];//;,bb
	struct DATE d_date;	
	struct TIME t_time;
	while(1)
	 {
 		F_back = 0x55;				//在主屏,不需要返回F_baCK=0X55标识需要返回标志
	 	key_value=GetKey(12);
		if(key_value==ENTER)		//按确认键进入主菜单
		{	
	 		F_back = 0xaa;			//标识需要返回标志
			d_first();				
		}
	 
		watchdog();
		secb=SECOND;				//每秒刷新一次时间
		if(seca!=secb)
		{
			seca=secb;	
			GetTime(&t_time);
			watchdog();
			GetDate(&d_date);
			if((d_date.year>99)||(d_date.mon>12)||(d_date.day>31)||(t_time.hour>23)||(t_time.min>59)||(t_time.sec>59))
			{
				//repair_time();
				InitLcd();
				PrintStr(1,2,"时钟出错");	//时钟出错后把年月日时分秒设为默认值后进入时钟设置界面
				Delay1(5000);
				InitLcd();
			}
			PrintStr(1,0,"  菜单程序调试  ");
			PrintStr(2,6,"    ");
			PrintStr(2,0,"    ");
			PrintStr(0,0,"    实验程序    ");
			PrintStr(3,6,"    ");
			PrintStr(3,0,"    ");

			temp[0] = d_date.year/10 + 0x30;
			temp[1] = d_date.year%10 + 0x30;
			temp[2] = '-';
			temp[3] = d_date.mon/10 + 0x30;
			temp[4] = d_date.mon%10 + 0x30;
			temp[5] = '-';
			temp[6] = d_date.day/10 + 0x30;
			temp[7] = d_date.day%10 + 0x30;
			temp[8] = 0;
			PrintStr(2,2,temp);

			temp[0] = t_time.hour/10 + 0x30;
			temp[1] = t_time.hour%10 + 0x30;
			temp[2] = ':';
			temp[3] = t_time.min/10 + 0x30;
			temp[4] = t_time.min%10 + 0x30;
			temp[5] = ':';
			temp[6] = t_time.sec/10 + 0x30;
			temp[7] = t_time.sec%10 + 0x30;
			temp[8] = 0;
			PrintStr(3,2,temp);

			}
		}
	}
//*****************************************************
//定时器0初始化10MS中断
//*****************************************************
void InitTimer0(void)
{
	unsigned char temp;
	//t0_error = 0;
	temp = TMOD;
	temp &= 0xf0;
	TMOD = temp|0x01;		//timer0 work mode 1,act as the timer ticker
	TL0 = 0x00;
	TH0 = 0xB8;		//interrupt every 10 ms,at 11.0592MHz	
///	watchdog();
}
//*********************************
//定时器0中断服务子程序
//*********************************
void timer0(void) interrupt 1 using 0
{
	ET0 =0;
	TL0 = 0x00;
	TH0 = 0xB8;		//interrupt every 10 milisecond,at 11.0592MHz	
	Ticker++;
	ET0 = 1;
}
//*************************************************************
//主程序
//*************************************************************
void main()
{
	Init12c887();
	InitTimer0();
	EA=1;
	ET0=1;
	TR0=1;
	InitLcd();
	AUXR=0x01;			//在使用MOVX指令时访问外部RAM,如果AUXR = 0X01
 			 			//则在使用MOVX时访问片内自带RAM			
	init5045();	
	LED=0X86;
	ClearGraph();
	X5045WriteStatus(0x00);	
	init5045();
	welcome();
}

⌨️ 快捷键说明

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