栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

基于51单片机的交通灯

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于51单片机的交通灯

1.控制要求

  (1) 东西南北双向红绿灯显示,红灯30s,绿灯27s,黄灯闪烁3s。

(2)夜间模式:黄灯闪烁

(3)禁行模式:一侧红灯,一侧绿灯

(4)时间调节:改变红绿灯时间

2.仿真

(1)工具:proteus

3.程序

(1)keil c51

4.程序

#include	           // 头文件
#define uchar unsigned char	   // 宏定义
#define uint unsigned int	   // 宏定义

uchar led_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴数码管字符
sbit w1=P1^0; 	 		//南北方向数码管第一位的选择标志
sbit w2=P1^1; 	    	//南北方向数码管第二位的选择标志
sbit w3=P1^2;		    //东西方向数码管第二位的选择标志
sbit w4=P1^3; 	        //东西方向数码管第二位的选择标志

sbit green1=P2^4;  	 	//南北绿灯标志
sbit yellow1=P2^5; 	 	//南北黄灯标志
sbit red1=P2^6;	  		//南北红灯标志
sbit green2=P2^1; 		//东西绿灯标志
sbit yellow2=P2^2;		//东西黄灯标志
sbit red2=P2^3;		    //东西红灯标志

sbit  k1=P3^5;			//夜间模式
sbit  k2=P3^6;			//禁行
sbit  k3=P3^4;			//方向切换
sbit  k4=P3^7;      	 //加时间
sbit  k5=P3^1;			//减时间
sbit  k6=P1^5;			//确认

char number1=30; 		//南北红灯时间	  
char number2=27;  		//南北绿灯时间  
char number3=3;			//南北黄灯时间
char number4=27;		//东西绿灯时间 
char number5=3;			//南北黄灯时间
char number6=30;		//东西红灯时间
uchar number_ns=0;		//南北方向时间
uchar number_we=0;		//东西方向时间
uchar time1=60;			//南北方向时间标志
uchar time2=60;			//东西方向时间标志
uchar i;	     		//定时器T0溢出计数
bit set=0;				//方向切换标志
void num_display(void);			//数字显示函数声明
void delay(unsigned char t1);	//声明延时函数
void led_display(void);			//LED灯显示函数声明
void key(void);					//按键函数声明

void main()	            		//主程序
{
	number_ns=number1;			 
	number_we=number4;			 //初始赋值
	TMOD=0x01;	    			//定时器T0的模式1
	TH0=0x3c;					//定时器T0初值设置,实现50ms定时
	TL0=0xb0;      			
	EA=1;						//打开总中断
	ET0=1;						//允许定时器T1中断
	TR0=1;						//启动定时器T0
	while(1)					//循环执行程序
	{
		num_display();
		led_display();
		key();
	}
}

void num_display(void)
{
	P0=led_code[number_ns/10];  	//南北方向数码管数字十位显示
	w1=0;					  		//南北位选:为0时送数据,为一时关闭,
	delay(5);
	w1=1;
	P0=led_code[number_ns%10];		//南北方向数码管显示各位
	w2=0;
	delay(5);
	w2=1;
	P0=led_code[number_we/10];     //东西方向数码管显示个位
	w3=0;					  	   //东西方向位选
	delay(5);
	w3=1;
	P0=led_code[number_we%10];	   //东西方向数码管数字个位显示
	w4=0;
	delay(5);
	w4=1;
}

void led_display(void)
{
	if(time1>(60-number1)) 			//	南北红灯阶段
	{
		yellow1=0;
		green1=0;
		red1=1;
	}
	if((time1<(60-number1)||time1==(60-number1))&&(time1>3))		//南北绿灯阶段
	{
		red1=0;
		yellow1=0;
		green1=1;
	}
	if(time1<3||time1==3)		//南北方向黄灯阶段
	{
		green1=0;
		if(i==5||i==15)
		yellow1=1;
		if(i==10||i==20)
		yellow1=0;
	}
   if(time2>(60-number4))		//东西方向绿灯阶段
	{
		yellow2=0;
		green2=1;
		red2=0;
	}
	if((time2<(60-number4)||time2==(60-number4))&&(time2>number6))		 //东西方向黄灯阶段
	{
		green2=0;
		if(i==5||i==15)
		yellow2=1;
		if(i==10||i==20)
		yellow2=0;
	}
	if(time2<(number6)||time2==number6)			//东西方向红灯阶段
	{
		red2=1;
		yellow2=0;
		green2=0;
	}

}

