原理图

功能描述

  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

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

51单片机——交通灯相关推荐

  1. 51单片机交通灯(定时器+38译码器+中断)

    51单片机交通灯这个实例主要用到的知识点有: >如何点亮LED >38译码器位选与段选 >定时器控制 >中断控制 #include <reg52.h>/****** ...

  2. 【Proteus】51单片机交通灯信号模拟仿真示例二

    [Proteus]51单片机交通灯信号模拟仿真示例二 Proteus仿真效果 相关篇<[Proteus]51单片机交通灯信号模拟仿真示例一> 程序代码 /*---------------- ...

  3. 基于51单片机交通灯控制系统

    51单片机交通灯控制系统 可调时间+紧急+行人+黄灯5s 仿真:proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:J008 目录标题 51单片机交通灯控制系统 ...

  4. 30、基于51单片机交通灯车流量管控数码管显示系统设计

    摘要 随着社会主义的建设,城市的规模在不断扩大,城市的交通也在不断的提高和改进,交通的顺畅已经成为制约社会主义建设的一个重要因素.目前,伴随着机动车辆的不断增加,尤其是十字路口的交通建设 颇为关键,严 ...

  5. protues 51单片机交通灯仿真

    1.仪器.材料 PC机.keil软件.proteus软件 2.内容及要求 使用51单片机控制交通灯状态的改变,并使用数码管来实现倒计时时间的显示.设置3个按键用于改变交通灯工作于不同的工作状态(全部黄 ...

  6. **51单片机交通灯画图打板历程**

    整个原理图由STC89C52芯片.上拉电阻.复位电路.晶振电路.复位按键.电源供电模块有DC插座,外部的电插入DC电源接口来给整个电路供电,还有数码管,数码管都是由单片机来驱动的 一.原理图 原理图中 ...

  7. 基于protues的51单片机交通灯仿真

    要求使用protues仿真软件,来模仿实际十字路口的红绿的显示变化,同时数码管进行时间倒计时的显示.百度了下实际情况的交通灯规则如下图. 整个交通灯的运行流程如下图所示,这个应该和实际工作流程是非常接 ...

  8. 基于51单片机交通灯设计时间可设置仿真红绿灯十字路口

    演示视频:https://www.bilibili.com/video/BV1Tt4y1y7s8/ 将链接复制至IE浏览器打开!!! 功能操作说明: 从上到下,设置键,加键,减键,特殊键.单独一个按键 ...

  9. 51单片机流水灯现象1

    **` 51单片机流水灯程序 `** 初学者小白,分享上课时写的小程序和普中科技程序,感兴趣的可以瞧瞧. 程序如有相同冒犯了. /*********************************** ...

最新文章

  1. GitPush时提示:fatal: The remote end hung up unexpectedly
  2. 吐血整理!10 个机器学习教程汇总,爱可可推荐!
  3. Symantec SEP 端点防护[五]
  4. java gt lt_Java运算符,,|,||,^,lt;lt;,gt;gt;,~,gt;gt;gt;
  5. 接受与返回json数据
  6. Java Float类floatToIntBits()方法与示例
  7. Import Changes from Direct3D 11 to Direct3D 12
  8. axure画扇形_axure实现粗略饼状图
  9. win10计算机网络共享设置密码,win10系统清除网络共享密码的方法介绍
  10. JavaScript导出excel文件,并修改文件样式
  11. 基础笔记(三):网络协议之Tcp、Http
  12. 林志颖在微博展示iPhone 5
  13. 解决Iphonex 底部按钮fixed,bottom:0 底部留白问题
  14. 北京师范大学网络教育计算机考试题,2020年北京师范大学网络教育入学考试高起专语文模拟题及答案(机考古文阅读)...
  15. 现代交换原理——空间接线器
  16. 新东方报名系统服务器地址,新东方邮箱服务器地址
  17. JAVA联机版五子棋——源码(一个类一个main暴力开发)
  18. 制作系统光盘Server 2003 总结
  19. 使用云服务器实现共享文件,使用云服务器实现共享文件
  20. EJB是什么Java使用EJB容器的详细概述

热门文章

  1. 斗鱼虎牙合并:从内耗走向一致抗敌
  2. 江南大学计算机应用第三阶段,2019下半年江南大学第三阶段语文英语计算机基..._公共英语考试_帮考网...
  3. 国外人经常上的网站,即全球各个领域最大的互联网网站
  4. 网络安全“全面防”,应对难以察觉的网络威胁!
  5. 如何用 Python 让你的 PPT 数据动起来?
  6. css特效实现透明渐变
  7. 临床试验中edc录入_临床试验中EDC(电子数据采集)操作须知
  8. 计算机专业的单招大学排名,全国单招学校排名 单招哪个学校比较好
  9. 图解Java数据结构之双向链表
  10. 金山快盘 linux,WPS移动版5.5发布 支持金山快盘双向读写