//----------------東西方向綠燈時,按下1鍵后分別按2鍵和3鍵可進行綠燈時間的加和減
//----------------東西方向黃燈時,按下1鍵后分別按2鍵和3鍵可進行黃燈時間的加和減
//----------------南北方向綠燈時,按下1鍵后分別按2鍵和3鍵可進行綠燈時間的加和減
//----------------南北方向黃燈時,按下1鍵后分別按2鍵和3鍵可進行黃燈時間的加和減
//----------------按下4鍵各路口紅燈亮
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define N 35
sfr P1M1=0x91;
sfr P1M0=0x92;
sbit a=P0^5; //矩陣鍵盤第一列
sbit b=P0^6;//矩陣鍵盤第二列
sbit c=P0^7;//矩陣鍵盤第三列
sbit d=P3^6;//矩陣鍵盤第一行
sbit e=P3^7;//矩陣鍵盤第二行
uchar code table1[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
}; //共陰極數碼管0~F
uchar code table2[]={
0xfe,0xfd,0xfb,0xf7
}; //4位位選控制,低電平選通
uchar shu[]={
0,0,0,0
};//數碼管顯示數組
uchar count,t,n,flag,flag1=1; //flag1緊急按鍵標志
uint temp1,temp2,temp3,temp4,temp;
void delay(uint x);
void display();
void zhuangtai1();
void zhuangtai2();
void zhuangtai3();
void zhuangtai4();
void anjian();
//--------------延時函數-----------------//
void delay(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=110;j>0;j--);
}
//---------------數碼管顯示-------------------//
void display()
{
uchar i;
shu[0]=temp/1000;
shu[1]=temp%1000/100;
shu[2]=temp%100/10;
shu[3]=temp%10;
for(i=0;i<4;i++)
{
P1=table1[shu[i]];//P1段顯示
P0=table2[i];//P0位選打開
delay(10);
}
}
//-----------------東西方向綠燈亮,南北方向紅燈亮-------------------//
void zhuangtai1()
{
flag=1;
temp1=60;
TMOD=0x01; //定時器0工作方式1
TH0=(65536-46070)/256;
TL0=(65536-46070)%256; //定時器初值
EA=1; //開總中斷
ET0=1; //開定時器0中斷
TR0=1; //啟動定時器0
while(1)
{
if(flag1==1)
{
temp=temp1;
P2=0x9e;
P3=0xdf;
display();
if(count==20) //1秒時間到
{
count=0;
temp1--;
if(temp1==-1)
{
temp1=60;
flag=0;
break;
}
}
}
else
{
if(n==1)
{
P2=0xdb;
P3=0xdb;
}
}
anjian();
}
}
//-----------------東西方向黃燈閃爍,南北方向紅燈亮-------------------------//
void zhuangtai2()
{
flag=2;
temp2=5;
TMOD=0x01; //定時器0工作方式1
TH0=(65536-46070)/256;
TL0=(65536-46070)%256; //定時器初值
EA=1; //開總中斷
ET0=1; //開定時器0中斷
TR0=1; //啟動定時器0
while(1)
{
if(flag1==1)
{
temp=temp2;
P2=0x5d;
P3=0xdf;
display();
if(count==20) //1秒時間到
{
count=0;
temp2--;
if(temp2==-1)
{
temp2=5;
flag=0;
break;
}
}
}
else
{
if(n==1)
{
P2=0xdb;
P3=0xdb;
}
}
anjian();
}
}
//-----------------東西方向紅燈亮,南北方向綠燈亮---------------------------//
void zhuangtai3()
{
flag=3;
temp3=40;
TMOD=0x01; //定時器0工作方式1
TH0=(65536-46070)/256;
TL0=(65536-46070)%256; //定時器初值
EA=1; //開總中斷
ET0=1; //開定時器0中斷
TR0=1; //啟動定時器0
while(1)
{
if(flag1==1)
{
temp=temp3;
P2=0xf3;
P3=0xf3;
display();
if(count==20) //1秒時間到
{
count=0;
temp3--;
if(temp3==-1)
{
temp3=40;
flag=0;
break;
}
}
}
else
{
if(n==1)
{
P2=0xdb;
P3=0xdb;
}
}
anjian();
}
}
//-----------------東西方向紅燈亮,南北方向黃燈閃爍-------------------------//
void zhuangtai4()
{
flag=4;
temp4=5;
TMOD=0x01; //定時器0工作方式1
TH0=(65536-46070)/256;
TL0=(65536-46070)%256; //定時器初值
EA=1; //開總中斷
ET0=1; //開定時器0中斷
TR0=1; //啟動定時器0
while(1)
{
if(flag1==1)
{
temp=temp4;
P2=0xeb;
P3=0xeb;
display();
if(count==20) //1秒時間到
{
count=0;
temp4--;
if(temp4==-1)
{
temp4=5;
flag=0;
break;
}
}
}
else
{
if(n==1)
{
P2=0xdb;
P3=0xdb;
}
}
anjian();
}
}
//--------------矩陣鍵盤掃描函數------------//
void anjian()
{
uchar i;
d=0; //第一行鍵盤為0
if(a==0)
{
for(i=0;i<N;i++) //去抖
{
display();
}
if(a==0) //第一個按鍵按下
{
while(!a); //按鍵釋放
flag1=1;
t++;
if(t==1)
{
TR0=0; //關閉定時器0
display();
}
if(t==2)
{
t=0;
TR0=1; //啟動定時器0
display();
}
}
}
if(t!=0)
{
if(b==0)
{
for(i=0;i<N;i++)
{
display();
}
if(b==0)
{
while(!b);
if(t==1)//按下第一個鍵一次,第二個按鍵按下
{
display();
switch(flag)
{
case 1: temp1++;
if(temp1==60)
temp1=0;
break;
case 2: temp2++;
if(temp2==5)
temp2=0;
break;
case 3: temp3++;
if(temp3==40)
temp3=0;
break;
case 4: temp4++;
if(temp4==5)
temp4=0;
break;
}
}
}
}
if(c==0)
{
for(i=0;i<N;i++)
{
display();
}
if(c==0)
{
while(!c);
if(t==1)//按下第一個鍵一次,第三個按鍵按下
{
display();
switch(flag)
{
case 1: temp1--;
if(temp1==-1)
temp1=60;
break;
case 2: temp2--;
if(temp2==-1)
temp2=5;
break;
case 3: temp3--;
if(temp3==-1)
temp3=40;
break;
case 4: temp4--;
if(temp4==-1)
temp4=5;
break;
}
}
}
}
}
//-----------緊急按鍵-------------------//
e=0; //第二行鍵盤為0
if(a==0)
{
for(i=0;i<N;i++) //去抖
{
display();
}
if(a==0) //第四個按鍵按下
{
while(!a); //按鍵釋放
flag1=0;
n++;
if(n==1)
{
TR0=0; //關閉定時器0
display();
}
if(n==2)
{
n=0;
TR0=1;
flag1=1;
}
}
}
}
//-----------------主函數---------------------//
void main()
{
P1M1=0;
P1M0=0xff; //設置P1口推挽輸出
while(1)
{
zhuangtai1();
zhuangtai2();
zhuangtai3();
zhuangtai4();
}
}
//-------------定時器中斷----------------//
void timer0() interrupt 1
{
TH0=(65536-46070)/256;
TL0=(65536-46070)%256;
count++;
}