#include<reg51.H>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={ //共陰極數碼管碼表
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,
0xC9,0xFF,0x40};//設置碼,測試碼,不計時碼
void delay(uint x);//延時函數
void display(uchar,uchar,uchar,uchar); //數碼管顯示函數
void mkeys(); //鍵盤函數
void traffic(); //交通燈函數
uchar num,num1,num2, //1南北 2東西
shi1,ge1,shi2,ge2,
value1,value2,//南北 綠燈時間 黃燈時間
value3,value4,//東西 綠燈時間 黃燈時間
count1,count2,flag1,flag2; //南北標記 東西標記
void main()
{
TMOD=0x01;
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
EA=1;
ET0=1;
TR0=1;
/*初狀態*/
value1=15; //南北 黃綠燈默認值
value2=5;
value3=10; //東西 黃綠燈默認值
value4=5;
num1=value1; //南北數碼管先綠燈時間
num2=value2+value1;//東西紅燈時間
shi1=num1/10;
ge1=num1%10;
shi2=num2/10;
ge2=num2%10;
P1=0x41;//初始狀態:東西紅燈 南北綠燈 20 15
while(1){
if(num==20) //定時器1s
{
num=0;
num1--;
num2--;
traffic();
shi1=num1/10;
ge1=num1%10;
shi2=num2/10;
ge2=num2%10;
}
mkeys();
display(shi1,ge1,shi2,ge2);
}
}
void traffic() //紅綠燈主控制程序
{
if(num1==0){
count1++;
if(count1==1){
P1=0x42;//東西紅燈 南北黃燈 5 5
num1=value2;
}
if(count1==2){
num1=value3+value4;//東西綠燈 南北紅燈 10 15
P1=0x14;
}
if(count1==3){
P1=0x41;// 東西黃燈 南北紅燈 5 5
num1=value4;
count1=0;
}
}
if(num2==0){
count2++;
if(count2==1){
//P1=0x14;//東西綠燈 南北紅燈
num2=value3;
}
if(count2==2){
P1=0x24;//東西黃燈 南北紅燈
num2=value4;
}
if(count2==3){
num2=value1+value2; //東西紅燈 南北綠燈
num1=value1;
count2=0;
}
}
}
void display(uchar shi1,uchar ge1,uchar shi2,uchar ge2) //數碼管顯示子函數
{
uchar temp;
temp=P2;
P2=0xfe;
P0=table[shi1];
delay(5);
P2=0xfd;
P0=table[ge1];
delay(5);
P2=0xfb;
P0=table[shi2];
delay(5);
P2=0xf7;
P0=table[ge2];
delay(5);
}
void delay(uint x)//延時子函數
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
void mkeys() //4*4矩陣鍵盤功能子函數
{
uchar temp,key;
P3=0xfe;//第一行線
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0){
temp=P3;
switch(temp)
{
case 0xee:
key=0;
break;
case 0xde:
key=1;
break;
case 0xbe:
key=2;
break;
case 0x7e:
key=3;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
if(key==0) {//按鍵1:暫停
TR0=~TR0; //定時器取反
flag1=~flag1;//南北能夠設置標志 0有效
flag2=~flag2;//東西能夠設置標志
}
if(key==1&&flag1==0){ //按鍵2:設置時間按鈕
TR0=0;
P1=0x44;//禁止東南西北車輛 全為紅燈 可以設置
shi1=ge1=shi2=ge2=16;
}
if(key==2&&flag2==0){//按鍵3:設置完成 重啟
TR0=1;
num=0; //定時器 初始化
P1=0x41; //重新開始初狀態
num1=value1; //南北數碼管先綠燈時間
num2=value2+value1;//東西紅燈時間
shi1=num1/10;
ge1=num1%10;
shi2=num2/10;
ge2=num2%10;
}
if(key==3&&P1==0x44){ //按鍵4:測試交通燈各個設備的好壞
P1=0xff;
delay(1000);
P1=~P1;
shi1=ge1=shi2=ge2=17;
P1=0x44;
}
}
}
P3=0xfd;//第二行線
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0){
temp=P3;
switch(temp)
{
case 0xed:
key=0;
break;
case 0xdd:
key=1;
break;
case 0xbd:
key=2;
break;
case 0x7d:
key=3;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
if(key==0&&P1==0x44){ //按鍵5:設置南北綠燈時間+
num1=value1;
if(num2!=159){ //@@@@保證交通合理,紅燈最大值計時159s,綠燈不再增加
num1++;
value1=num1;
}
shi1=num1/10;
ge1=num1%10;
num2=value1+value2;//顯示東西紅燈時間
shi2=num2/10;
ge2=num2%10;
}
if(key==1&&P1==0x44){ //按鍵6:設置南北黃燈時間+
num1=value2;
if(num2!=159){
num1++;
value2=num1;
}
shi1=num1/10;
ge1=num1%10;
num2=value1+value2;//顯示東西紅燈時間
shi2=num2/10;
ge2=num2%10;
}
if(key==2&&P1==0x44&&value1>3){ //按鍵7:設置南北綠燈時間- @@@@保證交通合理,綠燈最小值計時3s,綠燈不再減少
num1=value1;
num1--;
value1=num1;
shi1=num1/10;
ge1=num1%10;
num2=value1+value2;//顯示東西紅燈時間
shi2=num2/10;
ge2=num2%10;
}
if(key==3&&P1==0x44&&value2>3){ //按鍵8:設置南北黃燈時間-
num1=value2;
num1--;
value2=num1;
shi1=num1/10;
ge1=num1%10;
num2=value1+value2;//顯示東西紅燈時間
shi2=num2/10;
ge2=num2%10;
}
}
}
////||||||||||||||||||
P3=0xfb;//第三行線
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0){
temp=P3;
switch(temp)
{
case 0xeb:
key=0;
break;
case 0xdb:
key=1;
break;
case 0xbb:
key=2;
break;
case 0x7b:
key=3;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
if(key==0&&P1==0x44){ //按鍵9:設置東西綠燈時間+
num2=value3;
if(num1!=159){
num2++;
value3=num2;
}
shi2=num2/10;
ge2=num2%10;
num1=value3+value4;//顯示南北紅燈時間
shi1=num1/10;
ge1=num1%10;
}
if(key==1&&P1==0x44){ //按鍵10:設置東西黃燈時間+
num2=value4;
if(num1!=159){
num2++;
value4=num2;
}
shi2=num2/10;
ge2=num2%10;
num1=value3+value4;//顯示南北紅燈時間
shi1=num1/10;
ge1=num1%10;
}
if(key==2&&P1==0x44&&value3>3){ //按鍵11:設置東西綠燈時間-
num2=value3;
num2--;
value3=num2;
shi2=num2/10;
ge2=num2%10;
num1=value3+value4;//顯示南北紅燈時間
shi1=num1/10;
ge1=num1%10;
}
if(key==3&&P1==0x44&&value4>3){ //按鍵12:設置東西黃燈時間-
num2=value4;
num2--;
value4=num2;
shi2=num2/10;
ge2=num2%10;
num1=value3+value4;//顯示南北紅燈時間
shi1=num1/10;
ge1=num1%10;
}
}
}
P3=0xf7;//第四行線 2未用
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0){
temp=P3;
switch(temp)
{
case 0xe7:
key=0;
break;
case 0xd7:
key=1;
break;
case 0xb7:
key=2;
break;
case 0x77:
key=3;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
if(key==0&&P1==0x44){ //按鍵13:南北緊急情況:南北綠燈常亮 東西紅燈常亮
P1=0x41;
shi1=ge1=shi2=ge2=18;
}
if(key==1&&P1==0x44){ //按鍵14:東西緊急情況:東西綠燈常亮 南北紅燈常亮
P1=0x14;
shi1=ge1=shi2=ge2=18;
}
if(key==2&&P1==0x44){//按鍵15:
}
if(key==3&&P1==0x44){//按鍵16:
}
}
}
}
void T0_time() interrupt 1 //定時器T0 中斷子程序
{
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
num++;
} |