基于51单片机的交通灯设计

        基于51单片机的交通灯设计利用AT89C51作为系统主控,使用四个二位数码管设计四个方向的倒计时,同时每个路口设计了红外模块,通过外部中断扩展检测下降沿,判断是否有行人通过。当未能到红灯时间有行人通过,蜂鸣器响起。

一、参考代码

        下面是本次设计的主要代码,主要实现定时器定时交通灯切换的逻辑,同时检测,红灯方向上是否有人员通过,如果有人员通过蜂鸣器进行报警,表示人员危险状态。

#include <REGX52.H>
#include "delay.h"
#include "Timer0.h"
#include "nixie.h"
#include "KEY.H"

typedef unsigned char u8;

u8 KeyNum,Temp;
u8 Sec,MiniSec;
u8 RunFlag=1;

int upSec_set=20, rightSec_set=20, btnSec_set=20, leftSec_set=20, change=5;
int upSec=20, rightSec=20, btnSec=20, leftSec=20;
u8 mode=0, lastState=0;
int upNum=0, rightNum=0, btnNum=0, leftNum=0;

sbit buzzer=P2^7;

sbit upRed 			= P1^0;
sbit upGreen 		= P1^1;
sbit upYellow 		= P1^2;

sbit rightRed 		= P1^3;
sbit rightGreen 	= P1^4;
sbit rightYellow 	= P1^5;

sbit dwnRed 		= P1^6;
sbit dwnGreen 		= P1^7;
sbit dwnYellow 		= P2^3;

sbit leftRed 		= P2^4;
sbit leftGreen 		= P2^5;
sbit leftYellow 	= P2^6;

void setTime()
{
	upSec = upSec_set;
	rightSec = rightSec_set;
	btnSec = btnSec_set;
	leftSec = leftSec_set;
}

//数码管显示显示
void showNixie()
{
	switch(mode){
		case 0:{
			nixie(1, upSec/10);
			nixie(2, upSec%10);
			nixie(3, (upSec+change)/10);
			nixie(4, (upSec+change)%10);
			nixie(5, (upSec+change+rightSec+change)/10);
			nixie(6, (upSec+change+rightSec+change)%10);
			nixie(7, (upSec+change+rightSec+change+btnSec+change)/10);
			nixie(8, (upSec+change+rightSec+change+btnSec+change)%10);				
		}break;
		case 1:{
			nixie(1, (rightSec+change+btnSec+change+leftSec+change)/10);
			nixie(2, (rightSec+change+btnSec+change+leftSec+change)%10);
			nixie(3, (rightSec)/10);
			nixie(4, (rightSec)%10);
			nixie(5, (rightSec+change)/10);
			nixie(6, (rightSec+change)%10);
			nixie(7, (rightSec+change+btnSec+change)/10);
			nixie(8, (rightSec+change+btnSec+change)%10);			
		}break;
		case 2:{
			nixie(1, (btnSec+change+leftSec+change)/10);
			nixie(2, (btnSec+change+leftSec+change)%10);
			nixie(3, (btnSec+change+leftSec+change+upSec+change)/10);
			nixie(4, (btnSec+change+leftSec+change+upSec+change)%10);
			nixie(5, (btnSec)/10);
			nixie(6, (btnSec)%10);
			nixie(7, (btnSec+change)/10);
			nixie(8, (btnSec+change)%10);				
		}break;
		case 3:{
			nixie(1, (leftSec+change)/10);
			nixie(2, (leftSec+change)%10);
			nixie(3, (leftSec+change+upSec+change)/10);
			nixie(4, (leftSec+change+upSec+change)%10);
			nixie(5, (leftSec+change+upSec+change+rightSec+change)/10);
			nixie(6, (leftSec+change+upSec+change+rightSec+change)%10);
			nixie(7, (leftSec)/10);
			nixie(8, (leftSec)%10);			
		}break;
		case 4:{
			if(lastState==0){
				nixie(1, change/10);
				nixie(2, change%10);
				nixie(3, (upSec+change)/10);
				nixie(4, (upSec+change)%10);
				nixie(5, (upSec+change+rightSec+5)/10);
				nixie(6, (upSec+change+rightSec+5)%10);
				nixie(7, (upSec+change+rightSec+5+btnSec+5)/10);
				nixie(8, (upSec+change+rightSec+5+btnSec+5)%10);				
			}
			else if(lastState==1){
				nixie(1, (rightSec+change+btnSec+5+leftSec+5)/10);
				nixie(2, (rightSec+change+btnSec+5+leftSec+5)%10);
				nixie(3, (change)/10);
				nixie(4, (change)%10);
				nixie(5, (rightSec+change)/10);
				nixie(6, (rightSec+change)%10);
				nixie(7, (rightSec+change+btnSec+5)/10);
				nixie(8, (rightSec+change+btnSec+5)%10);				
			}
			else if(lastState==2){
				nixie(1, (btnSec+change+leftSec+5)/10);
				nixie(2, (btnSec+change+leftSec+5)%10);
				nixie(3, (btnSec+change+leftSec+5+upSec+5)/10);
				nixie(4, (btnSec+change+leftSec+5+upSec+5)%10);
				nixie(5, (change)/10);
				nixie(6, (change)%10);
				nixie(7, (btnSec+change)/10);
				nixie(8, (btnSec+change)%10);				
			}
			else if(lastState==3){
				nixie(1, (leftSec+change)/10);
				nixie(2, (leftSec+change)%10);
				nixie(3, (leftSec+change+upSec+5)/10);
				nixie(4, (leftSec+change+upSec+5)%10);
				nixie(5, (leftSec+change+upSec+5+rightSec+5)/10);
				nixie(6, (leftSec+change+upSec+5+rightSec+5)%10);
				nixie(7, (change)/10);
				nixie(8, (change)%10);			
			}
		}break;
		default:break;
	}

}

