/*#include<REG51.H> */
#include<AT89X51.H>
#define uchar unsigned char
uchar code duanma[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
uchar code weima[4]={0x0D,0x0E,0x07,0x0B};
uchar code deng[4]={0xDE,0xDD,0xF3,0xEB};
char SN=50,WE=60;
char SN_G=50,WE_G=40,Y=10;
uchar i,k=0,count=0;
void delayms(uchar ms);
void light();
void led();
sbit K0=P3^7;
sbit K1=P3^6;
sbit K2=P3^3;
sbit K3=P3^5;
/*程序初始化*/
void init(void)
{
/*12MHz */
TMOD=0x01;
TH1=(65536-50000)/256; /*0x3C*/
TL1=(65536-50000)%256; /*0xB0*//*計50000個數,用時50ms*/
IT0=1;/*外部中斷0為邊沿觸發方式*/
ET0=1;/*允許T0中斷*/
TR0=1;/*啟動計數器*/
EA=1;/*CPU開放總中斷*/
EX0=1;/*允許外部中斷0中斷,即允許響應端口P3^2(K4)中斷*/
EX1=1;/*允許外部中斷1中斷,即允許響應端口P3^3(K2)中斷*/
}
/*延時ms毫秒*/
void delayms(uchar ms)
{
uchar i;
while(ms--)
{
for(i=0;i<200;i++)
{}
}
}
/*中斷0處理程序*/
void int0(void) interrupt 0
{
EA=0;/*CPU禁止響應一切中斷*/
P1=0xF6,P0=duanma[0];/*東西南北方向均紅燈亮,P0口輸出0*/
while(1)/*無條件循環*/
{
P2=weima[0],P0=duanma[(SN_G+Y)%10];/*南北方向數碼管顯示可通行時間的個位*/
delayms(10); /*延時*/
P2=weima[1],P0=duanma[(SN_G+Y)/10];/*南北方向數碼管顯示可通行時間的十位*/
delayms(10); /*延時*/
P2=weima[2],P0=duanma[(WE_G+Y)%10];/*東西方向數碼管顯示可通行時間的個位*/
delayms(10); /*延時*/
P2=weima[3],P0=duanma[(WE_G+Y)/10];/*東西方向數碼管顯示可通行時間的十位*/
delayms(10); /*延時*/
/*設置南北方向通行時間*/
if(K0==0) /*P3^7=0*/
{
delayms(20);/*延時,把抖動的時間拋掉*/
if(K0==0)
{
while(K0==0)/*當松開K0開關時,跳出空循環,執行后面的程序*/
{
}
SN_G++;/*南北方向綠燈時間+1*/
if(SN_G==100)
SN_G=0;/*由于使用的是兩位數碼管,當南北方向綠燈時間加到100后清零*/
}
}
/*設置東西方向通行時間*/
if(K1==0) /*P3^6=0*/
{
delayms(20);/*延時,把抖動的時間拋掉*/
if(K1==0)
{
while(K1==0)/*當松開K1開關時,跳出空循環,執行后面的程序*/
{
}
WE_G++;/*東西方向綠燈時間+1*/
if(WE_G==100)
WE_G=0;/*由于使用的是兩位數碼管,當東西方向綠燈時間加到100后清零*/
}
}
/*返回*/
if(K3==0) /*P3^5=0*/
{
delayms(20);/*延時,把抖動的時間拋掉*/
if(K3==0)
{
while(K3==0)/*當松開K3開關時,跳出空循環,執行后面的程序*/
{
}
count=0;/*清零*/
k=0;/*南北方向通車,東西方向不通車*/
SN=SN_G,WE=SN_G+Y;/*南北方向顯示時間為南北方向綠燈通行時間,東西方向顯示時間為南北方向綠燈通行時間加黃燈閃亮時間*/
light();/*調用交通燈函數*/
led(); /*調用數碼管函數*/
EA=1; /*CPU開放總中斷*/
break;/*跳出*/
}
}
}
}
/*中斷1處理程序*/
void int1(void) interrupt 2
{
P1=0xF6,P0=duanma[0];/*東西南北方向均紅燈亮,P0口輸出0*/
EA=0;/*CPU禁止響應一切中斷*/
TR0=!TR0;/*計數器停止工作*/
while(1)/*無條件循環*/
{/*數碼管掃描程序,*/
P2=weima[0];/*顯示南北方向個位*/
delayms(10);/*延時*/
P2=weima[1];/*顯示南北方向十位*/
delayms(10);/*延時*/
P2=weima[2];/*顯示東西方向個位*/
delayms(10);/*延時*/
P2=weima[3];/*顯示東西方向十位*/
delayms(10);/*延時*/
/*返回*/
if(K3==0) /*P3^5=0*/
{
delayms(20);/*延時,把抖動的時間拋掉*/
if(K3==0)
{
while(K3==0)/*當松開K3開關時,跳出空循環,執行后面的程序*/
{
}
EA=1;/*CPU開放總中斷*/
TR0=!TR0;/*啟動計數器*/
break;/*跳出*/
}
}
}
}
/*鍵盤程序*/
void key()
{
/*南北有車而東西無車*/
if(K0==0) /*K0=0*/
{
delayms(20);/*延時,把抖動的時間拋掉*/
if(K0==0)
{
while(K0==0)/*當松開K0開關時,跳出循環,執行后面的程序*/
{
light();/*調用交通燈函數*/
led(); /*調用數碼管函數*/
}
count=0;/*清零*/
k=0;/*南北方向通車,東西方向不通車*/
SN=SN_G,WE=SN_G+Y;/*南北方向顯示時間為南北方向綠燈通行時間,東西方向顯示時間為南北方向綠燈通行時間加黃燈閃亮時間*/
light();/*調用交通燈函數*/
led(); /*調用數碼管函數*/
}
}
/*南北無車而東西有車*/
if(K1==0) /*K1=0*/
{
delayms(20);/*延時,把抖動的時間拋掉*/
if(K1==0)
{
while(K1==0)/*當松開K1開關時,跳出循環,執行后面的程序*/
{
light();/*調用交通燈函數*/
led(); /*調用數碼管函數*/
}
count=0;/*清零*/
k=1;/*南北方向不通車,東西方向通車*/
SN=WE_G+Y,WE=WE_G;/*南北方向顯示時間為東西方向綠燈通行時間加黃燈閃亮時間,東西方向顯示時間為東西方向綠燈通行時間*/
light();/*調用交通燈函數*/
led(); /*調用數碼管函數*/
}
}
}
/*定時函數*/
void time1(void) interrupt 1
{
TH0=0x3c;
TL0=0xb0;/*計50000個數,用時50ms*/
count++; /*自增運算*/
if(count>=20)/*當count大于或等于20時,歷時1s,執行程序*/
{
SN--;/*自減運算*/
WE--;/*自減運算*/
count=0;/*清零*/
if(SN==0||WE==0)/*當SN=0或者WE=0時,執行程序*/
{
k++;/*自增運算*/
if(k>3)/*當k>3時,執行程序*/
k=0;/*清零*/
switch(k)/*switch 語句*/
{
case 0:SN=SN_G,WE=SN_G+Y;break;/*南北方向顯示時間為南北方向綠燈通行時間,東西方向顯示時間為南北方向綠燈通行時間加黃燈閃亮時間*/
case 1:SN=Y,WE=Y;break; /*東西南北方向顯示時間均為黃燈閃亮時間*/
case 2:SN=WE_G+Y,WE=WE_G;break;/*南北方向顯示時間為東西方向綠燈通行時間加黃燈閃亮時間,東西方向顯示時間為東西方向綠燈通行時間*/
case 3:SN=Y,WE=Y;break; /*東西南北方向顯示時間均為黃燈閃亮時間*/
}
}
}
}
/*交通燈函數*/
void light()
{
P1=deng[k];/*交通燈對應著k的值變化*/
if(P1==deng[1]&&count==0)/*當南北方向亮黃燈且count=0時,執行程序*/
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;/*延時50ms*/
P1=0xDF;/*南北方向黃燈熄滅,東西方向亮紅燈*/
}
else
if(P1==deng[3]&&count==0)/*當東西方向亮黃燈且count=0時,執行程序*/
{
TH1=(65536-300000)/256;
TL1=(65536-300000)%256;/*延時50ms*/
P1=0xFB;/*南北方向亮紅燈,東西方向黃燈熄滅*/
}
}
/*數碼管函數*/
void led()
{
P2=weima[0],P0=duanma[SN%10];/*顯示南北方向個位*/
delayms(10);/*延時*/
P2=weima[1],P0=duanma[SN/10];/*顯示南北方向十位*/
delayms(10);/*延時*/
P2=weima[2],P0=duanma[WE%10];/*顯示東西方向個位*/
delayms(10);/*延時*/
P2=weima[3],P0=duanma[WE/10];/*顯示東西方向十位*/
delayms(10); /*延時*/
}
/*主函數*/
void main(void)
{
init();/*調用程序初始化函數*/
while(1)/*無條件循環*/
{
key();/*調用鍵盤程序*/
light();/*調用交通燈函數*/
led(); /*調用數碼管函數*/
}
}
|