51单片机——交通灯

原理图

在这里插入图片描述

功能描述

  1、基本功能就是如同红绿灯一般,不做赘述。
  2、红灯时长和绿灯时长可通过按键设置,即按键列中的上面4个,当这4个按键有一个按下后便进入时长设置功能,设置完成后按最下面两个按键(紧急控制按钮)任意一个便可退出该功能。
  3、有紧急控制功能,按下紧急控制按钮后,便进入该功能,保持红灯或绿灯常亮,且关闭数码管,当按下时长控制按钮即最上面的4个按钮便可退出该功能。

效果展示

在这里插入图片描述

代码

#include <reg52.h>//数码管选择位
sbit EW_1=P1^0;		   
sbit EW_2=P1^1;
sbit NS_1=P1^2;		   
sbit NS_2=P1^3;sbit add_red_time=P1^4;		   		//加红灯时间按钮
sbit add_green_time=P1^5;	   		//加绿灯时间按钮
sbit reduce_red_time=P1^6;		   	//减红灯时间按钮
sbit reduce_green_time=P1^7;	   	//减绿灯时间按钮
sbit NS_led=P2^6;	   				//南北向灯紧急控制按钮
sbit EW_led=P2^7;	   				//东西向灯紧急控制按钮sbit EW_red=P2^0;	   				//东西向红灯
sbit EW_green=P2^1;	   				//东西向绿灯
sbit EW_yellow=P2^2;	   		    //东西向黄灯
sbit NS_red=P2^3;	   				//南北向红灯
sbit NS_green=P2^4;	   				//南北向绿灯
sbit NS_yellow=P2^5;	   			//南北向黄灯char count=0;						//计数,count=20表示1s
char red_time=30;					//红灯停留时间
char green_time=25;					//绿灯停留时间
char yellow_time=0;					//黄灯停留时间
char NS_second=0;					//南北红绿灯秒计时
char EW_second=0;		    		//东西红绿灯秒计时
char code smgduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};		//共阳数码管段码表,仿真中用的是共阴数码管,所以使用时需对段码取反
char display_data[4]={0};			//show_data[0]显示南北计时十位,show_data[1]显示南北计时个位,show_data[2]显示东西计时十位,show_data[3]显示东西计时个位
char temp_data[4]={0};char NS_R_G_mode=0;					//南北红绿灯亮模式  0  红灯  1  绿灯  2  黄灯
char EW_R_G_mode=1;					//东西红绿灯亮模式  0  红灯  1  绿灯  2  黄灯bit NS_R_G_flag=0;					//南北红绿灯标识位  0  红灯  1  绿灯 
bit EW_R_G_flag=0;					//东西红绿灯标识位  0  红灯  1  绿灯 void delay(unsigned int i)			//简单延时
{while(i--);
}void Timer_init()					//定时器初始化
{//定时50msTMOD = 0x01;					//定时器方式1TH0 = 0x3C;						//定时器赋初值TL0 = 0xB0;EA = 1;							//开启总中断ET0 = 1;						//开启定时器中断TR0 = 1;						//开启定时器
}void Init()							//系统初始化
{P0=0x00;P2=0x00;EW_1=1;		   EW_2=1;NS_1=1;NS_2=1;NS_led=1;EW_led=1;NS_second=red_time;				//默认初始时南北向灯亮红灯,并赋红灯时长EW_second=green_time;			//默认初始时东西向灯亮绿灯,并赋绿灯时长yellow_time=red_time-green_time;//黄灯时间为红灯时间与绿灯时间差Timer_init();
}void NS_SMG_drive(char *buff)		//南北向数码管驱动
{//显示十位NS_1=0;NS_2=1;P0=~smgduan[buff[0]];           //段码取反delay(5); 						//间隔一段时间扫描	P0=0x00;						//消隐//显示个位NS_1=1;NS_2=0;P0=~smgduan[buff[1]];delay(5); P0=0x00;//关闭南北向数码管NS_1=1;NS_2=1;
}void EW_SMG_drive(char *buff)		//东西向数码管驱动
{//显示十位EW_1=0;EW_2=1;P0=~smgduan[buff[2]];           //段码取反delay(5); 						//间隔一段时间扫描	P0=0x00;						//消隐//显示个位EW_1=1;EW_2=0;P0=~smgduan[buff[3]];delay(5); 	P0=0x00;//关闭东西向数码管EW_1=1;		   EW_2=1;
}void data_del(char *buff,char data1,char data2)	//数据处理
{buff[0]=data1/10;							//取data1的十位buff[1]=data1%10;							//取data1的个位buff[2]=data2/10;							//取data2的十位buff[3]=data2%10;							//取data2的个位
}void Time_del()									//计时处理
{if(count>=20)								//判断是否满1s{NS_second--;							//南北向灯计时自减EW_second--;							//东北向灯计时自减switch(NS_R_G_mode)						//南北向灯{case 0:								//红灯{if(NS_second<0){NS_second=green_time;		//开始绿灯倒计时NS_R_G_mode=1;   			//红灯亮完绿灯亮}				}break;case 1:								//绿灯{if(NS_second<0){NS_second=yellow_time;		//开始黄灯倒计时NS_R_G_mode=2;   			//绿灯亮完黄灯亮					}		}break;case 2:								//黄灯{if(NS_second<0){NS_second=red_time;			//开始红灯到计时NS_R_G_mode=0;   			//黄灯亮完红灯亮					}		}break;default:break;}switch(EW_R_G_mode)						//东西向灯{case 0:								//红灯{if(EW_second<0){EW_second=green_time;		//开始绿灯倒计时EW_R_G_mode=1;   			//红灯亮完绿灯亮}				}break;case 1:								//绿灯{if(EW_second<0){EW_second=yellow_time;		//开始黄灯倒计时EW_R_G_mode=2;   			//绿灯亮完黄灯亮					}		}break;case 2:								//黄灯{if(EW_second<0){EW_second=red_time;			//开始红灯倒计时EW_R_G_mode=0;   			//黄灯亮完红灯亮					}		}break;default:break;}count=0;								//计数值清零}
}void R_G_Y_led()								//红绿灯驱动
{switch(NS_R_G_mode)							//南北向{case 0:									//红灯{NS_yellow=0;						//黄灯灭NS_red=1;							//红灯亮}break;case 1:									//绿灯{NS_red=0;							//红灯灭NS_green=1;							//绿灯亮}break;case 2:									//黄灯{NS_green=0;							//绿灯灭if(count<10)						//黄灯以1hz频率闪烁NS_yellow=1;elseNS_yellow=0;			}break;default:break;		}switch(EW_R_G_mode)							//东西向{case 0:									//红灯{EW_yellow=0;						//黄灯灭EW_red=1;							//红灯亮}break;case 1:									//绿灯{EW_red=0;							//红灯灭EW_green=1;							//绿灯亮}break;case 2:									//黄灯{EW_green=0;							//绿灯灭if(count<10)						//黄灯以1hz频率闪烁EW_yellow=1;elseEW_yellow=0;			}break;default:break;		}
}void Set_time()									//设置红绿灯亮的时长
{if((add_red_time==0)||(add_green_time==0)||(reduce_red_time==0)||(reduce_green_time==0))//设置红绿灯时长时任一设置按钮都可触发{TR0 = 0;								//关闭定时器P2=0x00;								//清零P2寄存器EW_led=1;								//EW_led、NS_led引脚也在P2寄存器内,但是后面需要这两个按钮结束设置红绿灯时长任务,故而这两个引脚要拉高NS_led=1;while(1){data_del(temp_data,red_time,green_time);//显示当前红绿灯时长NS_SMG_drive(temp_data);EW_SMG_drive(temp_data);if(add_red_time==0)					//判断加红灯时间按钮是否按下{delay(5);						//消抖if(add_red_time==0){red_time++;					//红灯时间自加if(red_time>99)				//限制红灯时间最大值为99red_time=99;data_del(temp_data,red_time,red_time);//南北向数码管显示红灯时长NS_SMG_drive(temp_data);}while(!add_red_time);			//等待加红灯时间按钮弹起}if(add_green_time==0)				//判断加绿灯时间按钮是否按下{delay(5);if(add_green_time==0){green_time++;				//绿灯时间自加if(green_time>95)			//限制绿灯时间最大值95green_time=95;data_del(temp_data,green_time,green_time);//东西向数码管显示绿灯时长EW_SMG_drive(temp_data);}while(!add_green_time);		//等待加绿灯时间按钮弹起}if(reduce_red_time==0)				//判断减红灯时间按钮是否按下{delay(5);if(reduce_red_time==0){red_time--;					//红灯时间自减if(red_time<10)				//限制红灯时间最小值10red_time=10;data_del(temp_data,red_time,red_time);NS_SMG_drive(temp_data);}while(!reduce_red_time);		//等待减红灯时间按钮弹起}if(reduce_green_time==0)			//判断减绿灯时间按钮是否按下{delay(5);if(reduce_green_time==0){green_time--;				//绿灯时间自减if(green_time<5)			//限制绿灯时间最小值5green_time=5;data_del(temp_data,green_time,green_time);EW_SMG_drive(temp_data);}while(!reduce_green_time);		//等待减绿灯时间按钮弹起}if((NS_led==0)||(EW_led==0))		//任一紧急控制按钮按下则结束设置红路灯时长任务{break;}}while((!NS_led)||(!EW_led));			//等待紧急控制按钮弹起TR0 = 1;								//开启定时器yellow_time=red_time-green_time;		//更新黄灯时间}
}void Urgent()									//红绿灯紧急控制
{if((NS_led==0)||(EW_led==0))				//任一紧急控制按钮按下触发{TR0 = 0;								//关闭定时器P2=0x00;EW_led=1;NS_led=1;EW_1=1;									//关闭所有数码管EW_2=1;NS_1=1;NS_2=1;while((!NS_led)||(!EW_led));			//判断紧急控制按钮按是否弹起while(1){if(NS_R_G_flag)						//根据NS_R_G_flag状态交替亮红灯或者绿灯{NS_green=1;	NS_red=0;					}	else{NS_red=1;	NS_green=0;				}if(EW_R_G_flag)						//根据EW_R_G_flag状态交替亮红灯或者绿灯{EW_green=1;	EW_red=0;									}else{EW_red=1;EW_green=0;						}	if(NS_led==0)						//判断南北向紧急控制按钮是否按下{delay(5);if(NS_led==0){NS_R_G_flag=!NS_R_G_flag;	//NS_R_G_flag状态取反				}while(!NS_led);				//等待南北向紧急控制按钮弹起}if(EW_led==0)						//判断东西向紧急控制按钮是否按下{delay(5);if(EW_led==0){EW_R_G_flag=!EW_R_G_flag;	//EW_R_G_flag状态取反						}while(!EW_led);				//等待东西向紧急控制按钮弹起}	if((add_red_time==0)||(add_green_time==0)||(reduce_red_time==0)||(reduce_green_time==0))//任一红绿灯设置时长按钮按下结束紧急控制人物{TR0 = 1;						//开启定时器break;}}while((!add_red_time)||(!add_green_time)||(!reduce_red_time)||(!reduce_green_time));//等待红绿灯时间设置按钮弹起	P2=0x00;EW_led=1;NS_led=1;}
}void main()
{Init();while(1){Time_del();								//时间处理data_del(display_data,NS_second,EW_second);//数据处理NS_SMG_drive(display_data);				//南北向数码管驱动EW_SMG_drive(display_data);				//东西向数码管驱动R_G_Y_led();							//红绿灯驱动Set_time();								//红绿灯时长设置Urgent();								//紧急控制}
}void Timer0(void) interrupt 1					//定时器中断
{TH0 = 0x3C;TL0 = 0xB0;count++;									//触发中断后计数值自加,定时器中断每50ms触发一次
}

工程下载

链接:https://pan.baidu.com/s/1P0Gj6PmNfffJdsEe5j6JGA
提取码:0yzj

由于后续发现了些小问题,程序有所修改,网盘中的代码由于一些原因暂时不能更新,以本篇博客为准。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/545584.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设置TextField内文字距左边框的距离

2019独角兽企业重金招聘Python工程师标准>>> //设置文本框左边的viewUITextField *textField [[UITextField alloc]init];textField.frame CGRectMake(10, 30, 300, 30);[self.view addSubview:textField];textField.leftView [[UIView alloc]initWithFrame:CGRe…

Oracle注册表修改 乱码编码

HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0"NLS_LANG"值改为"SIMPLIFIED CHINESE_CHINA.ZHS16GBK"AMERICAN.AL32UTF8乱码更改oracle 10g装上后,建了个表写入中文数据,发现通过工具DbVisualizer 6.5 写入/读取中文都正常,就sqlplus和PL/SQL Developer不正常…

设计模式常见面试题汇总

1.说一下设计模式?你都知道哪些? 答:设计模式总共有 23 种,总体来说可以分为三大类:创建型模式( Creational Patterns )、结构型模式( Structural Patterns )和行为型模式( Behavioral Patterns )。 分类包含关注点创建型模式工厂模式、抽象工厂模式、单例模式、建…

java 根据类名示例化类_Java LocalDateTime类| minusMinutes()方法与示例

java 根据类名示例化类LocalDateTime类minusMinutes()方法 (LocalDateTime Class minusMinutes() method) minusMinutes() method is available in java.time package. minusMinutes()方法在java.time包中可用。 minusMinutes() method is used to subtract the given minutes …

类的三大特性

类有三大特性&#xff1a;继承&#xff0c;封装&#xff0c;多态&#xff0c;这个也是介绍类的时候&#xff0c;必须提到的话题&#xff0c;那么今天就来看一下OC中类的三大特性&#xff1a; 一、封装 学习过Java中类的同学可能都知道了&#xff0c;封装就是对类中的一些字段&a…

JVM 面试题汇总

1.什么是 JVM?它有什么作用? 答:JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,顾名思义它是一个虚拟计算机,也是 Java 程序能够实现跨平台的基础。它的作用是加载 Java 程序,把字节码翻译成机器码再交由 CPU 执行的一个虚拟计算器。 2.JVM 主要组成部分有哪些? …

Java BigInteger类| isProbablePrime()方法与示例

BigInteger类isProbablePrime()方法 (BigInteger Class isProbablePrime() method) isProbablePrime() method is available in java.math package. isProbablePrime()方法在java.math包中可用。 isProbablePrime() method is used to check whether this BigInteger is probab…

20141215胡思乱想

书读得越多&#xff0c;越发现自己无知。 我们的就像在一个空白的圆里面&#xff0c;周围都是黑暗&#xff0c;不断成长&#xff0c;圆会越来越大&#xff0c;接触到的黑暗会越多。所以要时刻保持谦逊。 Stay Hungry, Stay Foolish!! 时刻要思考&#xff0c;不要急于求成。 转载…

常见面试题翻车合集

1.去掉 main 方法的 static 修饰符,程序会怎样? A:程序无法编译 B:程序正常编译,正常运行 C:程序正常编译,正常运行一下马上退出 D:程序正常编译,运行时报错 答:D 题目解析:运行时异常如下: 错误: main 方法不是类 xxx 中的 static, 请将 main 方法定义为: p…

c语言i++和++i程序_使用C ++程序从链接列表中消除重复项

c语言i和i程序Given a sorted linked list (elements are sorted in ascending order). Eliminate duplicates from the given LL, such that output LL contains only unique elements. 给定一个排序的链表(元素按升序排序)。 从给定的LL中消除重复项&#xff0c;以便输出LL仅…

struts的开发模式

<constant name"struts.devMode" value"true" /> struts.devMode也就是struts的开发模式&#xff0c;默认值为false&#xff0c;这里修改为true就可以了&#xff0c;以后一旦就该这个文件中的配置就不用去重启tomcat。struts2.1的bug&#xff0c;tom…

nginx启动与停止

转自&#xff1a;http://www.nginx.cn/nginxchscommandline#commandnginx启动sudo /usr/local/nginx/nginx (nginx二进制文件绝对路径&#xff0c;可以根据自己安装路径实际决定)nginx从容停止命令&#xff0c;等所有请求结束后关闭服务ps -ef |grep nginxPID PPID USER …

编程c语言 十进制转八进制_使用C编程语言处理八进制值

编程c语言 十进制转八进制Octal value has 8 digit values from 0 to 7, with the base 8. (Read more about Computer number systems), here we will learn how to work with octal values in c programming language? 八进制值具有从0到7的8位数字&#xff0c;以8为底。(阅…

加餐 | Java 面试通关攻略

面试分为三个重要的阶段: 面试前准备面试中表现面试后复盘做好这三个阶段的准备,相信一定会有很大的收获。下面来分别看看这三个阶段需要准备哪些内容。 一. 面试前准备 1. 研究待面试的公司 所谓知己知彼方能百战不殆,对待面试同样如此,企业希望招聘的人能够直接上手工…

java中_null和“”的区别详解

null和""的区别 问题一&#xff1a; null和""的区别 String snull; string.trim()就会抛出为空的exception String s""; string.trim()就不会抛,为什么? 答&#xff1a; NULL代表声明了一个空对象&#xff0c;根本就不是一个字符串。 …

结语|日拱一卒无有尽,功不唐捐终入海

到今天为止,我们已经共同阅读了 40 篇文章,共计 13 万字、505 道面试题,这些面试题由浅入深,系统地把 Java 面试中,可能遇到的所有知识点都囊括了。这个系列的面试课程,也汇聚了我作为面试官这 4 年的经验,同时为了写好这门课程,我联系了 20 多个面试官朋友,只为给大家…

Android学习—Notification消息通知

最近在项目中需要使用消息通知&#xff0c;自己把它封装成了一个方法&#xff0c;需要的时候方便调用&#xff0c;下面对Notification类中的一些常量&#xff0c;字段&#xff0c;方法简单介绍一下&#xff1a;常量&#xff1a;DEFAULT_ALL 使用所有默认值&#xff0c;比如声…

手机子王掩码和网关查找_C程序使用位掩码查找奇数或偶数

手机子王掩码和网关查找Problem statement: Write a C program to find odd or even no using bitwise operators. 问题陈述&#xff1a;编写一个C程序以使用按位运算符查找奇数或什至无 。 Solution: We can use bitwise operator here to solve the problem. 解决方案&#…

struts处理中文乱码问题总结

乱码中有三种情况&#xff1a;㈠页面显示中文乱码 ㈡传递参数中文乱码 ㈢国际化资源文件乱码 详细摘出&#xff1a;传递参数中文乱码 传递参数出现的乱码&#xff0c;参数的内容为中文。比如在struts应用中&#xff0c;简单的一个登录界面中&#xff0c;需要传递的登录名为中文…

第 6-5 课:MyBatis 核心和面试题(下)

MyBatis 最初的设计是基于 XML 配置文件的,但随着 Java 的发展(Java 1.5 开始引入注解)和 MyBatis 自身的迭代升级,终于在 MyBatis 3 之后就开始支持基于注解的开发了。 下面我们使用 Spring Boot + MyBatis 注解的方式,来实现对数据库的基本操作,具体实现步骤如下。 M…