找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7066|回复: 4
打印 上一主题 下一主题
收起左侧

智能交通灯控制系统单片机课程设计报告

  [复制链接]
跳转到指定楼层
楼主
ID:429279 发表于 2018-11-19 16:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
题目:智能交通灯控制系统设计     

摘要:交通灯在我们日常生活中随处可见,它在交通系统中处于至关重要的位置。交通灯的使用大大减少了交通繁忙路口的事故发生,给行人和车辆提供一个安全的交通环境,人们的生命和财产安全有了保障。本设计旨在模拟十字路口的交通灯,以AT89C52单片机为基础,结合按键和数码管等元器件设计出一个简单且完全的交通灯系统。

目录
一、课程设计任务
1、设计目的
2、设计要求
二、设计总体方案
1、主要器件介绍
    1.1 AT89C52单片机              2
    1.2两位共阴极数码显示管              3
    1.3红绿灯              3
2、流程图              4
3、硬件电路设计              4
3.1时钟模块              5
3.2开关控制模块              5
3.3显示输出模块              6
3.4蜂鸣器模块              6
3.5复位电路模块              7
三、模拟仿真结果              7
四、心得体会              10
参考文献              11
附件1 源程序代码              12
附件2 原理图              22

一、课程设计任务1、设计目的

随着经济的发展,城市现代化程度不断提高,交通需求和交通量迅速增长,城市交通网络中交通拥挤日益严重,道路运输所带来的交通拥堵、交通事故和环境污染等负面效应也日益突出,逐步成为经济和社会发展中的全球性公共问题。因此,研究基于智能集成的城市交通信号控制系统具有相当的学术价值和使用价值,使交通灯具有智能化的控制,未来的城市交通控制系统才能适应城市交通的发展。

本次设计实现了一个简易智能交通灯控制系统,其核心思想就是根据两个交叉方向的车流量、天气状况、是否是上下班高峰期等因素,能实现不同的红绿灯切换时间,并且具有倒计时的功能。本次的课程设计,是基于89C51单片机结合按键,数码管,二极管采用C语言作为编程语言设计的一个简易的交通灯控制系统,具有红绿灯计时,紧急车强制通过,自定义时间,黄灯闪烁,声音提示等功能。

2、设计要求

(1)设计一个十字路口的交通灯控制电路,要求南北方向和东西方向两条交叉道路上的车辆交替运行,每次通行时间都设30秒,时间可设置修改。

(2)在绿灯转为红灯时,要求黄灯先亮5秒钟,才能变换运行车道,且黄灯亮时,要求每秒亮一次。

(3)有紧急车辆要求通过时,系统要能禁止东西和南北两条路上所有的车辆通行。

二、设计总体方案1、主要器件介绍1.1 AT89C52单片机

本系统的课程设计选用MCS-51系列单片机作为整个系统的控制核心。AT89C52(如图1)是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,功能强大的AT89C52单片机可提供许多较复杂系统控制应用场合。

  AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,AT89C52可以按照常规方法进行编程,也可以在线编程。其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。鉴于以上的优点本系统采用AT8952作为主控芯片,实现对整个系统的控制。

图1  AT89C52单片机

1.2 两位共阴极数码显示管

在红绿灯与数码管的显示上,本系统采用两位的7段两位共阴极数码管,可显示00-99范围,对于交通灯的倒计时,已经完全满足需求。

P0输入到数码管为高电平是才能显示,数码管显示通过控制其中的8个发光二极管来控制显示,abcdefg用于控制数字显示,dp用于控制小数点,例如:输出为0X3f即00111111时abcdef都显示,此时整个数码管显示0。1,2端口用于动态显示时控制需要输出到那个数码管。

图2 共阴极数码显示管

1.3 红绿灯

              红绿灯控制由P2端口控制,输出高电平时就会时某一个发光二极管发亮,P2.1-P2.3控制东西方向,P2.4-P2.6控制南北方向,从而模拟红绿灯的效果例如,输出为P2 = 0Xc3时东西为绿灯,南北为黄灯。

