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…

类的三大特性

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

操作系统抢占式优先级调度_操作系统中的优先级调度(非抢先)

操作系统抢占式优先级调度Priority scheduling is a type of scheduling algorithm used by the operating system to schedule the processes for execution. The priority scheduling has both the preemptive mode of scheduling and the non-preemptive mode of scheduling…

数据结构pta选择判断复习

第一章绪论 1-3数据的逻辑结构是指数据的各数据项之间的逻辑关系。 错 是数据元素之间的逻辑关系 2-4以下属于逻辑结构的是&#xff08; &#xff09;。 (2分) 顺序表 散列表 有序表 单链表 有序表 2-12以下关于数据结构的说法中正确的是____。 (2分) A数据结构的逻辑结构独立于…

粗略的看JFinal的基于AOP的拦截器的实现

2019独角兽企业重金招聘Python工程师标准>>> 简单的说一下AOP的实现&#xff0c;所谓AOP&#xff0c;即&#xff08;Aspect Oriented Programming&#xff09;的缩写&#xff0c;体现在程序中就是你可以通过配置在任意的代码块前后插入你想插入的执行代码。例如日志…

大二上数据结构复习

目录 第一章绪论练习 第二章线性表 第三章栈和队列 第四章串 第五章数组和广义表 第六章树和二叉树 第七章图 第九章查找 第十章排序 第一章绪论练习 1-8 数据结构的抽象操作的定义与具体实现有关。 (1分) T F 1-14 数据结构包括数据对象集以及它们的逻辑结构和物理结构&#…

大二上数据结构复习2

第二章线性表 综合 一、在什么情况下用顺序表比用链表好 表长度确定&#xff0c;很少进行插入删除操作且经常访问元素 二、2-4 顺序表的插入和删除要求仍然保持各个元素原来的次序。设在等概率情形下, 对有 127 个元素的顺序表进行插入, 平均需要移动多少个元素? 删除一个元素…

操作系统(王道笔记第二章)

目录第二章 2.1_1进程的定义、组成、组成形式、特征 2.1_2进程的状态与转换 2.1_3进程的控制 2.1_4进程通信 2.1_5线程概念和多线程模型 2.2_1处理机调度的概念层次 2.2_2处理机调度的时机、切换与过程、方式 2.2_3调度算法的评价指标 2.2_4FCFS、SJF、HRRN调度算法 2.2_5时间片…

C语言画图形(图形库graphics的使用)

目录 工具 c语言基本绘图 文字输出 c语言基本贴图 获取鼠标、键盘信息 工具 &#xff08;1&#xff09;环境&#xff1a;VC &#xff08;2&#xff09;库函数&#xff1a;graphics.h&#xff08;因为不是标准库函数&#xff0c;所以需下载EASYX&#xff09; &#xff08;3&am…

关于DDD中Domain的思考

2019独角兽企业重金招聘Python工程师标准>>> 本文既不推销UML&#xff0c;也不推广DDD&#xff0c;更不涉及各种论战。-- 作者 某天又一次打开关于DDD(领域驱动设计)的PDF文档时&#xff0c;自己有了个疑问&#xff1a;什么是领域(Domain)&#xff1f;译文中是这样描…

算法设计TSP问题动态规划

#include <iostream> #include <cmath> using namespace std; //集合虚拟化用000 、001 、010 、011 、100 、101 、110 、111分别表示{} 、{1}&#xff08;V[2^(1-1)]&#xff09; 、{2}&#xff08;V[2^(2-1)]&#xff09; 、{1,2}&#xff08;V[2^(1-1)2^(2-1)]…

字符串使用与内部实现原理

Redis 发展到现在已经有 9 种数据类型了&#xff0c;其中最基础、最常用的数据类型有 5 种&#xff0c;它们分别是&#xff1a;字符串类型、列表类型、哈希表类型、集合类型、有序集合类型&#xff0c;而在这 5 种数据类型中最常用的是字符串类型&#xff0c;所以本文我们先从字…

Lisp-Stat翻译 —— 第九章 统计绘图窗体

2019独角兽企业重金招聘Python工程师标准>>> 第九章 统计绘图窗体 除了前几章略述的绘图窗体原型提供的基本绘图工具之外&#xff0c;Lisp-Stat里的统计绘图还需要用来管理数据和将那些数据转换成屏幕上的图形的工具集。这些工具由绘图原型graph-proto提供。更多的…

操作系统(王道笔记第三章内存)

第三章内存3.1_1内存的基础知识&#xff08;1&#xff09;什么是内存&#xff1a;略&#xff08;2&#xff09;进程运行的基本原理①从写程序到程序运行②链接③装入3.1_2内存管理的概念&#xff08;1&#xff09;内存管理管哪几个方面&#xff08;2&#xff09;内存保护①上下…

Redis 快速搭建与使用

Redis 是由 C 语言开发的开源内存数据存储器&#xff0c;经常被用作数据库、缓存以及消息队列等。 Redis 因为其强大的功能和简洁的设计&#xff0c;深受广大开发者和公司的喜爱&#xff0c;几乎占领了内存数据库市场的所有份额。 1 Redis 特性 Redis 有很多优秀的特性&#…

hibernate annotation注解方式来处理映射关系

2019独角兽企业重金招聘Python工程师标准>>> 在hibernate中&#xff0c;通常配置对象关系映射关系有两种&#xff0c;一种是基于xml的方式&#xff0c;另一种是基于annotation的注解方式&#xff0c;熟话说&#xff0c;萝卜青菜&#xff0c;可有所爱&#xff0c;每个…

操作系统Ubuntu(实验一二)

摘录&#xff1a;https://www.cnblogs.com/penglang14/p/10632360.html 实验一二1.1_小技巧1.2_ls查看目录命令1.3_cd切换目录命令1.4_查看文件内容命令(1)cat filename(2)more filename(3)head [-n] filename([]表示此内容可有可无)&#xff08;4&#xff09;wc命令确定行数、…

Redis 是如何执行的?

在以往的面试中&#xff0c;当问到一些面试者&#xff1a;Redis 是如何执行的&#xff1f;收到的答案往往是&#xff1a;客户端发命令给服务器端&#xff0c;服务端收到执行之后再返回给客户端。然而对于执行细节却「避而不谈」 &#xff0c;当继续追问服务器端是如何执行的&am…

第五章I/O管理

I/O章节5.1.1I/O分类&#xff08;1&#xff09;按使用特性分&#xff08;2&#xff09;I/O设备按传输速率分类&#xff08;3&#xff09;I/O设备按信息交换的单位分5.1.2I/O控制器5.1.3I/O控制方式&#xff08;1&#xff09;程序直接控制方式&#xff08;轮询&#xff09;&…

列表使用与内部实现原理

列表类型 (List) 是一个使用链表结构存储的有序结构,它的元素插入会按照先后顺序存储到链表结构中,因此它的元素操作 (插入\删除) 时间复杂度为 O(1),所以相对来说速度还是比较快的,但它的查询时间复杂度为 O(n),因此查询可能会比较慢。 1 基础使用 列表类型的使用相对来…