void showYellowLed(u8 lastState)
{
	switch(lastState){
		case 0:{
			upRed=1;upGreen=1;upYellow =0;

			rightRed =0;rightGreen 	=1;rightYellow =1;
		  
			dwnRed =0;dwnGreen =1;dwnYellow =1;
	 
			leftRed =0;leftGreen =1;leftYellow =1;					
		}break;
		case 1:{
			upRed 	=0;upGreen =1;upYellow =1;

			rightRed =1;rightGreen =1;rightYellow =0;
		  
			dwnRed 	=0;dwnGreen =1;dwnYellow =1;
	 
			leftRed =0;leftGreen=1;leftYellow=1;						
		}break;
		case 2:{
				upRed =0;upGreen=1;upYellow=1;
  
				rightRed =0;rightGreen =1;rightYellow =1;
			  
				dwnRed =1;dwnGreen =1;dwnYellow=0;
		 
				leftRed=0;leftGreen=1;leftYellow=1;						
		}break;
		case 3:{
			upRed =0;upGreen=1;upYellow=1;

			rightRed=0;rightGreen =1;rightYellow =1;
		  
			dwnRed =0;dwnGreen =1;dwnYellow=1;
	 
			leftRed=1;leftGreen =1;leftYellow=0;						
		}break;
		default:break;
	}	
}

//外部中断初始化
void Int0_Init()
{
	// 使能全局中断
	EA = 1;
	// 使能外部中断0
	EX0 = 1;
	// 配置外部中断0的触发方式为下降沿触发
	IT0 = 1;	
}

//外部中断捕捉
void Int0_ISR() interrupt 0
{
	switch(mode){
		case 0:{
			//进行车流量统计
			if(P3_4==0){
				upNum++;
			}
		}break;
		case 1:{
			if(P3_5==0){
				rightNum++;
			}
		}break;
		case 2:{
			if(P3_6==0){
				btnNum++;
			}
		}break;
		case 3:{
			if(P3_7==0){
				leftNum++;
			}
		}break;
		default:break;
	}
}

void main()
{
	Int0_Init();
    Timer0_Init();
//	UART_Init();
	while(1)
	{	
		//违规行驶判断
		switch(mode){
			case 0:{
				if(P3_5==0 || P3_6==0 || P3_7==0){
					buzzer=0;
				}
				else{
					buzzer=1;
				}
			}break;
			case 1:{
				if(P3_4==0 || P3_6==0 || P3_7==0){
					buzzer=0;
				}
				else{
					buzzer=1;
				}
			}break;
			case 2:{
				if(P3_4==0 || P3_5==0 || P3_7==0){
					buzzer=0;
				}
				else{
					buzzer=1;
				}
			}break;
			case 3:{
				if(P3_4==0 || P3_5==0 || P3_6==0){
					buzzer=0;
				}
				else{
					buzzer=1;
				}
			}break;
			default:break;
		}		
    }
}