图3 红绿灯设计图

2、流程图

图4 设计流程图


3、硬件电路设计

本系统的设计主要分为两大部分,单片机最小系统模块和显示模块。

单片机最小系统模块的电路设计比较简单,主要由时钟电路、复位电路组成。此外,本系统添加了三个输入按键,主要实现三个功能:东西通行、南北通行、禁止通行。

显示电路采用七段共阴极数码管显示,南北方向的数码管的段选端分别与P0端口的P0.0-P0.7相连,位选端分别与P1.2和P1.3相连;东西方向数码关的段选端也与P2端口的P0.0-P0.7相连,位选端分别与P1.0和P1.1相连。

交通灯采用的是发光二极管,南北方向的红黄绿等分别与P2.6、P2.5和P2.4相连:东西方向的红黄绿灯分别与P2.3、P2.2和P2.1相连。

本系统的软件设计主要分为五大模块:时钟模块、开关控制模块、显示输出模块、蜂鸣器模块、红绿灯与数码管模块。

2.1时钟模块

MCS-51单片机芯片内部有一个用于构成振荡器的高增益反向放大器,引脚XTAL1和XTAL2分别是此放大器的输入端和输出端。当使用内部震荡电路时,XTAL1和XTAL2引脚外接石英晶体和微调电容,C2,C3大小一般为30pF,采用12M的晶振。时钟模块电路图如图5。

图5 时钟模块电路图

2.2开关控制模块

在这个模块中,主要用到了两个外部中断INT0和INT1,用于控制南北或东西强制通行,其他的5个开关在程序中定义。开关模块电路图如图6。

图6 开关模块电路图

2.3显示输出模块

排插是因为P0口是准双向口,即是开漏输出的,当P0口作为并行口使用时,只能输出低电平,不能输出高电平,需要接一个上拉电阻才能输出高电平,输出是采用动态输出P1.0,P1.1,P1.2,P1.3用与控制输出选择。显示模块电路图如图7。

图7 开关模块电路图

2.4蜂鸣器模块

P3.7用于蜂鸣器输出,蜂鸣器一端接地,当P3.7口输出高电平时,蜂鸣器就会响声。蜂鸣器模块电路图如图8。

图8 蜂鸣器模块电路图

2.5复位电路模块

使用Vcc为电容充电,当按下开关时电容,当持续输出2us时即可reset单片机。复位电路模块如图9。

图9 复位电路模块电路图

三、模拟仿真结果

(1)南北正常通行仿真结果如图 10。

图10 南北正常通行

(2)东西正常通行仿真结果如图 11。

图11 东西正常通行

(3)交通灯跳转黄灯仿真结果如图 12。

图12 交通灯跳转黄灯

(4)外部中断南北通行仿真结果如图13。

图13 南北通行

(5)外部中断东西通行仿真结果如图14。

图14 东西通行


(6)紧急情况仿真结果如图15。

图15 紧急车

4、心得体会

这次交通灯的制作是我学会了不少的东西,首先是proteus和keil的使用。单片机程序的编写和原理图的仿真都是在这两个软件的运行下才可以进行的。这个实验最重要的是让我对51系列的单片机有了更深层次的了解,这一学期开始接触单片机的时候觉得这是一门极其高深的课程,老师讲的什么基本完全不懂,课后看仍旧是一头雾水。通过交通灯的学习和制作,对单片机有了初步的了解,知道了它的组成、工作原理等等。

在软件编写这一块,开始时遇到了很大的难题,因为两百行的程序,哪怕有一个错误,修改起来也不是十分方便。时常没有心思去寻找和改正错误,所以软件这一块花了很大的一部分时间。几次调试后总算出现“0 warning”和“0 error”的字样。

除了学会很多东西以为,也发现了自己的不足。由于自己在这一方面只是的短缺,所以很多问题都需要查阅资料或者向别的同学请教。比如说proteus和keil的使用方法,都是看着别人操作几遍之后才慢慢学会。另外,由于时间问题,没能做到真正的实物实现,没有接触到焊接工作,这一点是十分遗憾的,相信如果做了实物实现,可能还会遇到更多的问题,学习到更多的实践知识。

庆幸设计模拟结果是成功的,模拟出了交通灯的功能,各个按键的功能也和模拟时一致,看着数字的跳动自己信息也感到十分开心。虽然想过在这个交通灯里加入一些额外的功能,但终究由于自己知识的局限性而放弃,有点遗憾,不过能够学到东西就好。此次试验增长了自己的单片机知识外也让我知道实践和理论学习的差别。实践过程中学到的知识自己记得会更加牢固一些,不容易忘记。总的来说,单片机的制作让我收获不小。


附件2 原理图


  1. #include <reg51.h>
  2. #define uchar unsigned char
  3. #define uint  unsigned int

  4. uchar data buf[4];
  5. uchar data sec_dx = 20;//东西数默认
  6. uchar data sec_nb = 30;//南北默认值
  7. uchar data set_timedx = 20;
  8. uchar data set_timenb = 30;
  9. int n;
  10. uchar data b;//定时器中断次数
  11. sbit  k1 = P1 ^ 6;//++
  12. sbit  k2 = P1 ^ 7; //--
  13. sbit  k3 = P2 ^ 7;  //确定
  14. sbit  k4 = P3 ^ 0; //切换方向
  15. sbit  k5 = P3 ^ 1; //紧急车
  16. sbit Yellow_nb = P2 ^ 5;        //南北黄灯标志
  17. sbit Yellow_dx = P2 ^ 2;        //东西黄灯标志
  18. sbit Green_nb = P2 ^ 4;
  19. sbit Green_dx = P2 ^ 1;
  20. sbit Red_nb = P2 ^ 6;
  21. sbit Red_dx = P2 ^ 3;
  22. sbit Buzz = P3 ^ 7;
  23. bit Buzzer_Indicate;
  24. bit time = 0;//灯状态循环标志
  25. bit   set = 1;//调时方向切换键标志
  26. uchar code table[11] = {          //共阴极字型码
  27.         0x3f,  //--0
  28.         0x06,  //--1
  29.         0x5b,  //--2
  30.         0x4f,  //--3
  31.         0x66,  //--4
  32.         0x6d,  //--5
  33.         0x7d,  //--6
  34.         0x07,  //--7
  35.         0x7f,  //--8
  36.         0x6f,  //--9
  37.         0x00   //--NULL
  38. };

  39. //函数的声明部分
  40. void delay(int ms);//延时子程序
  41. void key();//按键扫描子程序
  42. void key_to1();//键处理子程序
  43. void key_to2();
  44. void key_to3();
  45. void display();//显示子程序
  46. void logo();   //开机LOGO
  47. void Buzzer();
  48. //主程序
  49. void main()
  50. {
  51.            TMOD = 0X01;
  52.         /*TH0 = 0XD8;
  53.         TL0 = 0XF0;*/
  54.         TH0 = 0X3C; //1101 1000   50ms
  55.         TL0 = 0XB0;
  56.         EA = 1;
  57.         ET0 = 1;
  58.         TR0 = 1;        //开始
  59.         EX0 = 1;        //外部中断0请求标志 允许
  60.         EX1 = 1;
  61.         logo();
  62.         P2 = 0Xc3;// 开始默认状态,东西绿灯,南北黄灯
  63.         sec_nb = sec_dx + 5;
  64.         while (1)
  65.         {
  66.                 key(); //调用按键扫描程序
  67.                 display(); //调用显示程序
  68.                 //Buzzer();
  69.         }
  70. }
  71. //函数的定义部分
  72. void key()        //按键扫描子程序
  73. {
  74.         if (k1 != 1)
  75.         {
  76.                 delay(10);
  77.                 if (k1 != 1)
  78.                 {
  79.                         while (k1 != 1)
  80.                         {
  81.                                 key_to1(); //时间增加
  82.                                 for (n = 0; n < 40; n++)
  83.                                 {
  84.                                         display();
  85.                                 }
  86.                         }
  87.                 }
  88.         }
  89.         if (k2 != 1)
  90.         {
  91.                 delay(10);
  92.                 if (k2 != 1)
  93.                 {
  94.                         while (k2 != 1)
  95.                         {
  96.                                 key_to2(); //时间减少
  97.                                 for (n = 0; n < 40; n++)
  98.                                 {
  99.                                         display();
  100.                                 }
  101.                         }
  102.                 }
  103.         }
  104.         if (k3 != 1)
  105.         {
  106.                 TR0 = 1;   //启动定时器
  107.                 Buzzer_Indicate = 0;
  108.                 sec_nb = set_timenb;        //从中断回复,仍显示设置过的数值
  109.                 sec_dx = set_timedx;
  110.                 if (time == 0)
  111.                 {
  112.                         P2 = 0X99; sec_nb = sec_dx + 5;
  113.                 }
  114.                 else { P2 = 0xC3; sec_dx = sec_nb + 5; }
  115.         }
  116.         if (k4 != 1)
  117.         {
  118.                 //切换方向
  119.                 delay(5);
  120.                 if (k4 != 1)
  121.                 {
  122.                         while (k4 != 1);
  123.                         set = !set;
  124.                 }
  125.         }
  126.         if (k5 != 1)
  127.         {
  128.                 delay(5);
  129.                 if (k5 != 1)
  130.                 {
  131.                         while (k5 != 1)
  132.                                 //紧急车
  133.                                 key_to3();
  134.                 }
  135.         }
  136. }
  137. void display() //显示子程序
  138. {
  139.         buf[1] = sec_dx / 10; //第1位 东西秒十位
  140.         buf[2] = sec_dx % 10; //第2位 东西秒个位
  141.         buf[3] = sec_nb / 10; //第3位 南北秒十位
  142.         buf[0] = sec_nb % 10; //第4位 南北秒个位               
  143.         P1 = 0xff;                                    // 初始灯为灭的
  144.         P0 = 0x00;
  145.         P1 = 0xfe;                                     //片选LCD1
  146.         P0 = table[buf[1]];
  147.         delay(1);
  148.         P1 = 0xff;
  149.         P0 = 0x00;
  150.         P1 = 0xfd;                              //片选LCD2
  151.         P0 = table[buf[2]];
  152.         delay(1);
  153.         P1 = 0xff;
  154.         P0 = 0x00;
  155.         P1 = 0Xfb;                  //片选LCD3
  156. P0 = table[buf[3]];
  157. delay(1);
  158. P1 = 0xff;
  159. P0 = 0x00;
  160. P1 = 0Xf7;
  161. P0 = table[buf[0]];                  //片选LCD4        
  162. delay(1);
  163. }
  164. void time0(void) interrupt 1 using 1  //定时中断 定时器0 子程序
  165. {
  166.         Buzz = 1;
  167.         b++;
  168.         if (b == 20)                          // 定时器中断次数
  169.         {
  170.                      Buzz = 0;
  171.                      b = 0;
  172.                      sec_dx--;
  173.                      sec_nb--;
  174.                      if (sec_nb <= 5 && time == 0)  //东西黄灯闪               
  175.                      {
  176.                              Green_dx = 0; Yellow_dx = !Yellow_dx;
  177.                      }
  178.                      if (sec_dx <= 5 && time == 1)  //南北黄灯闪               
  179.                      {
  180.                              Green_nb = 0; Yellow_nb = !Yellow_nb;
  181.                      }
  182.                      if (sec_dx == 0 && sec_nb == 5)
  183.                              sec_dx = 5;
  184.                      if (sec_nb == 0 && sec_dx == 5)
  185.                              sec_nb = 5;
  186.                      if (time == 0 && sec_nb == 0)
  187.                      {
  188. P2 = 0x99; time = !time; sec_nb = set_timenb; sec_dx = set_timenb + 5;
  189.                      }
  190.                      if (time == 1 && sec_dx == 0)
  191.                      {
  192. P2 = 0Xc3; time = !time; sec_dx = set_timedx; sec_nb = set_timedx + 5;
  193.                      }
  194.         }
  195. }
  196. void key_to1()        //键盘处理子程序之+
  197. {
  198.         TR0 = 0;               //关定时器        
  199.              if (set == 0)
  200.                 set_timenb++;    //南北加1S
  201.         else
  202.                 set_timedx++;    //东西加1S
  203.         if (set_timenb == 100)
  204.                 set_timenb = 1;
  205.         if (set_timedx == 100)
  206.                 set_timedx = 1;   //加到100置1
  207.         sec_nb = set_timenb;         //设置的数值赋给东西南北
  208.         sec_dx = set_timedx;
  209. }
  210. void key_to2()           //键盘处理子程序之-
  211. {
  212.         TR0 = 0;         //关定时器        
  213.             if (set == 0)
  214.                 set_timenb--;  //南北减1S
  215.         else
  216.                 set_timedx--;  //东西减1S
  217.             if (set_timenb == 0)
  218.                 set_timenb = 99;
  219.         if (set_timedx == 0)
  220.                 set_timedx = 99;   //减到1重置99
  221.         sec_nb = set_timenb;         //设置的数值赋给东西南北
  222.         sec_dx = set_timedx;
  223. }
  224. void key_to3()   //键盘处理之紧急车通行
  225. {
  226.         TR0 = 0;
  227.         P2 = 0Xc9;
  228.         sec_dx = 00;
  229.         sec_nb = 00;
  230.         Buzzer_Indicate = 1;
  231. }
  232. void int0(void) interrupt 0 using 1         //只允许东西通行 外部中断0 INT
  233. {
  234.         TR0 = 0;
  235.         P2 = 0Xc3;
  236.         Buzzer_Indicate = 0;
  237.         sec_dx = 00;
  238.             sec_nb = 00;
  239. }

  240. void int1(void) interrupt 2 using 1                   //只允许南北通行 外部中断1 INT
  241. {
  242.              TR0 = 0;
  243.         P2 = 0X99;        //控制红绿灯
  244.         Buzzer_Indicate = 0;
  245.         sec_nb = 00;
  246.         sec_dx = 00;
  247. }
  248. void logo()//开机的Logo  "- - - -"
  249. {
  250.              for (n = 0; n < 50; n++)
  251.         {
  252.                 P0 = 0x40;
  253.                 P1 = 0xfe;
  254.                 delay(1);
  255.                 P1 = 0xfd;
  256.                 delay(1);
  257.                 P1 = 0Xfb;
  258.                 delay(1);
  259.                 P1 = 0Xf7;
  260.                 delay(1);
  261.                 P1 = 0xff;
  262.         }
  263. }
  264. void Buzzer()        //蜂鸣器
  265. {
  266.         if (Buzzer_Indicate == 1)
  267.                      Buzz = !Buzz;
  268.              else Buzz = 0;
  269. }
  270. void delay(int ms)                //延时子程序
  271. {
  272.         uint j, k;
  273.              for (j = 0; j < ms; j++)
  274.                      for (k = 0; k < 124; k++);
  275. }


复制代码

完整的Word格式文档51黑下载地址:
智能交通灯控制系统设计报告.docx (467.52 KB, 下载次数: 116)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:425883 发表于 2018-11-25 22:44 | 只看该作者
请问一下,如果我想用c51单片机去给这个装置,做一个检测各个灯的状态和目前某路灯还剩多少秒,应该怎么做。
回复

使用道具 举报

板凳
ID:397699 发表于 2018-11-28 15:27 | 只看该作者
请问楼主可以发布一下proteus仿真图吗
回复

使用道具 举报

地板
ID:870047 发表于 2020-12-29 11:00 | 只看该作者
请问 红绿灯中间那个东西南北的圆盘 是哪个元器件啊




回复

使用道具 举报

5#
ID:1106031 发表于 2023-12-28 14:45 | 只看该作者
你好, 请问楼主可以发布一下proteus仿真图吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表