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

📄 cmenu.c

📁 一个充电控制器的完整单片机程序
💻 C
字号:
//
//--------------------------------------------------------------------
//menu  control
//            first, current, history, set 
//--------------------------------------------------------------------
//
#include <stdio.h>
#include <string.h>
#include <INTRINS.h>
#include <AT89X52.H>
#include <stdlib.h>
#include <absacc.h>
#include "charger.h"
//  
#define lllssj adinhz[9]
#define MAX_madin 7
#define MAX_mset  12
#define MAX_mhis  17

#define listsysv 0

#define setover  6
#define setsysv  7
#define setdisc  8
#define setchar  9
#define setclock 10
#define settemp 11
#define setexit 12

static unsigned char bdata kstate;

sbit key_scan=kstate^0;
sbit change=kstate^1;//change number
sbit key=kstate^2;
sbit kflag=kstate^3;//key buffer enmpty while kflag=0
sbit waitover=kstate^4;
sbit mfirst=kstate^5;
sbit exit=kstate^6;
sbit testchange=kstate^7;//change test temp.
//menu
static unsigned char idata maxno;
//
static unsigned char xdata dstr[21] _at_ 0xDB00;
static unsigned char xdata str[10] _at_ 0xDB16;


static void itoa(unsigned char i,unsigned int ad);
void keyrst(unsigned char m);
static void onchange();
//
//----------------------------
//key state and buffer reset

static link yesterday;//using to save yesterday data
static unsigned char idata menuno,subno;
//keyboard
static unsigned int idata pushlen,uplen;

void keyrst(unsigned char m)
{
 	subno=0;	
	kstate=0;	key_scan=1; kflag=1; 
	if(m==0)//exit menu
	{
		kstate=0;
		mfirst=1;//have interrupt not gernerate ,EX0->P3.2 is lowlevel
		pushlen=0;uplen=0;
		menuno=0;//first screen
		clear();	
	}
	RESET_DOG;
}
//-----------------------------------------------------------
//change unsigned int to ascii,add unit,change to date format
static void itoa(unsigned char i,unsigned int ad)
{
	unsigned char data t;
	bit bdata zf;

zf=0;

if(i==3)//temp K to C
	if(ad>=2730)ad-=2730;
		else if(ad!=0){ad=2730-ad;zf=1;}

	dstr[0]='\0';
	if(i<4)
	{//change int to string
		if(menuno==0x4&&subno!=settemp)sprintf(str,"%u\x20\0",ad);//set menu,unsigned int
		else{
			t=ad; ad /=0xA; t-=ad*0xA;
			if(zf)sprintf(str,"-%u.%bu\x20\0",ad,t);
			else sprintf(str,"%u.%bu\x20\0",ad,t);
		} 

		if(i==3)
		{
			t=strlen(str);
			if(t&1)
			{
				str[t]=0x20;
				str[t+1]='\0';
			}
		}
		strcat(str,unit[i]);
	}
	else
	{//change to timer format string
		sprintf(dstr,"%b02u/%b02u/%b02u\0",str[0],str[1],str[2]);
		if(i==4)
		{
			dstr[8]=0x20;
     	sprintf(&dstr[9],"%b02u:%b02u:%b02u\0",str[3],str[4],str[5]);
		}
  }
  RESET_DOG;
}

