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

📄 smallfunction.c

📁 一个以前开发的实际应用的交通灯控制器程序
💻 C
字号:
#include "iic.h" 
//////////////
//2007-3-26 20:01

void PrintNum(unsigned char x,unsigned char y,unsigned int dat)
{//3位数,不消隐
//2007-3-26 20:09
	unsigned char xdata i;
	while(dat>=1000)
		dat-=1000;
	i=0;
	while(dat>=100)
	{
		dat-=100;
		i++;
	}
	LcdChar(x,y,NUM_H);
	LcdAddChar(NUM_L+i);
	i=0;
	while(dat>=10)
	{
		dat-=10;
		i++;
	}
	LcdChar(x,y+1,NUM_H);
	LcdAddChar(NUM_L+i);
	LcdChar(x,y+2,NUM_H);
	LcdAddChar(NUM_L+dat);
}

void PrintNum2(unsigned char x,unsigned char y,unsigned int dat)
{//3位数,大于1000消隐
//2007-3-27 9:35
	unsigned char xdata i,k;
	LcdChar(x,y,0x20);//灭
	for(i=0;i<5;i++)
		LcdAddChar(0x20);
	if(dat>=1000)
		return;
	i=0;
	k=0;
	while(dat>=100)
	{
		dat-=100;
		i++;
	}
	if(i)
	{
		LcdChar(x,y,NUM_H);
		LcdAddChar(NUM_L+i);
		k=1;
	}
	i=0;
	while(dat>=10)
	{
		dat-=10;
		i++;
	}
	if(i||k)
	{
		LcdChar(x,y+1,NUM_H);
		LcdAddChar(NUM_L+i);
		k=1;
	}
	LcdChar(x,y+2,NUM_H);
	LcdAddChar(NUM_L+dat);	
	
}

unsigned int Get44Key(unsigned char x,unsigned char y)
{
//2007-3-27 9:35
	unsigned char kv,i,k;
	unsigned int kt;
	kt=1000;//1000为取消值
	k=10;//
	i=0;
	LcdCur(x,y);
	kv=KEY_NOKEY;
	while(1)
	{//需加入自动切换代码
		while(kv==KEY_NOKEY)
		{
			kv=GetKey();
			if(SecondFlag)
			{
				SecondCheck();
				AutoLockCnt--;
				SecondFlag=0;
				if(AutoLockCnt<SYS_AUTO_LOCK_TIME)
				{
					DeskTopFlag=1;
					PswLock=1;
					return(1000);
				}
			}
		}
		AutoLockCnt=SYS_LCD_OFF_TIME;

		switch(kv) 
		{
			case KEY_NUM0:
				k=0;
				break;
			case KEY_NUM1:
				k=1;
				break;
			case KEY_NUM2:
				k=2;
				break;
			case KEY_NUM3:
				k=3;
				break;
			case KEY_NUM4:
				k=4;
				break;
			case KEY_NUM5:
				k=5;
				break;
			case KEY_NUM6:
				k=6;
				break;
			case KEY_NUM7:
				k=7;
				break;
			case KEY_NUM8:
				k=8;
				break;
			case KEY_NUM9:
				k=9;
				break;
			case KEY_BKSPACE://退格
				k=10;
				if(i>1)
				{
					kt/=10;
					i--;
				}
				else if (i==1)
				{
					kt=NUM_CANCEL;
					i=0;
				}
				PrintNum2(x,y,kt);
				break;
			case KEY_CANCEL:
			case KEY_MENU://相当于取消
				LcdCurOff();
				return(1000);
			case KEY_ENTER:
				LcdCurOff();
				return(kt);
			default:
				k=10;
		}
		if(k==10)
			continue;//无效继续循环
		if(i>=3)
			continue;
		if(kt==NUM_CANCEL)
			kt=k;
		else
		{
			kt=kt*10;
			kt+=k;
		}
		PrintNum2(x,y,kt);
		i++;
		LcdCur(x,y+i);//光标
		k=10;
	}	
}

unsigned char Get256Key(unsigned char x,unsigned char y)
{
	unsigned int xdata t;
	t=Get44Key(x,y);
	if(t>255)//取消则返回255
		return(255);
	x=(unsigned char)(t & 0xff);
	return(x);
}

