欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于51单片机的交通信号灯(Proteus仿真+源码)

程序员文章站 2024-01-10 23:54:40
...

一、 系统方案

模拟交通灯控制系统就是使用单片机来控制一些LED灯和数码管,模拟真实交通灯的功能。南北主干道通车时绿灯亮,而东西次干道红灯亮;当主干道通车7s时间过了之后,绿灯熄灭,黄灯亮,黄灯闪烁3s,之后由主干道切换到次干道通车。此时主干道黄灯熄灭,红灯亮,而次干道红灯熄灭,绿灯亮,次干道开始通车;7s通车时间到后,次干道绿灯熄灭,黄灯亮,黄灯亮3s后由次干道切换到主干道;而主干道红灯熄灭,绿灯亮,如此循环。红、黄、绿交替闪亮,利用数码管倒计时,用于管理十字路口的车辆及行人交通。

二、硬件设计

1. 振荡电路

片内的高增益反向放大器通过XTAL1、XTAL2端外接作为反馈元件的片外晶体振荡器与电容组成的并联谐振回路构成一个自激振荡器,向内部时钟电路提供振荡时钟。本实验采用12MHz的晶振频率,电容C1,C2的值为30pF,电容的大小对振荡频率有微小的作用,可起频率微调作用。

基于51单片机的交通信号灯(Proteus仿真+源码)

2. 复位电路

单片机在运行中由于本身或外界干扰的原因会导致出错,此时可以使用按键复位,使单片机恢复初始状态。
基于51单片机的交通信号灯(Proteus仿真+源码)

3. P0口驱动电路

用P0口控制两位的八段数码管。由于P0口输出为漏极开路式,因此需要外接上拉电阻,阻值一般为5~10kΩ,本实验采用阻值为10kΩ的上拉电阻。
基于51单片机的交通信号灯(Proteus仿真+源码)

4. 数码管显示电路

在P1口外接六个红绿灯,南北各三个红绿灯,因为南北红绿灯变化一样,东西红绿灯变化一样,因此用P1.1、P1.2、P1.3端口控制东西方向的红绿灯,P1.5、P1.6、P1.7端口控制南北方向的红绿灯。
基于51单片机的交通信号灯(Proteus仿真+源码)

5. 总电路原理图

基于51单片机的交通信号灯(Proteus仿真+源码)

三、 软件设计(流程图)

1. 交通灯显示流程图

基于51单片机的交通信号灯(Proteus仿真+源码)

四、 仿真结果

1. 南北绿灯,东西红灯。

基于51单片机的交通信号灯(Proteus仿真+源码)

2.南北倒计时剩余三秒 ,黄灯开始闪烁。

基于51单片机的交通信号灯(Proteus仿真+源码)

3. 东西倒计时剩余3s,黄灯开始闪烁

基于51单片机的交通信号灯(Proteus仿真+源码)

4. 按下复位按键,回到初始状态。

基于51单片机的交通信号灯(Proteus仿真+源码)

五、C语言实现

#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;  //南北方向倒计时单元
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;//启动定时

	/*******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;
	} 
}


//注意:需要在proteus仿真软件进行仿真必须将上述C语言代码生成为后缀名为.hex的文件