单片机仿真软件红绿灯功能

功能一:东西方向、南北方向均有红、黄、绿三种信号灯,初始红灯20秒,黄灯闪烁3秒,绿灯10秒东西方向红灯时刻,南北方向绿灯,南北方向绿灯,东西方向红灯。(时间为标准秒数,信号灯切换顺序为绿黄红) (4分)

功能二:设置夜间模式按钮,按钮按下,所有方向显示黄灯闪烁 

功能三:通过按键调节整体时间,第一个按键按下每种灯的持续时间增加一秒,第二个按键按下每种灯的持续时间减小一秒。(按键需要灵敏快速反应)

功能四:使用2位数码管实时提醒灯亮的剩余时间 

功能五:分时控制单路红绿灯,在40秒内,0-10秒为北面红绿灯通行,10-20秒内为东面红绿灯通行,20-30s内为南面红绿灯通行,30-40秒内为西面红绿灯通行。

#include <REGX52.H>
#include "Timer0.h"
#include "Key.h"
#include <INTRINS.H>
#include "Delay.h"
#include "Nixie.h"
sbit N_R=P1^0;              // 东西南北红绿黄灯定义
sbit N_Y=P1^1; 
sbit N_G=P1^2;
sbit S_R=P1^3;
sbit S_Y=P1^4; 
sbit S_G=P1^5;
sbit W_R=P2^0;
sbit W_Y=P2^1; 
sbit W_G=P2^2;
sbit E_R=P2^3;
sbit E_Y=P2^4; 
sbit E_G=P2^5;
sbit K1=P3^0;				// 按键定义
sbit K2=P3^1;
sbit K3=P3^2;
sbit K4=P3^3;
sbit E_Tube1=P3^4;          //东西南北数码管管脚定义
sbit E_Tube2=P3^5;
sbit S_Tube1=P3^6;
sbit S_Tube2=P3^7;
sbit N_Tube1=P1^6;
sbit N_Tube2=P1^7;
sbit W_Tube1=P2^6;
sbit W_Tube2=P2^7;
int flag_1=10000;            //旗帜用来标记进行红绿灯切换
int flag_2=3000;
int flag_3=7000;
int flag_4=3000;
int flag=0;
int Y_flag=0;                //黄灯闪烁
int Count=0;
int Compare=0;               //对比值
int Change=0;                //也是个旗帜
int Change_4=0;              //功能4旗帜
int Compare_4=10000;         //功能4时间定义
int symbol=0;                //记号
int KeyNum=0;
int a,b;
int C_1=0;                   //数码管显示管脚
int C_2=0;
int N_C1=0;
int N_C2=0;
int E_C1=0;
int E_C2=0;
int S_C1=0;
int S_C2=0;
int W_C1=0;
int W_C2=0;
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40};
void Nixie(unsigned char Location,Number)
{
	switch(Location)		//位码输出
	{
		case 1: 
		N_Tube1=S_Tube1=W_Tube1=E_Tube1=1;          //公用管脚
		N_Tube2=S_Tube2=W_Tube2=E_Tube2=0;
		break;
		case 2:
		N_Tube2=S_Tube2=W_Tube2=E_Tube2=1;          //公用管脚
		N_Tube1=S_Tube1=W_Tube1=E_Tube1=0;
		break;
		case 3:                                     //东南西北管脚控制
		N_Tube1=1;
		N_Tube2=S_Tube2=W_Tube2=E_Tube2=0;
		break;
		case 4:
		N_Tube1=0;
		N_Tube2=1;	
		break;
		case 5:
		E_Tube1=1;
		N_Tube2=S_Tube2=W_Tube2=E_Tube2=0;
		break;
		case 6:
		E_Tube1=0;
		E_Tube2=1;		
		break;
		case 7:
		S_Tube1=1;	
		N_Tube2=S_Tube2=W_Tube2=E_Tube2=0;
		break;
		case 8:
		S_Tube1=0;	
		S_Tube2=1;
		break;
		case 9:
		W_Tube1=1;
		N_Tube2=S_Tube2=W_Tube2=E_Tube2=0;
		break;
		case 10:
		W_Tube1=0;
		W_Tube2=1;
		break;
	}
	P0=~NixieTable[Number];	//段码输出
	Delay(1);				//显示一段时间
	P0=~0x00;				//段码清0,消影
}
void Key()
{
	if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNum=1;}       //按键检测
	if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNum=2;}
	if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNum=3;}
	if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNum=4;}
}
void main()
{
N_Tube1=S_Tube1=W_Tube1=E_Tube1=N_Tube2=S_Tube2=W_Tube2=E_Tube2=0;  //初始化
N_R=S_R=W_R=E_R=N_Y=S_Y=W_Y=E_Y=N_G=S_G=W_G=E_G=0;
while(1){
Key();	
N_R=S_R=W_R=E_R=N_Y=S_Y=W_Y=E_Y=N_G=S_G=W_G=E_G=0;
while(KeyNum==0)
		{
		Timer0Init();
		Nixie(1,a);
		Nixie(2,b);
		Key();
		if(Change==0){            //通过flag和Change相互照应用计时器达到切换效果
		Compare=flag_1;			  //Delay函数行动缓慢弃之
		flag=1;
		N_R=S_R=W_G=E_G=1;
		}
		if(Change==1){		
		Compare=flag_2;
		flag=2;
		N_Y=S_Y=W_Y=E_Y=1;
		}
		if(Change==2){
		Compare=flag_3;
		flag=3;	
		N_G=S_G=W_R=E_R=1;	
		}
		if(Change==3){		
		Compare=flag_4;
		flag=4;
		N_Y=S_Y=W_Y=E_Y=1;
		}
	    }
switch(KeyNum)
{

		break;
	case 1:
		flag_1+=1000;                         //功能1 按下按键所有时间+1s
		flag_2+=1000;
		flag_3+=1000;
		flag_4+=1000;
		KeyNum=0;
	break;
	case 2:
		if(flag_1>1020){flag_1-=1000;}        //功能2 按下按键所有时间-1s
		if(flag_2>1020){flag_2-=1000;}        //边界处理,防止出现负数的情况,1020是让显示更灵敏以防闪烁
		if(flag_3>1020){flag_3-=1000;}
		if(flag_4>1020){flag_4-=1000;}
		KeyNum=0;
	break;
	case 3:
		N_R=S_R=W_R=E_R=N_Y=S_Y=W_Y=E_Y=N_G=S_G=W_G=E_G=0;	
		while(KeyNum==3)                      //功能3 按下按键 黄灯闪烁
	{	Nixie(1,10);                          //数码管显示 - -
		Nixie(2,10);	
		Key();
		if(Y_flag==1)                         //旗帜,用来标记原理跟第一题一样
		{
		N_Y=S_Y=W_Y=E_Y=1;
		}
		if(Y_flag==0)
		{
		N_Y=S_Y=W_Y=E_Y=0;
		}
	}
	break;
	case 4:
	N_R=S_R=W_R=E_R=N_Y=S_Y=W_Y=E_Y=N_G=S_G=W_G=E_G=0;
	Timer0Init();
	while(KeyNum==4)
		{
		N_Tube2=S_Tube2=W_Tube2=E_Tube2=C_2;           //到所有数码管个位都一样,所以管脚设置统一
		if(symbol==1)
		{
		N_C1=C_1;
		N_C2=C_2;
		E_C1=C_1;
		S_C1=C_1+1;                                    //用symbol标记,轮流计时,达到转圈圈的效果,防止错乱
		W_C1=C_1+2;			                           //四种情况依次考虑
		}
		if(symbol==2)
		{
		N_C1=C_1+2;
		E_C1=C_1;
		S_C1=C_1;
		W_C1=C_1+1;	
		}
		if(symbol==3)
		{
		N_C1=C_1+1;
		E_C1=C_1+2;
		S_C1=C_1;
		W_C1=C_1;		
		}
		if(symbol==4)
		{
		N_C1=C_1;
		E_C1=C_1+1;
		S_C1=C_1+2;
		W_C1=C_1;	
		}
		Nixie(3,N_C1);                             //控制显示,交替进行防止错乱
		Nixie(2,C_2);
		Nixie(5,E_C1);
		Nixie(2,C_2);
		Nixie(7,S_C1);
		Nixie(2,C_2);
		Nixie(9,W_C1);
		Nixie(2,C_2);
		Key();
		
		if(Change_4==0){                            //亮灯处理与功能一相似
		symbol=1;
		N_G=S_R=W_R=E_R=1;
		}
		if(Change_4==1){		
		symbol=2;
		E_G=W_R=N_R=S_R=1;
		}
		if(Change_4==2){
		symbol=3;
		S_G=N_R=W_R=E_R=1;	
		}
		if(Change_4==3){		
		symbol=4;
		W_G=N_R=S_R=E_R=1;
		}
	    }
	break;		
}
}
}
void Timer0_Routine() interrupt 1                      //定时器部分
{
	static unsigned int Count;
	
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	Count++;		//T0Count计次,对中断频率进行分频
	a=(Compare-Count+999)/10000;                       //+999为了显示多一秒防止一开始出现数码管跳动
	b=((Compare-Count+999)/1000)%10;                   //a得到十位,b得到个位
	C_1=(Compare_4-Count+999)/10000;                   //同理
	C_2=((Compare_4-Count+999)/1000)%10;
	if(KeyNum==0)
	{
	if(Count>=Compare)
	{   	
		Count=0;
		if(flag==1){                                   //旗帜照应flag<-->change,实现灯的变换
		Count=0;
		N_R=S_R=W_R=E_R=N_Y=S_Y=W_Y=E_Y=N_G=S_G=W_G=E_G=0;
		Change=1;		
		}
		if(flag==2){
		Count=0;
		N_R=S_R=W_R=E_R=N_Y=S_Y=W_Y=E_Y=N_G=S_G=W_G=E_G=0;
		Change=2;
		}
		if(flag==3){
		Count=0;
		N_R=S_R=W_R=E_R=N_Y=S_Y=W_Y=E_Y=N_G=S_G=W_G=E_G=0;
		Change=3;
		}
		if(flag==4){
		Count=0;
		N_R=S_R=W_R=E_R=N_Y=S_Y=W_Y=E_Y=N_G=S_G=W_G=E_G=0;
		Change=0;
		}
	EA=1;
	}
	//             功能3
	
	}
	if(KeyNum==3)                         //黄灯闪烁间隔0.3秒频率刚刚好
	{	
	if(Count<300)
	{Y_flag=1;}
	if(Count>300&&Count<600)
	{Y_flag=0;}
	if(Count>600){Count=0;}
	}
	
	//             功能4
	if(KeyNum==4)
	{
	if(Count>=Compare_4)//MOD 1
	{
		Count=0;
		if(symbol==1){                           //symbol<-->Change_4相互照应
		Count=0;
		N_R=S_R=W_R=E_R=N_Y=S_Y=W_Y=E_Y=N_G=S_G=W_G=E_G=0;
		Change_4=1;		
		}
		if(symbol==2){
		Count=0;
		N_R=S_R=W_R=E_R=N_Y=S_Y=W_Y=E_Y=N_G=S_G=W_G=E_G=0;
		Change_4=2;
		}
		if(symbol==3){
		Count=0;
		N_R=S_R=W_R=E_R=N_Y=S_Y=W_Y=E_Y=N_G=S_G=W_G=E_G=0;
		Change_4=3;
		}
		if(symbol==4){
		Count=0;
		N_R=S_R=W_R=E_R=N_Y=S_Y=W_Y=E_Y=N_G=S_G=W_G=E_G=0;
		Change_4=0;
		}
		}
		}
}

