#include <stc15.h>    	            //包含支持IAP15W4K58S4单片机的头文件
#include <intrins.h>
#include <gpio.h>					 //I/O初始化文件
#define uchar unsigned char
#define uint  unsigned int
uchar x;
uchar Y;
sbit main_road_red     =P1^0;     //主道红灯
sbit main_road_green   =P1^1;     //主道绿灯
sbit main_road_yellow  =P1^2;     //主道黄灯
sbit branch_road_red    =P1^3;    //支道红灯
sbit branch_road_green  =P1^4;    //支道绿灯
sbit branch_road_yellow =P1^5;    //支道黄灯
sbit k1=P3^4;
sbit k2=P3^5;
/*----------------500ms延时函数-------------*/	
void Delay500ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 23;
	j = 205;
	k = 120;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

/*----------------t×0.5s延时函数-------------*/				
void DelayX500ms(uint t)		 
{	
	uint k;
	for(k=0;k<t;k++) Delay500ms();
}
/*----------------主函数-------------*/
void main()
{
	uchar m;
	PX0=1;       //外部中断0为高优先级
	IT0=1;EX0=1;  //允许外部中断0，下降沿触发
	IT1=1;EX1=1;   //允许外部中断1，下降沿触发
	EA=1;         //开放总中断
	gpio();      //I/O初始化
	while(1)
	{			  
		main_road_red=1;               //主道通行55秒
 		main_road_green=0;
		main_road_yellow=1;
 		branch_road_red=0;
		branch_road_green=1;
		branch_road_yellow=1;
		DelayX500ms(110);
		for(m=0;m<6;m++)           //主道绿灯闪烁6次
		{
			main_road_green=!main_road_green;
			DelayX500ms(1);	
		}
		main_road_green=1;
		main_road_yellow=0;               //主道黄灯2秒
		DelayX500ms(4);	
		main_road_red=0;                  //支道通行25秒
 		main_road_green=1;
		main_road_yellow=1;
 		branch_road_red=1;
		branch_road_green=0;
		branch_road_yellow=1;
		DelayX500ms(50); 
		for(m=0;m<6;m++)                  //支道绿灯闪烁6次
		{
			branch_road_green=!branch_road_green;
			DelayX500ms(1);	
		}
		branch_road_green=1;               //支道黄2秒
		branch_road_yellow=0;
		DelayX500ms(4);	
	}
}	
/*---------------- 外部中断0函数，紧急车辆通行-------------*/
void Ex0_int() interrupt 0
{ 
	Y=P1;	               //保存进入中断前交通灯状态
	main_road_red=0;        //主道、支道皆为红灯，备紧急车辆通行
 	main_road_green=1;
	main_road_yellow=1;
 	branch_road_red=0;
	branch_road_green=1;
	branch_road_yellow=1;
	DelayX500ms(40);      //保持20秒
	while(P32==0);	     //等待本次中断信号结束，若需要更长的时间，保持按键为低电平
   	P1=Y;                //恢复进入中断前交通灯状态
}
/*---------------- 外部中断1函数，强行选择车道通行-------------*/
void Ex1_int() interrupt 2
{
	EA=0;
	x=P1;                      //保存进入中断前交通灯状态
	EA=1;
	if(k1==0)
	{	  
		main_road_red=1;          //主道通行
 		main_road_green=0;
		main_road_yellow=1;
 		branch_road_red=0;
		branch_road_green=1;
		branch_road_yellow=1;
	}
	if(k2==0)
	{	  
		main_road_red=0;               //支道通行
 		main_road_green=1;
		main_road_yellow=1;
 		branch_road_red=1;
		branch_road_green=0;
		branch_road_yellow=1;	
	}
	DelayX500ms(10);      //保持5秒
	while(P33==0);          //等待本次中断信号结束，若需要更长的时间，保持按键为低电平
	EA=0;
	P1=x;                   //恢复进入中断前交通灯状态
	EA=1;
}
