基于51单片机的交通灯设计(含Proteus仿真和原理图及芯片头文件等资料)

基于51单片机的交通灯设计(附有Proteus仿真和原理图)
该设计,难点在于程序编写时对于定时器中断,标志位的灵活使用,其次是对数码管的控制。
注:
1.单片机型号是“stc10f08xe”,Keil软件中不包含stc10.h这个头文件,与原理图和仿真文件一起附在附件中了。
2.此型号的单片机端口驱动能力不够,采用的推挽输出,增强对小灯的驱动能力,改善实际显示效果
3.按下plus button 可以增加此干道的通行时间,minus button可以减少通行时间,stop button对应紧急情况,所有路口红灯亮。
4.下载附件后若无法查看,建议修改文件格式为“zip”,然后解压查看。

交通灯仿真界面图仿真启动显示通行时间,主干道绿灯亮,次干道红灯亮绿灯通行结束后,有3秒的等待时间,黄灯亮起紧急情况,所有路口红灯亮

/****************************************交通灯程序*********************************************/
/*
	作者:Eric 
	功能:以南北方向为主干道,东西方向为次干道。		
			1、实现主干道通行15秒转通行注意状态,黄灯亮3秒。这段时间内次干道保持红灯常亮  (由数码管显示时间)
			2、次干道通行10秒转通行注意状态,黄灯亮2秒。这段时间内主干道保持红灯常亮      (由数码管显示时间)
			3、紧急按键按下,所有路口红灯 
			
/************************************调用头文件、宏定义*****************************************/
#include<stc10.h>
#define D P1
#define uchar unsigned char
#define uint unsigned int
/*******************************************函数声明******************************************/
void z1(void);//南北通
void z2(void);//南北注意
void z3(void);//东西通
void z4(void);//东西注意
void gb(void);	 //全关
void jinji(void);//紧急状态,红灯全亮
void sm(void);   //键盘扫描
void plus();	 //加一扫描
void minus();	 //减一扫描
void plus2();
void minus2();
void timer(void);//定时器T1初始化
void time1(void);//定义定时器T1中断服务程序
void display(void);//显示函数
void delay(uint a);//10ms延时函数
/*************************************定义数组,全局变量***************************************/
uint duan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0~9断码数组
uint y,gw,sw,gw2,sw2;								  //全局变量
int time,s,times,time2,times2,time3;
/*********************************定义12个小灯、数码管位、按键*********************************/
/*************12个小灯*******************/     //数码管位选//   // 按键 //
sbit d1 =P2^0; sbit d2 =P2^1; sbit d3= P2^2;   sbit w1=P0^0;   sbit H1 =P3^6;	sbit H2=P3^7;	
sbit d4 =P2^3; sbit d5 =P2^4; sbit d6= P2^5;   sbit w2=P0^1;   sbit key1 =P0^5;	
sbit d7 =P2^6; sbit d8 =P2^7; sbit d9= P3^2;   sbit w3=P0^2;   sbit key2 =P0^6;
sbit d10=P3^3; sbit d11=P3^4; sbit d12=P3^5;   sbit w4=P0^3;   sbit key3 =P0^7;