挺复杂的,缺点是数码管有时候会卡顿。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
摘 要:近年来随着科技的飞速发展,单片机的应用正在不断深入,同时带动传统控制检测技术日益更新。在实时检测和自动控制的单片机应用系统中,单片机往往作为一个核心部件来使用,仅单片机方面知识是不够的,还应根据具体硬件结构软硬件结合,加以完善。十字路口车辆穿梭,行人熙攘,车行车道,人行人道,有条不紊。那么靠什么来实现这井然秩序呢?靠的就是交通信号灯的自动指挥系统。交通信号灯控制方式很多。本系统采用MSC-51系列单片机ATSC51和可编程并行I/O接口芯片8255A为中心器件来设计交通灯控制器,实现了能根据实际车流量通过8051芯片的P1口设置红、绿灯燃亮时间的功能。 关键词:单片机 交通灯 车流量 控制 Abstract:With the development of science and technology in recent years,the application of SCM is deepening in the same time promote more traditional control detection update.In real-time detection and control of the microcomputer application system,the microcontroller is often a core component to use,only SCM knowledge is not enough,also according to the specific combination of hardware,software and hardware structure ,to be improved.Crossroads shuttle vehicles,cars,buses and people walkways,orderly.What rely on to achieve the discipline of the order then? By automatic traffic lights is the chain of command control traffic lights.In this system,MSC-51 Series ATSC51 and programmable parallel I/O interface chip 8255A-centered design of traffic signal controller device to realize the actual traffic volume by 8051 according to the P1 port chip set of red,green time kindle function. Key words: microcontroller traffic light traffic flow control

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值