void Sec_Loop()
{
	if(RunFlag)
	{
		if(++MiniSec>=100)
		{
			MiniSec=0;
			switch(mode){
				//北方向通行
				case 0:{
					showNixie();
					if(--upSec<=0){
						lastState=0;
						mode=4;
					}
					upRed 		=1;
					upGreen 	=0;
					upYellow 	=1;
      
					rightRed 	=0;
					rightGreen 	=1;
					rightYellow =1;
                  
					dwnRed 		=0;
					dwnGreen 	=1;
					dwnYellow 	=1;
             
					leftRed 	=0;
					leftGreen 	=1;
					leftYellow 	=1;
					
					}break;
				//东方向通行
				case 1:{
					showNixie();
					if(--rightSec<=0){
						lastState=1;
						mode=4;
					}
					upRed 		=0;
					upGreen 	=1;
					upYellow 	=1;
      
					rightRed 	=1;
					rightGreen 	=0;
					rightYellow =1;
                  
					dwnRed 		=0;
					dwnGreen 	=1;
					dwnYellow 	=1;
             
					leftRed 	=0;
					leftGreen 	=1;
					leftYellow 	=1;
					
				}break;
				//南方向通行
				case 2:{
					if(--btnSec<=0){
						lastState=2;
						mode=4;
					}	
					upRed 		=0;
					upGreen 	=1;
					upYellow 	=1;
      
					rightRed 	=0;
					rightGreen 	=1;
					rightYellow =1;
                  
					dwnRed 		=1;
					dwnGreen 	=0;
					dwnYellow 	=1;
             
					leftRed 	=0;
					leftGreen 	=1;
					leftYellow 	=1;
					
					showNixie();
				}break;
				
				case 3:{
					showNixie();
					if(--leftSec<=0){
						lastState=3;
						mode=4;
					}		
					upRed 		=0;
					upGreen 	=1;
					upYellow 	=1;
      
					rightRed 	=0;
					rightGreen 	=1;
					rightYellow =1;
                  
					dwnRed 		=0;
					dwnGreen 	=1;
					dwnYellow 	=1;
             
					leftRed 	=1;
					leftGreen 	=0;
					leftYellow 	=1;
					
				}break;
				//西方向通行
				case 4:{
					showNixie();
					showYellowLed(lastState);
					if(--change<0){
						change=5;
						switch(lastState){
							case 0:{
								mode=1;
								if(upNum>20){
									upSec_set+=5;
								}
								else if(upNum<10){
									upSec_set-=5;
									if(upSec_set<=10){
										upSec_set=10;
									}
								}
								upNum=0;
								setTime();
							}break;
							case 1:{

								mode=2;
								if(rightNum>20){
									rightSec_set+=5;
								}
								else if(rightNum<10){
									rightSec_set-=5;
									if(rightSec_set<=10){
										rightSec_set=10;
									}
								}
								rightNum=0;
								setTime();
							}break;
							case 2:{
								mode=3;
								if(btnNum>20){
									btnSec_set+=5;
								}
								else if(btnNum<10){
									btnSec_set-=5;
									if(btnSec_set<=10){
										btnSec_set=10;
									}
								}
								btnNum=0;
								setTime();
							}break;
							case 3:{
								mode=0;
								if(leftNum>20){
									leftSec_set+=5;
								}
								else if(leftNum<10){
									leftSec_set-=5;
									if(leftSec_set<=10){
										leftSec_set=10;
									}
								}
								leftNum=0;
								setTime();
							}break;
							default:break;
						}
					}
				}break;
				default:break;
			}		
		}		
	}	
}	

void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count1,T0Count2,T0Count3;
	TL0=0X18;
	TH0=0xfc;
	T0Count1++;
	if(T0Count1>=20)
	{
		T0Count1=0;
		Key_Loop();
	}
	T0Count2++;
	if(T0Count2>=2)
	{
		T0Count2=0;
		nixie_Loop();
	}
	T0Count3++;
	if(T0Count3>=10)
	{
		T0Count3=0;
		Sec_Loop();
	}		
}

二、功能演示

1、灯光切换逻辑

        如图可知,以下是红绿灯运行逻辑,四个二位数码管进行显示时间,同时到点进行红绿黄灯切换,如下图:

2、红外检测人员通过并报警

        当红灯方向有人员通过的时候,此时检测到有人员闯红灯,此时系统驱动蜂鸣器进行报警。

三、项目总结

        本次项目使用定时器加数码管加led实现了交通灯的一个仿真,通过交通灯倒计时时间实现红绿黄灯的切换,完成最后功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值