/*********************************************主函数***********************************************/
void main(void)
{  			
	times=18;
	time=15;
	time2=10;
	times2=12;
	y=0,s=0;   //定时器溢出计数初始化
	P1M1=0X00; //推挽输出,增加数码管亮度  
	P1M0=0XFF;	
	timer();   //启动定时器T1
	while(1) 
	{
		z1();  //主干道通行,绿灯15秒
		z2();  //主干道注意,黄灯 3秒
		z3();  //次干道通行,绿灯10秒
		z4();  //次干道注意,黄灯 2秒
   	}					  
}
/******************不同状态函数、定时器初始化、定时器中断服务函数************************/
void z1(void)//南北通行,东西禁止
{   	
	while(s<time)
	{
		sm();
		plus();
		minus();
		if(TR1==1)
		{
		//蓝   /黄   /红
		d4 =0;d5 =1;d6 =1;//北		
		d10=0;d11=1;d12=1;//南
		d7 =1;d8 =1;d9 =0;//东
		d1 =1;d2 =1;d3 =0;//西
		}
		sw2=(time-s)/10;  //数码管十位(南北主干道) 
		gw2=(time-s)%10;  //数码管个位	
		sw=(times-s)/10;
		gw=(times-s)%10;	  
		display();		  //显示
		gb();			  //关闭
	}	s=0;//对定时时间标志位清零重置							   
}
void z2(void)//南北注意,东西禁止
{   	
	time3=3;
	while(s<time3)
	{	
		sm();
		if(TR1==1)
		{
		//蓝   /黄   /红								
		d4 =1;d5 =0;d6 =1;//北			
		d10=1;d11=0;d12=1;//南
		d7 =1;d8 =1;d9 =0;//东
		d1 =1;d2 =1;d3 =0;//西
		}
		sw2=(time3-s)/10;  //数码管十位(南北主干道) 
		gw2=(time3-s)%10;  //数码管个位
		sw=sw2;			  //东西次干道
		gw=gw2;	  
		display();		  //显示
		gb();			  //关闭
	}	s=0;
}
void z3(void)//东西通行,南北禁止
{   

	while(s<time2)
	{	
		sm();
		plus2();
		minus2();
		//蓝   /黄   /红									 
		d4 =1;d5 =1;d6 =0;//北			
		d10=1;d11=1;d12=0;//南
		d7 =0;d8 =1;d9 =1;//东
		d1 =0;d2 =1;d3 =1;//西
		sw2=(times2-s)/10;;		  //南北主干道
		gw2=(times2-s)%10;
		sw=(time2-s)/10;   //数码管十位(东西次干道)
		gw=(time2-s)%10;   //数码管个位	  		 
		display();		  //显示
		gb();			  //关闭
	} 	s=0;
}
void z4(void)//东西注意,南北禁止
{   
	time3=2;
	while(s<time3)
	{
		sm();
		//蓝   /黄   /红								
		d4 =1;d5 =1;d6 =0;//北			
		d10=1;d11=1;d12=0;//南
		d7 =1;d8 =0;d9 =1;//东
		d1 =1;d2 =0;d3 =1;//西
		sw=(time3-s)/10;   //东西次干道_数码管十位
		gw=(time3-s)%10;   //东西次干道_数码管个位	 
		sw2=sw;		  	  //南北主干道
		gw2=gw; 		 
		display();		  //显示
		gb();			  //关闭
	}	s=0;
}
void jinji(void)//红灯全亮,其余全灭,紧急状态
{
	 //蓝   /黄   /红								
	d4 =1;d5 =1;d6 =0;//北			
	d10=1;d11=1;d12=0;//南
	d7 =1;d8 =1;d9 =0;//东
	d1 =1;d2 =1;d3 =0;//西	
}
void gb(void)//全部关闭
{
	//蓝   /黄   /红								
	d4 =1;d5 =1;d6 =1;//北			
	d10=1;d11=1;d12=1;//南
	d7 =1;d8 =1;d9 =1;//东
	d1 =1;d2 =1;d3 =1;//西 
}
void delay(uint a)	//@11.0592MHz	10ms延时(使用烧录软件生成的延时代码)
{
	for(a;a>0;a--)
  {
	unsigned char i, j;
	i = 18;
	j = 235;
	do
	{
		while (--j);	  
	} while (--i);
  }
}
void display() 		//数码管显示
{
	w1=0;			 //十位		 
	D=duan[sw];			
	delay(1);
	w1=1;
	D=0X00;										 
	w2=0;			 //个位
	D=duan[gw];
	delay(1);
	w2=1;
	D=0x00;	
	w3=0;			 //十位		 
	D=duan[sw2];			
	delay(1);
	w3=1;
	D=0X00;										 
	w4=0;			 //个位
	D=duan[gw2];
	delay(1);
	w4=1;
	D=0x00;		
}								 
void timer(void)
{
	TMOD=0X10;
	TH1=(65536-50000)/256;	  //50ms定时
	TL1=(65536-50000)%256;
	EA=1;
	ET1=1;
	TR1=1;
}
void time1(void) interrupt 3 //定时器T1中断服务程序
{			
	TH1=(65536-50000)/256;	  //50ms定时
	TL1=(65536-50000)%256;
	y++; 	
	if(y==20)
	{s++; y=0;}
}

void sm(void)//紧急状态扫描函数
{
	H1=0;					//按键另一端置0,当按键按下相当于接地,由原理图,没有按下时,通过上拉电阻拉高了
	if(key1==0)				//判断按键是否按下
	{
		delay(2);			//消抖
		while(!key1)			//松手检测	   		
		TR1=!TR1;			//关闭定时器
		while(key1==1)	    //四个方向全为红灯,进入紧急状态
		{	
			gb();
			jinji();		//打开紧急状态
			gw=gw2=sw=sw2=8;
			display();		
		}
		while(key1==0)		//松手检测
		display();	   
		TR1=1;			   //打开定时器,跳出
	}
}
void plus()
{
	H1=0;					//按键另一端置0,当按键按下相当于接地,由原理图,没有按下时,通过上拉电阻拉高了
	if(key2==0)				//判断按键是否按下
	delay(2);			//消抖
	if(key2==0)
	{
	time+=1;
	times+=1;}
	while(!key2);			//松手检测	 
}
void minus()
{
	H1=0;					//按键另一端置0,当按键按下相当于接地,由原理图,没有按下时,通过上拉电阻拉高了
	if(key3==0)				//判断按键是否按下
	delay(2);			//消抖
	if(key3==0){
	time-=1;
	times-=1;}
	while(!key3);			//松手检测	 
}
void plus2()
{
	H2=0;					//按键另一端置0,当按键按下相当于接地,由原理图,没有按下时,通过上拉电阻拉高了
	if(key2==0)				//判断按键是否按下,在这里相当于key5
	delay(2);			//消抖
	if(key2==0)
	{
	time2+=1;
	times2+=1;}
	while(!key2);			//松手检测	 
}
void minus2()
{
	H2=0;					//按键另一端置0,当按键按下相当于接地,由原理图,没有按下时,通过上拉电阻拉高了
	if(key3==0)				//判断按键是否按下,这里相当于key6
	delay(2);			//消抖
	if(key3==0){
	time2-=1;
	times2-=1;}
	while(!key3);			//松手检测	 
}


展开阅读全文

没有更多推荐了,返回首页