void times() interrupt 1
{
	TH0=0x3c;					//定时器T0初值设置,实现50ms定时
	TL0=0xb0;
	i++;		
	if(i==20)					//定时1S完成
	{
		i=0;					//清空标志
		number_ns--;			//南北数字减一
		number_we--;			//东西数字减一
		time1--;				
		time2--;				//转换标志同步自减
		if(time1==(60-number1))	//南北红灯时间结束
		number_ns=number2;		//赋绿灯时间
		if(time1==3)
		number_ns=number3;		//绿灯时间赋黄灯时间
		if(time1==60)
		number_ns=number1;		//初始赋红灯时间
		if(time1==0)			//循环结束重新赋值
		{
			time1=60;
			number_ns=number1;
		}
		if(time2==(60-number4))	//东西绿灯时间结束
		number_we=number5;		//赋黄灯时间
		if(time2==57-number4)	//黄灯时间结束赋绿灯时间
		number_we=number6;
		if(time2==60)			//初始赋绿灯时间
		number_we=number4;
		if(time2==0)		   //重新赋值
		{
			time2=60;
			number_we=number4;
		}
	}
}

void key(void)
{
	if(k1==0)	  				//当夜间模式按键按下
	delay(100);					//消抖
	if(k1==0)
	{
		while(k1==1);		   //松手检测
		while(1)			   //循环执行黄灯闪烁与数码管置0
		{
			red1=0;
			red2=0;
			green1=0;
			green2=0;
			if(i==5||i==15)	  // 黄灯闪烁
			{
				yellow2=1;
				yellow1=1;
			}
			if(i==10||i==20)
			{
				yellow2=0;
				yellow1=0;
			}
			P0=led_code[0];   //数码管显示0
			w1=0;					  
			delay(5);
			w1=1;
			P0=led_code[0];
			w2=0;
			delay(5);
			w2=1;
			P0=led_code[0];   
			w3=0;					  
			delay(5);
			w3=1;
			P0=led_code[0];
			w4=0;
			delay(5);
			w4=1;
		}
	}
	if(k2==0);					  // 当单向禁行按键被按下
	delay(100);					  // 消抖
	if(k2==0)					 
	{
		while(k2==1);			  //松手检测
		while(1)
		{
			P0=led_code[0];   	 //数码管显示0
			w1=0;					  
			delay(5);
			w1=1;
			P0=led_code[0];
			w2=0;
			delay(5);
			w2=1;
			P0=led_code[0];   
			w3=0;					  
			delay(5);
			w3=1;
			P0=led_code[0];
			w4=0;
			delay(5);
			w4=1;
			if(k3==0)				 //切换按键按下
			delay(100);
			if(k3==0)
			{
				while(k3==0);
				set=~set;			//切换标志取反,方向切换
			}
			if(set==0)				//切换标志为0时,南北禁行
			{
				red1=1;
				red2=0;
				green1=0;
				green2=1;
				yellow1=0;
				yellow2=0;
			}
			if(set==1)				//切换标志为1时,东西禁行
			{
				red1=0;
				red2=1;
				green1=1;
				green2=0;
				yellow1=0;
				yellow2=0;
			}
		}
	}
	if(k4==0)					  //时间加按键按下
	delay(100);					  //消抖
	if(k4==0)
	{
		TR0=0;
		number1++;	  //南北红灯加
		number2--;	  //南北绿灯减
		number4++;	  //东西绿灯加
		number6--;	  //东西绿灯减
	    number_ns=number1;		   //赋入改变后的值
		number_we=number4;
		while(k4==1);			 //松手监测
		while(1)
		{
			P0=led_code[number1/10];   //显示南北调节的数字
			w1=0;					  
			delay(5);
			w1=1;
			P0=led_code[number1%10];
			w2=0;
			delay(5);
			w2=1;
			P0=led_code[number4/10];   	 //显示东西调节的数字
			w3=0;					  
			delay(5);
			w3=1;
			P0=led_code[number4%10];
			w4=0;
			delay(5);
			w4=1;
			if(k4==1)
			break;
		}
	}
	if(k5==0)					// 当减时间按键按下
	delay(100);					// 消抖
	if(k5==0)					
	{
		TR0=0;
		number1--;				// 南北红灯时间减
		number2++;				// 南北绿灯时间加
		number4--;				// 东西绿灯时间减
		number6++;				// 东西红灯时间加
		number_ns=number1;		// 赋入改变后的值
		number_we=number4;
	   	while(k5==1);			//松手检测
		while(1)
		{
			P0=led_code[number1/10];   	   // 显示南北方向调节中的值
			w1=0;					  
			delay(5);
			w1=1;
			P0=led_code[number1%10];	   
			w2=0;						   
			delay(5);
			w2=1;
			P0=led_code[number4/10];   	   // 显示东西方向调节中的值
			w3=0;					  
			delay(5);
			w3=1;
			P0=led_code[number4%10];	  
			w4=0;
			delay(5);
			w4=1;
			if(k5==1)
			break;						   //跳出死循环
		}
			
	}									   
	if(k6==0)							   //确认键被按下
	delay(100);							   //消抖
	if(k6==0)
	{
		while(k6==1);					   //松手检测
		TR0=1;							   //开定时器
		number_ns=number1;				   //赋改变后的值
		number_we=number4;
	}

}
	
void delay(uchar t1)	    //延时函数,约1ms延时
{
	uchar i,j;
	for(i=5;i>t1;i--)
		for(j=200;j>0;j--);
}




5.仿真图

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1000964.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号