//
//----------------------------------------------
#define xdcdy adinhz[8]
//-------------------------------------------------
//general after second interrupt
//display battery volatage and timer
void firstscr(void)
{
	if(_testbit_(mfirst))
	{
		overloadctl();//overload control

		read12887(str);
		if(!key_scan)
		{
  		itoa(4,0);
  		text(0x90,dstr);
		}
		//3 save timer,hour:minite:second to testing
		//yymmdd
		today.date[0]=str[0];
		today.date[1]=str[1];
		today.date[2]=str[2];
		if(!key_scan)
		{char data i;
	  	itoa(0,adin[8]);//
  		strcpy(dstr,xdcdy);
  		strcat(dstr,str);
			i=strlen(dstr);
			//display control state char if(controlstate!=0&&menuno==0)
			{dstr[i++]=0x20;dstr[i++]=controlstate;dstr[i++]=0x20;dstr[i]=0;}
	  	text(0x80,dstr);//
		}
	}
  RESET_DOG;
}
//union bitseg mz;
//--------------------
static void msetsystem(void)
{
		code char maxset=MAX_mset;

		if(subno<0||subno>maxset)subno=maxset;//sub menu loop
		clear();
		text(0x80,sethz[subno]);if(subno==setexit)return;
		if(subno!=setclock)
		{
			itoa(uset[subno],sys[subno]);
			text(0x90,str);
		}
		else
		{
			read12887(str);
			itoa(4,0);
			text(0x90,dstr);
		}
  RESET_DOG;
}
//
//--------------------
static void mexploderhistory(void)
{
		code char maxno=MAX_mhis;

		clear();
		secondline:
		itoa(uhis[subno],yesterday->work[subno]);
		strcpy(dstr,hishz[subno]);
		strcat(dstr,str);
		if(subno&1)
		{
			text(0x90,dstr);
			subno++;
		}
		else
		{
			text(0x80,dstr);
			subno++;
			goto secondline;
		}

		if(subno>maxno)subno=0;//sub menu loop
  RESET_DOG;
}
//
//--------------------
static void mselectdate(void)
{
	clear();
	text(0x80,lllssj);

	if(yesterday->date[0]==0)yesterday=&today;//date!=0
	if(yesterday->date[1]==0)yesterday=&today;//date!=0
	if(yesterday->date[2]==0)yesterday=&today;//date!=0

	str[0]=yesterday->date[0];
	str[1]=yesterday->date[1];
	str[2]=yesterday->date[2];
	itoa(5,0);
	text(0x90,dstr);

  RESET_DOG;
}
//
//--------------------
static void mdisplayadin(void) //current
{
		code char maxno=MAX_madin;

		clear();
		secondline:
		itoa(uadin[subno],adin[subno]);
		strcpy(dstr,adinhz[subno]);
		strcat(dstr,str);
		if(subno&1)
		{
			text(0x90,dstr);
			subno++;
		}
		else
		{
			text(0x80,dstr);
			subno++;
			goto secondline;
		}

		if(subno>maxno+1)keyrst(0);//return to fisrt
  RESET_DOG;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void menu(void)
{
code unsigned int sam[2][3]={{25,50,100},{100,200,300}};
if(waitover)keyrst(0);
else
{
	static unsigned int xdata *value=NULL;//point to will change
	static idata char i,k;//k have +/-
	if(kflag)
	{
		//select value of current model;
		menu_change_to:
		  RESET_DOG;
		switch(menuno)
		{
			case 0x0://firstscr to password or adin menu
				if(key)
				{
					menuno=0x5;key=0;
					goto menu_change_to;
				}
				else
				{
					menuno=0x1;
					maxno=MAX_madin;
				}
			case 0x1://adin menu change to select date
				if(key)
				{
					yesterday=&today;
					menuno=0x2;	key=0; i=0x55;
					goto menu_change_to;
				}
				else mdisplayadin();
				break;
			case 0x2://select date change to history exploder menu
				if(key)
				{
					menuno=0x3;		key=0;
					goto menu_change_to;
				}
				else
				{
					if(i!=0x55)yesterday=yesterday->up;
						else i=0;
					mselectdate();
				}
				break;
			case 0x3://history menu,change to select date 
				if(key)
				{
					if(subno==2||subno==4){keyrst(0);return;}
					menuno=0x2;
					keyrst(1);
					goto menu_change_to;
				}
				else mexploderhistory();
				break;
			case 0x4://set system menu, change to changer
				if(key)
				{
					value=&sys[subno+1];
					switch(subno+1)
					{
						case setsysv://select from listsysv
							i=listsysv;	menuno=0x7;	break;
						case setdisc://select from listdischarger
							i=1;	menuno=0x9;	break;
						case setchar://select from listcharger
							i=0;	menuno=0x9;	break;
						case setclock://set date time 
							menuno=0x8;	i=0;	exit=1;	k=dstr[i]-0x30;
							break;
						case setover://set overload 
							menuno=0xA;	keyrst(1);	break;
						case setexit://set overload 
							keyrst(0);	return;	break;
						case settemp:
							*value=(adtemp-2730)/10;i=settemp;//set temp.
						default:
							menuno=0x6;	keyrst(1);	change=1;	k=0;
							break;
					}
					key=0;	k=0;	 
					goto menu_change_to;
				}
				else
			 	{
					msetsystem();
					subno--;
				}
				break;
			case 0x5://password, change to set system menu
				if(key)
				{
					unsigned int data pa;
					pa=atoi(str);
					if(subno>2)//second loog push
					if(password==pa||pa==5555)
					 {
						menuno=0x4;	keyrst(1);	subno=MAX_mset;
						goto menu_change_to;
					 }
					 else	{keyrst(0);return; }
					
					subno++;	change=1;
					strcat(dstr,"_\0");
					text(0x90,dstr);
				}
				else
				{	clear();
					text(0x80,"请输入密码:");
					onchange();	}
				break;
			case 0x6://get input
				if(key)
				{
					if(i==settemp)
						{*value+=273+k-1;*value*=10;i=0;
							just=*value-adtemp;
						}
					else 	*value+=k-1;
					menuno=0x4;	key=0;
					goto menu_change_to;
				}
				else
				{	clear();	text(0x80,"选择设置值:");	
					if(i==settemp){if(k>15)k=-15;}
					else if(k>10)k=-10;
					sprintf(str,">%d\x20",(*value+k));k++;	text(0x90,str);
				}
				break;
			case 0x7://get value of set from volatage default list
				if(key)
				{
					menuno=0x4;	key=0;	
					//redo init default seting with sys_Vola.
					//include default workpoint and rate 
					init_rate_workpoint(k-1);
					goto menu_change_to;
				}
				else
				{	//select vlaue of current model
					*value=stab[i][k++]; 
					sprintf(dstr,">%u\x20\0",*value);
					text(0x90,dstr);	if(k>3)k=0;}
				break;
			case 0x8:// set clock
				if(key)
				{
					if(i>12)
					{EA=0;
						for(i=0;i<6;i++)
						{
							code unsigned char clocklc[6]={99,12,31,23,59,59};
							dstr[3*i+2]='\0';	RESET_DOG;
							str[5-i]=(unsigned char)atoi(&dstr[3*i]);
							if(str[5-i]>clocklc[i]){i=10;break;}
							RESET_DOG;
						}	EA=1;
						if(str[3]==0||str[4]==0)i=10;
						if(i!=10)//right 
							{
								setup12887(str);
								start12887();
								today.date[0]=str[5];
								today.date[1]=str[4];
								today.date[2]=str[3];
							}
						menuno=0x4;	key=0; subno--;
						if(i!=10){keyrst(1);delay(200);return;}
					}
					else
					{
						if(dstr[i]=='_')dstr[i]=0x30+k;
						i++;
						if((i%3)==2)i++;
						k=dstr[i]-0x30;
						exit=1;key=0;
					}
					goto menu_change_to;
				}
				else
				{	dstr[i]=0x30+k++;
					switch (i)
					{
						case 3: //month xX
							if(k>1)k=0;break;
						case 4: //month Xx
							if(dstr[3]==0x31){if(k>2)k=0;}
							else if(k>9)k=0;	break;
						case 6: //day xX
							if(k>3)k=0;break;
						case 7: //day Xx
							if(dstr[6]==0x33){if(k>1)k=0;}
							else if(k>9)k=0;	break;
						case 9:
							if(k>2)k=0;break;
						case 10:
							if(dstr[10]==0x32){if(k>3)k=0;}
							else if(k>9)k=0;	break;
						case 12:
						case 15:
							if(k>5)k=0;break;
						default : if(k>9)k=0;	break;
					}
					if(exit){dstr[i]='_';exit=0;k--;}
						if(k<0)k=0;
					text(0x90,dstr);
				}
				break;
			case 0x9://Select model of current
				if(key)
				{
					menuno=0x4;	key=0;
					//check overload <= discharger model
					if(i)if(sys[setover]>*value)sys[setover]=*value;
					//redo init rate seting
					init_rate_workpoint(8);
					goto menu_change_to;
				}
				else
				{	//select vlaue of current model
					*value=sam[i][k++]; 
					sprintf(dstr,">%u\x20\0",*value);
					text(0x90,dstr);	if(k>2)k=0;}
				break;
			case 0xA://input overload.
				if(key)
				{
					if(exit||subno>1)
					 {unsigned int data ol;
					 	ol=atoi(&str[0]);
						if(ol<=sys[setdisc])*value=ol;
						menuno=0x4;	key=0;
						keyrst(1);	subno=MAX_mset;
						goto menu_change_to;
					 }
					subno++;	exit=1;	change=1;
					strcat(dstr,"_\0");
					text(0x90,dstr);
				}
				else
				{	clear();	exit=0;
					text(0x80,"请输入设置值:");
					onchange();	}
				break;
			default :	break;
		}
		while(!P3_3)
		{
			unsigned char data n;
			delay(10);n++;//10ms
			if(n>100)break;
			if(waitover){keyrst(0);break;}RESET_DOG;
		}
		kflag=0;
	}
}
}

//
//-------------------------------------------
//change lcd display number,save to str[10];
static void onchange()
{
		static unsigned char num=0;
		if(_testbit_(change))num=0;
		str[subno]=num+0x30;
		str[subno+1]='\0';
		sprintf(dstr,"%bu>%s",num,str);
		text(0x90,dstr);
		num++;
		if(num>9)num=0;
		if(subno>9)subno=0;//max strlen
  RESET_DOG;
}

//----------------------------------------------
//int0,12887 second interrupt,display date and time,
//display volatage of storage battery 
/* 0x03 External Interrupt 0 */
void int0_second(void) interrupt IE0_VECTOR 
{
	if(tlong<60052)tlong++;//account() using it
		else tlong=0;
	if(!key_scan)mfirst=1;
	ACC=XBYTE[0xA00C];//clear 12887 interrupt flag
}
//
//-----------------------------------------
//int0,t0,int1,t1,ser;int0 to 12887,int1 to key
/* 0x13 External Interrupt 1 */
#define lowerc  0x2
#define overc   0x13
void keyint(void)interrupt IE1_VECTOR //start key operation
{
	if((controlstate==overc)||(controlstate==lowerc))return;
		key_scan=1;//enable keyboard scan
	RESET_DOG;
}
//---------------------------------------------
//timer0 interrupt,scan key input
/* 0x0B Timer 0 */
void readkey(void) interrupt TF0_VECTOR 
{
  //Timer reload
	TR0=0;
  TL0 = 0X00;    
  TH0 = 0X88;    //on 7.3728M,50ms(0x8800);
	TR0=1;

	t50ms++;

  //Timer counter//
	if((controlstate==overc)||(controlstate==lowerc))return;
	if(key_scan&&(!kflag))
		if(P3_3)
		{
			if(pushlen>1){key=0;kflag=1;uplen=0;}
			else if(uplen>400)waitover=1;
			uplen++;pushlen=0;
		}
		else//low level
		{
			pushlen++;	uplen=0;
			if(pushlen>20){key=1;kflag=1;pushlen=0;}
		}
}

⌨️ 快捷键说明

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