unsigned char GetBoolKey(unsigned char x,unsigned char y,unsigned char bl)
{
	unsigned char xdata i,k,ik;
	i=bl;

	k=Line[x];
	ik=k+y;
	WriteCmd(0x0f);//开下标
	if(bl)
		LcdCnString(x,y,"是");
	else
		LcdCnString(x,y,"否");
	WriteCmd(ik);//1xxx,xxxx 设定DDRAM 7位地址xxx,xxxx到地址计数器AC

	while(1)
	{	
		k=GetKey();
		if(k==KEY_NOKEY)
			continue;
		if(k==KEY_CANCEL)
		{
			WriteCmd(0x0c);//关下标
			return i;//取消
		}

		if(k==KEY_ENTER)
		{
			WriteCmd(0x0c);//关下标
			return bl;
		}
		bl=!bl;
		if(bl)
		{
			LcdCnString(x,y,"是");
			WriteCmd(ik);
		}
		else
		{
			LcdCnString(x,y,"否");
			WriteCmd(ik);
		}
	}
}

void GetPassword(unsigned char x,unsigned char y)
{
//2007-4-2 19:43
//输入:无,返回:AppBuf[0],AppBuf[1]
	unsigned char kv,i,k;
	unsigned int kt,kt1;
	kt=0;//1000为取消值
	kt1=0;
	k=10;//
	i=0;
	LcdCur(x,y);
	kv=KEY_NOKEY;
	while(1)
	{//需加入自动切换代码
		while(kv==KEY_NOKEY)
		{
			kv=GetKey();
			if(SecondFlag)
			{
				SecondCheck();
				AutoLockCnt--;
				SecondFlag=0;
				if(AutoLockCnt<SYS_AUTO_LOCK_TIME)
				{
					DeskTopFlag=1;
					PswLock=1;
					AppBuf[0]=0xff;
					AppBuf[1]=0xff;
					LcdCurOff();
					return;
				}
			}
		}
		AutoLockCnt=SYS_LCD_OFF_TIME;
			
		switch(kv) 
		{
			case KEY_NUM0:
				k=0;
				break;
			case KEY_NUM1:
				k=1;
				break;
			case KEY_NUM2:
				k=2;
				break;
			case KEY_NUM3:
				k=3;
				break;
			case KEY_NUM4:
				k=4;
				break;
			case KEY_NUM5:
				k=5;
				break;
			case KEY_NUM6:
				k=6;
				break;
			case KEY_NUM7:
				k=7;
				break;
			case KEY_NUM8:
				k=8;
				break;
			case KEY_NUM9:
				k=9;
				break;
			case KEY_CANCEL:
			case KEY_MENU://相当于取消
				LcdCurOff();
				AppBuf[0]=0xff;
				AppBuf[1]=0xff;
				return;
			case KEY_ENTER:
				AppBuf[0]=kt;
				AppBuf[1]=kt1;
				LcdCurOff();
				return;
			default:
				k=10;
		}
		if(k==10)
			continue;//无效继续循环
		if(i<2)//前两位
		{
			kt=kt*10;
			kt+=k;
		}
		else
		{
			kt1=kt1*10;
			kt1+=k;
		}
		for(k=0;k<=i;k++)
		{
			LcdChar(x,y+k,0xA1);
			LcdAddChar(0xEF);//★
		}
		i++;
		if(i>=4)//
		{
			AppBuf[0]=kt;
			AppBuf[1]=kt1;
			LcdCurOff();
			return;
		}
		LcdCur(x,y+i);//光标
		k=10;
	}
}
///////////////////////////////////////////////
void HourUpdate()
{
//
	unsigned char xdata i,j,k;
	unsigned char xdata yy,mm,dd;
	k=EPR_Read(ADDR_HOLIDAY_PERMIT);
	if(!k)//不允许节日
		pSchBaseAddr=ADDR_GENARAL;
	else
	{//是否节日
		yy=XBYTE[RTC_BASE+RegYear];
		mm=XBYTE[RTC_BASE+RegMonth];
		dd=XBYTE[RTC_BASE+RegDate];
		for(i=0;i<20;i++)
		{//检查是否假日
			j=EPR_Read(ADDR_HOLIDAY_HEAD+1);//mm
			k=EPR_Read(ADDR_HOLIDAY_HEAD+2);//dd
			if((mm==j)&&(dd==k))
			{
				k=100;//不可能的天数,标记是节日
				break;
			}
		}
		if(k==100)
			pSchBaseAddr=ADDR_HOLIDAY;
		else
			pSchBaseAddr=ADDR_GENARAL;
	}
//	printf("Sch:%d\n",pSchBaseAddr);

	k=XBYTE[RTC_BASE+RegHours];//小时
//	printf("Hour:%d\n",k);
	k>>=1;//换到时段去
	
	pPhaseGroupAddr=pSchBaseAddr+k*PHASE_GROUP_LEN;//可有12个相位组

	PhaseCnt=0;
	SecondCnt=0;
	//PhaseSwitch();
}

