#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; //南北红灯,东西绿灯
}
}
}
|