通过51单片机实现简易交通灯系统
如果需要proteus仿真,联系作者
紧急情况可以按下按键让所有的信号灯全变为红色
雨天雾天可以按下按键让所有的信号灯全变为黄色
利用定时器实现信号灯的倒计时,外部中断实现外部控制
按下复位键即可重新开始工作
#define uchar unsigned char
#define uint unsigned int
#include <reg52.h>
/*****定义控制位**********************/
sbit EW_LED2=P2^3; //EW_LED2控制位
sbit EW_LED1=P2^2; //EW_LED1控制位
sbit SN_LED2=P2^1; //SN_LED2控制位
sbit SN_LED1=P2^0; //SN_LED1控制位
sbit SN_Yellow=P1^6; //SN黄灯
sbit SN_Red=P1^7; //SN红灯
sbit EW_Yellow=P1^2; //EW黄灯
sbit EW_Red=P1^3; //EW红灯
bit Flag_SN_Yellow; //SN黄灯标志位
bit Flag_EW_Yellow; //EW黄灯标志位
char Time_EW; //东西方向倒计时单元
char Time_SN; //南北方向倒计时单元
sbit k1=P3^2;
sbit k2=P3^3;
uchar EW=10,SN=10,EWL=3,SNL=3; //程序初始化赋值,正常模式
uchar EW1=10,SN1=10,EWL1=3,SNL1=3; //用于存放修改值的变量
uchar code table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~~~~9段选码
uchar code S[9]={0X28,0X48,0X18,0X48,0X82,0X84,0X81,0X84,0x88};//交通信号灯控制代码
/**********************延时子程序************************/
void delay_ms(unsigned int x) //延时ms
{
unsigned int i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
/*****************显示子函数**************************/
void Display(void) //数码管倒计时显示
{
char h,l;
h=Time_EW/10;
l=Time_EW%10;
P0=table[l];
EW_LED2=1;
delay_ms(1);
EW_LED2=0;
P0=table[h];
EW_LED1=1;
delay_ms(1);
EW_LED1=0;
h=Time_SN/10;
l=Time_SN%10;
P0=table[l];
SN_LED2=1;
delay_ms(1);
SN_LED2=0;
P0=table[h];
SN_LED1=1;
delay_ms(1);
SN_LED1=0;
}
/**********************T0中断服务程序*******************/
void timer0(void)interrupt 1 using 1
{
static uchar count;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==10)
{
if(Flag_SN_Yellow==1) //测试南北黄灯标志位
{SN_Yellow=~SN_Yellow;}
if(Flag_EW_Yellow==1) //测试东西黄灯标志位
{EW_Yellow=~EW_Yellow;}
}
if(count==20) {
Time_EW--;
Time_SN--;
if(Flag_SN_Yellow==1)//测试南北黄灯标志位
{SN_Yellow=~SN_Yellow;}
if(Flag_EW_Yellow==1)//测试东西黄灯标志位
{EW_Yellow=~EW_Yellow;}
count=0;
}
}
/*********************主程序开始**********************/
void main(void)
{
TMOD=0x01;//定时器工作于方式1
TH0=(65536-50000)/256;//定时器赋初值
TL0=(65536-50000)%256;
EA=1; //CPU开中断总允许
ET0=1;//开定时中断
TR0=1;//启动定时
IT0=1;//外部中断0下降沿触发
EX0=1; //允许外部中断
IT1=1;//外部中断0下降沿触发
EX1=1; //允许外部中断
/*******S0状态(初始状态)**********/
Time_EW=3;
Time_SN=3;
while(Time_SN>=0||Time_EW>=0)
{
Flag_EW_Yellow=0; //EW关黄灯显示信号
P1=S[8]; //所有路口红灯
Display();
}
while(1)
{
/*******S1状态(主干道直行状态)**********/
Time_EW=EW;
Time_SN=SN;
while(Time_SN>=4)
{
Flag_EW_Yellow=0; //EW关黄灯显示信号
P1=S[0]; //SN通行,EW红灯
Display();
}
/*******S2状态(主干道直行黄灯闪烁状态)**********/
P1=0x00;
while(Time_SN>=0)
{
Flag_SN_Yellow=1; //SN开黄灯信号位
EW_Red=1; //SN黄灯亮,等待左转信号,EW红灯
Display();
}
/***********赋值(主干道通行变次干道通行)**********/
EW=EW1;
SN=SN1;
EWL=EWL1;
SNL=SNL1;
/*******S3状态(次干道直行状态)**********/
Time_EW=SN;
Time_SN=EW;
while(Time_EW>=4)
{
Flag_SN_Yellow=0; //SN关黄灯显示信号
P1=S[4]; //EW通行,SN红灯
Display();
}
/*******S4状态(次干道直行黄灯闪烁状态)**********/
P1=0X00;
while(Time_EW>=0)
{
Flag_EW_Yellow=1;//EW开黄灯信号位
SN_Red=1;//EW黄灯亮,等待左拐信号,SN红灯
Display();
}
/***********赋值(次干道通行变主干道通行)**********/
EW=EW1;
SN=SN1;
EWL=EWL1;
SNL=SNL1;
}
}
/*******利用外部中断0实现紧急状况全变为红灯**********/
void Int0 () interrupt 0
{
delay_ms(10);
if(k1==0)
{
P1=S[8];while(1);
}
}
/*******利用外部中断1实现雨天雾天变为黄灯**********/
void Int1 () interrupt 2
{
delay_ms(10);
if(k2==0)
{
P1=0x44;while(1);
}
}