void PhaseSwitch()
{
	unsigned char xdata k;

	GsFlag=1;
	while(PhaseCnt<8)//在8个相位中寻找下一个相位
	{
		PhaseCnt++;
		k=EPR_Read(pPhaseGroupAddr+PhaseCnt*PHASE_LEN+CHEDAO_ADJ+2);
		if((k & 0xf0)==0x00)//车道2在高4位为0则该相位有效
			break;
	}
	if(PhaseCnt>=8)
	{
		HourUpdate();
		PhaseCnt=0;	
	}

	CheDaoBuf[2]=EPR_Read(pPhaseGroupAddr+PhaseCnt*PHASE_LEN+CHEDAO_ADJ+0);
	CheDaoBuf[1]=EPR_Read(pPhaseGroupAddr+PhaseCnt*PHASE_LEN+CHEDAO_ADJ+1);
	CheDaoBuf[0]=EPR_Read(pPhaseGroupAddr+PhaseCnt*PHASE_LEN+CHEDAO_ADJ+2);
	GreenTime=(unsigned int)EPR_Read(pPhaseGroupAddr+PhaseCnt*PHASE_LEN+GT_ADJ);
	GsTime=(unsigned int)EPR_Read(pPhaseGroupAddr+PhaseCnt*PHASE_LEN+GST_ADJ);
	if(GsTime>=GreenTime)
		GsTime=GreenTime>>=1;
	YellowTime=(unsigned int)EPR_Read(pPhaseGroupAddr+PhaseCnt*PHASE_LEN+YT_ADJ);
	RedTime=(unsigned int)EPR_Read(pPhaseGroupAddr+PhaseCnt*PHASE_LEN+RT_ADJ);
}

void SecondCheck()
{//每秒钟更新输出
//2007-3-27 10:44 每秒钟调用此函数确保正常输出
	SecondCnt+=1;
	if(MeterSta==MSTA_AUTO)//GreenWayFlag)
	{//绿色通道特殊处理
		ManChanelSta=STA_GREEN;
		CarChanelSta=STA_GREEN;
		GsFlag=1;
		SecondCnt-=1;//保持计数不变,防止溢出
	}//绿色通道开启后不必理会其它
	else if(SecondCnt<=GreenTime-GsTime)
	{
		ManChanelSta=STA_GREEN;
		CarChanelSta=STA_GREEN;
		//if(ManuelFlag)
		if(MeterSta==MSTA_MANUAL)
			SecondCnt-=1;//保持计数不变					
	}
	else if(SecondCnt<=GreenTime)
	{
		ManChanelSta=STA_GS;
		CarChanelSta=STA_GREEN;
		GsFlag=!GsFlag;
		//if(ManuelFlag)
		if(MeterSta==MSTA_MANUAL)
			SecondCnt-=1;//保持计数不变	
	}
	else if(SecondCnt<=GreenTime+GsTime)
	{
		ManChanelSta=STA_RED;
		CarChanelSta=STA_GS;
		GsFlag=!GsFlag;
		//if(ManuelFlag)
		if(MeterSta==MSTA_MANUAL)
			SecondCnt-=1;//保持计数不变	
	}
	else if(SecondCnt<=GreenTime+GsTime+YellowTime)
	{
		ManChanelSta=STA_RED;
		CarChanelSta=STA_YELLOW;
		//if(ManuelFlag)
		if(MeterSta==MSTA_MANUAL)
			SecondCnt-=1;//保持计数不变
	}
	else if(SecondCnt<=GreenTime+GsTime+YellowTime+RedTime)
	{
		ManChanelSta=STA_RED;
		CarChanelSta=STA_RED;
		//if(ManuelFlag)
		if(MeterSta==MSTA_MANUAL)
			SecondCnt-=1;//保持计数不变	
	}
	else
	{//
		SecondCnt=0;
		SwitchFlag=1;
		//don't Copy Page0 to Page1
		PhaseSwitch();
	}
	//集中输出
	IO_Output();	
}

