📄 traffic_light.c
字号:
#include<REG51.H>
#define uint unsigned int
#define uchar unsigned char
uchar code SEG7[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //段码组合,共阴极
uchar code ACT[4]={0xfe,0xfd,0xfb,0xf7}; //位码组合 低有效
//*************************************************************************************
uchar sec=30,cnt,flag=0,m,n,status=0,i,j,sign1,sign2; //sec控制东西、南北方向时间;cnt记录一次中断;flag控制黄灯闪烁;sign作为按键按下标记;
//*************************************************************************************
sbit EWGREEN=P2^0; //定义六盏交通灯的端口
sbit EWYELLOW=P2^1;
sbit EWRED=P2^2;
sbit SNGREEN=P2^4;
sbit SNYELLOW=P2^5;
sbit SNRED=P2^6;
sbit P3_0=P3^0; // 定义按键接口
sbit P3_1=P3^1;
sbit P3_2=P3^2;
sbit GREEN=P3^4; //按键控制灯接口
sbit YELLOW=P3^5;
sbit RED=P3^6;
//************************调用函数定义**************************************************
void LED_ORD(uchar);
void LED_5S(uchar);
void key_s1();
void key_s2();
void key_s3();
//*************************中断程序*************************************************
void inrupt(void)
{
TMOD=0x01;
TH0 = -(50000/256);
TL0 = -(50000%256);
ET0=1;
TR0=1;
EA=1;
}
//**************************中断处理程序***************************************************
void timeout(void) interrupt 1
{
TH0=-(50000/256);
TL0=-(50000%256);
cnt++;
key_s1(); //控制“东西”道路时间的按键(有20和30秒的选择)
key_s2(); //控制“南北”道路时间的按键
key_s3(); //紧急停止通车按键
switch(status)
{
case 0: m=1;n=1;i=0;j=1; break; //status是0和1两种状态;控制是轮到“东西”显示还是“南北”显示;
case 1: m=2;n=2;i=2;j=3; break;
}
if(flag==0){LED_ORD(m);} //红绿灯正常显示
else
{
if(cnt<=10){LED_5S(n);} //黄灯闪
else {EWYELLOW=1;SNYELLOW=1;} // 黄灯灭
}
if(cnt>=20)
{
sec--;cnt=0;
if(sec<=5)
{
flag=1;
if(sec==0)
{
if(status==0) //让两次交替循环下去
{
status=1;flag=0;i=2;j=3; //status=0状态结束,开始status=1状态,重新赋值;
if(sign2==0) sec=20;
else sec=30;
} //flag重置为0;flag用来提示到了5秒内闪黄灯;
else
{
status=0;flag=0;i=0;j=1; //status=1状态结束,开始status=0状态,重新赋值;
if(sign1==0) sec=20;
else sec=30;
} //此处多添加了i和j重新复制;是因为:
} //当一个状态过后到了这里,但是i和j如果不重新赋值则还是等于上个状态显示的位码;
} //则接下去会在原来显示的位码处显示一个中断时间,又跳回新的显示位码;
}
}
void LED_ORD(uchar f) //控制东西、南北红绿灯
{
switch(f)
{
case 1: P2=0xBE; break;
case 2: P2=0xEB; break;
}
}
void LED_5S(uchar f) //控制东西、南北黄灯
{
switch(f)
{
case 1: EWGREEN=1;EWYELLOW=0; break;
case 2: SNGREEN=1;SNYELLOW=0; break;
}
}
void key_s1()
{
if(P3_0==0) {sign1=0;GREEN=0;}
else {sign1=1;GREEN=1;}
}
void key_s2()
{
if(P3_1==0) {sign2=0;YELLOW=0;}
else {sign2=1; YELLOW=1;}
}
void key_s3()
{
if(P3_2==0)
{
P2=0xBB;P1=0xff;RED=0;
while(1)
{
if(P3_2==1){RED=1;break;}
}
status=0; sec=30;
}
}
void delay(uint t)
{
uint data i,j;
for(i=0;i<t;i++)
{for(j=0;j<50;j++){;}}
}
void main(void)
{
inrupt();
for(;;)
{
P1=0xff;
P0=SEG7[sec%10];
P1=ACT[i];
delay(1);
while(sec/10) //当sec小于10的时候只现实个位;
{
P1=0xff;
P0=SEG7[sec/10];
P1=ACT[j];
break;//不加会产生死循环;
}
delay(1);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -