#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P3^6; //段選鎖存器鎖存端
sbit wela=P3^7; //位選鎖存器鎖存端
uchar time1=13; //初值南北13秒
uchar time2=10; //初值東西10秒
uchar t1=13,t2=10,chose=0;
uchar time1_2,temp=0,p=0,tab;
uchar shi1,ge1,shi2,ge2,q;
uchar status,key,flag;
//共陰極數字顯示編碼
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f};
uchar code wei[]={0xfd,0xfe,0xf7,0xfb,
0xdf,0xef,0x7f,0xbf}; //位選
void delay(uint x)
{
uint i,j;
for(i=x;i>0;i--) //定時x毫秒
for(j=110;j>0;j--);
}
void display(uint ge1,uint shi1,uint ge2,uint shi2) //數碼管顯示
{
//顯示北
wela=1; //打開位選鎖存器
P0=wei[0]; //送入位選碼(北個位)
wela=0; //關閉位選鎖存器
P0=0; //消影
dula=1; //打開段選鎖存器
P0=table[ge1]; //送入段選
dula=0; //關閉段選鎖存器
delay(1);
wela=1; //打開位選鎖存器
P0=wei[1]; //送入位選碼(北十位)
wela=0; //關閉位選鎖存器
P0=0;
dula=1; //打開段選鎖存器
P0=table[shi1]; //送入段選
dula=0; //關閉段選鎖存器
delay(1);
//顯示東西
wela=1; //打開位選鎖存器
P0=wei[2]; //送入位選碼(東個位)
wela=0; //關閉位選鎖存器
P0=0;
dula=1; //打開段選鎖存器
P0=table[ge2];
dula=0; //關閉段選鎖存器
delay(1);
wela=1; //打開位選鎖存器
P0=wei[3]; //送入位選碼(東十位)
wela=0; //關閉位選鎖存器
P0=0;
dula=1; //打開段選鎖存器
P0=table[shi2];
dula=0; //關閉段選鎖存器
delay(1);
}
void key1_6()
{
//第一個按鍵(南北通行)
if(key==1)
{
TR0=0; //定時器0停止計時
P1=0x0c; //南北通行
p=1; //數碼管顯示99
}
//第二個按鍵(東西通行)
if(key==2)
{
TR0=0; //定時器0停止計時
P1=0x21; //東西通行
p=1;
}
//第三個按鍵(夜間模式)
if(key==3)
{
TR0=0; //關閉定時器
p=1;
}
//第四個按鍵(減時間)
if(key==4)
{
p=0;
TR0=0; //定時器0停止計時
P1=0; //燈滅
if(chose==0) //減南北方向
{
if(time1>0) //最低減到0
{
time1--;
t1=time1;
}
}
if(chose==1) //減東西方向
{
if(time2>0)
{
time2--;
t2=time2;
}
}
}
//第五個按鍵(加時間)
if(key==5)
{
p=0;
TR0=0; //定時器0停止計時
P1=0; //燈滅
if(chose==0) //加南北方向
{
if(time1<99) //最多加到99
{
time1++;
t1=time1;
}
}
if(chose==1) //加東西方向
{
if(time2<99)
{
time2++;
t2=time2;
}
}
}
//第六個按鍵(加減后確定工作)
if(key==6)
{
if(time1>time2)
time1=time2+3;
else
time2=time1+3;
temp=0; //計數值清零
p=0;
P1=0x21; //南北紅燈,東西綠燈
TR0=1; //定時器0開始計時
}
//第七個按鍵(切換)
if(key==7)
{
p=0;
chose=!chose;
}
}
void dis()
{
wela=1;
P0=0xff;
wela=0;
}
void main()
{
P1=0x21; //剛開始南北的紅燈亮,東西的綠燈亮
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256; //初值
EA=1; //打開總中斷
ET0=1; //定時器0允許中斷
TR0=1; //定時器0開始計時
EX0=1; //外部中斷0允許位
IT0=1; //外部中斷0觸發方式(下降沿)
while(1)
{
if(flag)
{
switch(status) //判斷按鍵
{
case 0xfe:key=1;break;
case 0xfd:key=2;break;
case 0xfc:key=3;break;
case 0xfb:key=4;break;
case 0xfa:key=5;break;
case 0xf9:key=6;break;
case 0xf8:key=7;break;
}
key1_6(); //按鍵程序
flag=0;
}
if(!p)
{
shi1=time1/10; //南北十位
ge1=time1%10; //南北個位
shi2=time2/10; //東西十位
ge2=time2%10; //東西個位
display(ge1,shi1,ge2,shi2); //顯示函數
}
if(p)
dis(); //不顯示函數
if(key==3) //夜間模式
{
P0=0xff;
q=!q;
if(q!=0)
P1=0x12;
else
P1=0;
delay(200);
}
}
}
void ext0() interrupt 0
{
flag=1;
status=P2;
}
void timer() interrupt 1 //定時中斷程序
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256; //重新賦初值
temp++;
if(temp==20) //說明過去了1秒
{
temp=0; //清零,重新加到20
//東西方向南北方向時間自減
time1--;
time2--;
if(time1>time2) //南北大于東西
{
time1=time2+3;
P1=0x21; //南北紅燈亮起,東西綠燈亮起
if(time2==0&&time1==3)
{
time2=3; //重新賦南北和東西的差值,與南北方向一起倒計時
P1=0x11; //東西黃燈亮起,東西綠燈關閉
tab=0; //標志位
}
}
if(time1<time2) //南北小于東西
{
time2=time1+3;
P1=0x0c; //南北綠燈亮起,東西紅燈亮起
if(time1==0&&time2==3)
{
time1=3; //重新賦南北和東西的差值,與東西方向一起倒計時
P1=0x0a; //南北黃燈亮起,南北綠燈關閉
tab=1; //標志位
}
}
if(!tab) //黃燈閃爍三秒
{
if(time1==2&&time2==2)
P1=0x01;
if(time1==1&&time2==1)
P1=0x11;
}
if(tab)
{
if(time1==2&&time2==2)
P1=0x08;
if(time1==1&&time2==1)
P1=0x0a;
}
if(time1==0&&time2==0&&tab==0) //東西倒計時結束
{
time1=t1;
time2=t1+3;
P1=0x0c; //東西紅燈,南北綠燈
}
if(time1==0&&time2==0&&tab==1) //南北倒計時結束
{
time1=t2+3;
time2=t2;
P1=0x21; //南北紅燈,東西綠燈
}
}
}
18DF73AD5C62DFFC8C38D87D550072C4.png (5.59 MB, 下載次數: 48)
下載附件
2021-11-15 21:23 上傳
|