void IO_Output()
{
	unsigned char xdata i,j,k,t,t1,t2;

	for(i=0;i<7;i++)
		OutputBuf[i]=0x00;
//0
	k=0x01;
	for(i=0;i<8;i++)
	{
		if(k & 0x31)//人行
		{
		if((k & CheDaoBuf[1])!=0)//选中的人行道
		{
			if((ManChanelSta==STA_GREEN)||(ManChanelSta==STA_GS))
			{
				if(GsFlag)//i亮绿灯
					j=0;
				else 
					j=3;//不亮
			}
			else
			{//i亮红灯
				j=2;
			}
		}
		else
		{
			j=2;//亮红灯
		}	
		}
		else//车道	
		{
		if((k & CheDaoBuf[0])!=0)//选中的车道
		{
			if((CarChanelSta==STA_GREEN)||(CarChanelSta==STA_GS))
			{
				if(GsFlag)//i亮绿灯
					j=0;
				else 
					j=3;//不亮
			}
			else if((CarChanelSta==STA_YELLOW))
			{//i亮黄灯
				j=1;
			}
			else
			{//i亮红灯
				j=2;
			}
		}
		else
		{
			j=2;//亮红灯
		}
		}
		//亮灭输出
		if(j!=3)
		{
			t=IOMap[i][j];
				t1=t & 0x0f;
			t=0x01;
			for(t2=0;t2<t1;t2++)
				t<<=1;//bit位
			t1=IOMap[i][j];
			t2= t1 >>4;//输出地址
			OutputBuf[t2]|=t;
		}
		k<<=1;
	}
//1	
	k=0x01;
	for(i=8;i<16;i++)
	{
		if(k & 0xc6)//人行
		{
		if((k & CheDaoBuf[1])!=0)//选中的人行道
		{
			if((ManChanelSta==STA_GREEN)||(ManChanelSta==STA_GS))
			{
				if(GsFlag)//i亮绿灯
					j=0;
				else 
					j=3;//不亮
			}
			else
			{//i亮红灯
				j=2;
			}
		}
		else
		{
			j=2;//亮红灯
		}	
		}
		else//车道	
		{
		if((k & CheDaoBuf[0])!=0)//选中的车道
		{
			if((CarChanelSta==STA_GREEN)||(CarChanelSta==STA_GS))
			{
				if(GsFlag)//i亮绿灯
					j=0;
				else 
					j=3;//不亮
			}
			else if((CarChanelSta==STA_YELLOW))
			{//i亮黄灯
				j=1;
			}
			else
			{//i亮红灯
				j=2;
			}
		}
		else
		{
			j=2;//亮红灯
		}
		}
		//亮灭输出
		if(j!=3)
		{
			t=IOMap[i][j];
				t1=t & 0x0f;
			t=0x01;
			for(t2=0;t2<t1;t2++)
				t<<=1;//bit位
			t1=IOMap[i][j];
			t2= t1 >>4;//输出地址
			OutputBuf[t2]|=t;
		}
		k<<=1;
	}
//2
	k=0x01;
	for(i=16;i<20;i++)
	{
		if(k & 0x08)//人行
		{
		if((k & CheDaoBuf[1])!=0)//选中的人行道
		{
			if((ManChanelSta==STA_GREEN)||(ManChanelSta==STA_GS))
			{
				if(GsFlag)//i亮绿灯
					j=0;
				else 
					j=3;//不亮
			}
			else
			{//i亮红灯
				j=2;
			}
		}
		else
		{
			j=2;//亮红灯
		}	
		}
		else//车道	
		{
		if((k & CheDaoBuf[0])!=0)//选中的车道
		{
			if((CarChanelSta==STA_GREEN)||(CarChanelSta==STA_GS))
			{
				if(GsFlag)//i亮绿灯
					j=0;
				else 
					j=3;//不亮
			}
			else if((CarChanelSta==STA_YELLOW))
			{//i亮黄灯
				j=1;
			}
			else
			{//i亮红灯
				j=2;
			}
		}
		else
		{
			j=2;//亮红灯
		}
		}
		//亮灭输出
		if(j!=3)
		{
			t=IOMap[i][j];
				t1=t & 0x0f;
			t=0x01;
			for(t2=0;t2<t1;t2++)
				t<<=1;//bit位
			t1=IOMap[i][j];
			t2= t1 >>4;//输出地址
			OutputBuf[t2]|=t;
		}
		k<<=1;
	}

	i=OutputBuf[6];
	i=i<<4;
	OutputBuf[6]|=i;
////
	OutputBuf[0]^=0xff;
	OutputBuf[1]^=0xff;
	OutputBuf[2]^=0xff;
	OutputBuf[3]^=0xff;
	OutputBuf[4]^=0xff;
	OutputBuf[5]^=0xff;
	OutputBuf[6]^=0xff;

	OUT0=OutputBuf[0];
	OUT1=OutputBuf[1];
	OUT2=OutputBuf[2];
	OUT3=OutputBuf[3];
	OUT4=OutputBuf[4];
	OUT5=OutputBuf[5];
	OUT6=OutputBuf[6];
}

void ShowDesk()
{
	unsigned char xdata i,k;
	k=XBYTE[RTC_BASE+RegMonth];
	{//月
	i=0;
	while(k>=10)
	{k-=10;i++;}
	i+='0';
	LcdChar(0,2,i);
	k+='0';
	LcdAddChar(k);
	}
	LcdCnString(0,3,"月");
	k=XBYTE[RTC_BASE+RegDate];
	{//日
	i=0;
	while(k>=10)
	{k-=10;i++;}
	i+='0';
	LcdChar(0,4,i);
	k+='0';
	LcdAddChar(k);
	}
	LcdCnString(0,5,"日");

	k=XBYTE[RTC_BASE+RegHours];
	{//小时
	i=0;
	while(k>=10)
	{k-=10;i++;}
	i+='0';
	LcdChar(1,2,i);
	k+='0';
	LcdAddChar(k);
	LcdAddChar(':');
	}
	k=XBYTE[RTC_BASE+RegMinutes];
	{//分钟
	i=0;
	while(k>=10)
	{k-=10;i++;}
	i+='0';
	LcdAddChar(i);
	k+='0';
	LcdAddChar(k);
	LcdAddChar(':');
	}

	k=XBYTE[RTC_BASE+RegSeconds];
	{//秒
	i=0;
	while(k>=10)
	{k-=10;i++;}
	i+='0';
	LcdAddChar(i);
	k+='0';
	LcdAddChar(k);
	LcdAddChar(':');
	}

	if(PswLock)
	LcdCnString(3,4,"锁");
	else
		LcdCnString(3,4,"开");

	
	if(MeterSta==MSTA_GREENWAY;)
		LcdCnString(3,1,"绿");
	else if(MeterSta==MSTA_MANUAL)
		LcdCnString(3,1,"手");
	else
		LcdCnString(3,1,"自");	
}


//////////////无效中断服务代码//////////
void EX_INT0() interrupt INT_SOURCE_EX0
{
	unsigned char t;
	t=XBYTE[RTC_BASE+CtrlRegC];
	EX0=0;
}

void timer0() interrupt INT_SOURCE_T0
{
	ET0=0;
}

void timer1() interrupt INT_SOURCE_T1
{
	ET1=0;
}

⌨️ 快捷键说明

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