找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 848|回复: 0
收起左侧

注释很详细的单片机交通灯程序Proteus仿真原理图 可修改通行时间功能很多

[复制链接]
ID:830257 发表于 2023-6-8 10:07 | 显示全部楼层 |阅读模式
基本要求
(1)控制器:推荐51系列单片机;
(2)仿真软件:Proteus 7.7;
(3)路口为十字路口,需要加入行人的通行时间,橙色灯的3秒等待功能必须添加;
(4)可以在允许期间随时修改各个路口的通行时间;
(5)通行策略如下:每个路口的车辆依次通行,即通行完A路口后,在进行B路口的车辆通行,在某个路口通行时,其他路口的车辆均处于等待状态,在没有车辆进入的路口(除车辆右转外),可进行人行通道是否通行的设置。

系统组成要求
输入部分:
允许控制:按钮(1),切换信息显示的路口;
参数设置:按钮(5),功能切换(修改、退出)、(修改项)移动、减少(1秒)、增加(1秒);
(修改项为每个路口的车辆(直行、左转)通行时间,人行时间根据其他路口时间的设置自动获取)
(按键也可采用KEYPAD-PHONE模块进行整合,利用文字功能进行在相关数字下进行标注)
显示部分:
采用LCD1602进行相关信息的显示,信息显示项为:路口、直行时间(秒)、左转时间(秒)、人行通道时间(秒);均采用倒计时方式,正值表示允许通行,负值表示等待。
采用TRAFFIC LIGHTS模块进行三色交通灯的模拟,LED灯进行人行通道的模拟。
数据连接部分(推荐,非硬性要求)
由于输出数据线较多,可以采用74HC595等并串转换期间进行信息的显示。

运行流程(功能要求)
(1)系统开始运行时可立即进入工作状态;
(2)按下切换按钮,可以在LCD上观测到各个路口的相关时间数据;
(3)按下修改按钮,工作状态被打断,此时可以进行各个路口车辆运行时间的修改。

工作量要求
   根据技术指标或功能要求合理设计整个课题的实现逻辑,完成总体设计;
   利用Proteus仿真软件搭建完整的控制系统,对于不能直接仿真的模块寻找合理的替代方式;
   设计合理的系统控制流程;
   利用(Keil C)μVision软件编写C语言控制程序,并完成系统功能的调试;

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.gif

单片机源程序如下(注释非常详细):
  1. #include "Common.h"
  2. #include "lcd1602.h"
  3. #include "stdio.h"


  4. //引脚定义
  5. sbit KeyChangeDisp = P2^3;                //切换显示按键
  6. sbit KeySet = P2^4;                //设置模式按键
  7. sbit KeyMove = P2^5;        //移动按键
  8. sbit KeyAdd = P2^6;                //加按键
  9. sbit KeySub = P2^7;                //减按键

  10. /* 直行交通灯定义 */
  11. sbit LedRedNS = P1^2;        // 南北直行方向红灯
  12. sbit LedGreenNS = P1^0;        // 南北直行方向绿灯
  13. sbit LedYellowNS = P1^1;// 南北直行方向黄灯
  14. sbit LedRedEW = P1^5;        // 东西直行方向红灯
  15. sbit LedGreenEW = P1^3;        // 东西直行方向绿灯
  16. sbit LedYellowEW = P1^4;// 东西直行方向黄灯

  17. /* 左转交通灯定义 */
  18. sbit LedLeftRedNS = P3^2;        // 南北左转方向红灯
  19. sbit LedLeftGreenNS = P3^0;        // 南北左转方向绿灯
  20. sbit LedLeftYellowNS = P3^1;// 南北左转方向黄灯
  21. sbit LedLeftRedEW = P3^5;        // 东西左转方向红灯
  22. sbit LedLeftGreenEW = P3^3;        // 东西左转方向绿灯
  23. sbit LedLeftYellowEW = P3^4;// 东西左转方向黄灯

  24. /* 人行道交通灯定义 */
  25. sbit LedPeopleRedNS = P1^6;                // 南北人行红灯
  26. sbit LedPeopleGreenNS = P1^7;        // 南北人行绿灯
  27. sbit LedPeopleRedEW = P3^6;                // 东西人行红灯
  28. sbit LedPeopleGreenEW = P3^7;        // 东西人行绿灯

  29. /* 定义变量保存各方向的剩余时间,正数为剩余通行时间,负数为剩余等待时间 */
  30. char RnTime_NS = 0;                  //南北方向直行剩余时间
  31. char RnTime_EW = 0;                  //东西方向直行剩余时间
  32. char RnLeftTime_NS = 0;          //南北方向左转剩余时间
  33. char RnLeftTime_EW = 0;          //东西方向左转剩余时间
  34. char RnPeopleTime_NS = 0;          //南北方向人行剩余时间
  35. char RnPeopleTime_EW = 0;          //东西方向人行剩余时间


  36. //相关变量定义
  37. Uint8 TimeGreen_NS=5;  //南北方向运行时间
  38. Uint8 TimeGreen_EW=5;  //东西方向运行时间
  39. Uint8 TimeLeftGreen_NS=5;  //南北左转方向运行时间
  40. Uint8 TimeLeftGreen_EW=5;  //东西左转方向运行时间
  41. Uint8 TimeYellow = 3;        //黄灯时间
  42. Uint8 index=0;  
  43. Uint8 flag_1S;          //1s时间基准标志
  44. Uint8 IntTimes=0;       //记录定时器中断次数
  45. Uint8 Time_NS,Time_WE;  //南北方向、东西方向换灯前剩余时间  

  46. Uint8 code StrNS1[] = "NS:  SF  TL XING";
  47. Uint8 code StrEW1[] = "EW:  SF  TL XING";
  48. Uint8      StrNum[] = "                ";
  49. Uint8 code Str[]    = "NS  NSL  EW  EWL";

  50. Uint8 DispState = 0;        // 显示的状态,0为显示南北方向信息,1为显示东西方向信息
  51. Uint8 CopyLightP1;                //备份交通灯状态
  52. Uint8 CopyLightP3;                //备份交通灯状态
  53. Uint8 State = 0;                //系统运行状态标志位,0:正常运行;1:设置南北直行方向通行时间;2设置南北左转通行时间
  54.                                                 //3:设置东西直行通行时间;4设置东西左转通行时间
  55.                                                                                        

  56. //函数声明
  57. void KeyScan();                                                  //按键扫描
  58. void Display();                        //数码管动态显示
  59. void InitTimer0();                                            //定时器0初始化,提供时间基准
  60. void FlashLED();                                                                //控制交通灯的变化
  61. void ProcTime();                        // 处理各个方向剩余时间和等待时间
  62. //主函数
  63. void main()
  64. {
  65.     InitTimer0();       //定时器0初始化
  66.         Init1602();                        //初始化LCD1602
  67.     while (1)
  68.     {
  69.                 KeyScan();                  //按键扫描
  70.         FlashLED();             //led指示灯扫描
  71.         if(flag_1S==1)          //定时器计时达到1秒
  72.         {
  73.             flag_1S=0;          //满1秒标志清零
  74.             Time_NS--;          //南北东西通行时间各减1
  75.             Time_WE--;
  76.                         ProcTime();                        // 处理各个方向剩余时间和等待时间
  77.         }
  78.     }
  79. }

  80. void Timer0() interrupt 1  //定时器0中断
  81. {
  82.         TH0=(65536-20000)/256;             //50ms一次中断
  83.         TL0=(65536-20000)%256;
  84.         IntTimes++;            //中断次数计算器加一
  85.         if(IntTimes>=50)       //进中断50次,即为1秒
  86.         {
  87.                 IntTimes=0;         //中断次数计算器清0
  88.                 if(State == 0)                //正常运行模式下倒计时减一
  89.                     flag_1S=1;                //1秒标志位置一        
  90.         }
  91. }

  92. void InitTimer0()              //定时器0初始化,提供时间基准
  93. {
  94.         TMOD=0X01;                  //定时器0方式设置1
  95.         TH0=(65536-20000)/256;      //初值设置 20ms
  96.         TL0=(65536-20000)%256;      //初值设置  
  97.         ET0=1;                      //使能定时器0中断
  98.         TR0=1;                      //开定时器0
  99.     EA=1;                       //开总中断
  100. }

  101. void ProcTime()                        // 处理各个方向剩余时间和等待时间
  102. {
  103.         /* 大于0代表剩余为通行时间,每秒减一;小于0代表为等待时间(负数),每秒加一 */
  104.         if (RnTime_NS > 0)
  105.         {
  106.                 RnTime_NS--;
  107.         }
  108.         else if(RnTime_NS < 0)
  109.         {
  110.                 RnTime_NS++;
  111.         }
  112.         
  113.         if (RnTime_EW > 0)
  114.         {
  115.                 RnTime_EW--;
  116.         }
  117.         else if(RnTime_EW < 0)
  118.         {
  119.                 RnTime_EW++;
  120.         }
  121.         
  122.         if (RnLeftTime_NS > 0)
  123.         {
  124.                 RnLeftTime_NS--;
  125.         }
  126.         else if(RnLeftTime_NS < 0)
  127.         {
  128.                 RnLeftTime_NS++;
  129.         }
  130.         
  131.         if (RnLeftTime_EW > 0)
  132.         {
  133.                 RnLeftTime_EW--;
  134.         }
  135.         else if(RnLeftTime_EW < 0)
  136.         {
  137.                 RnLeftTime_EW++;
  138.         }
  139.         
  140.         if (RnPeopleTime_NS > 0)
  141.         {
  142.                 RnPeopleTime_NS--;
  143.         }
  144.         else if(RnPeopleTime_NS < 0)
  145.         {
  146.                 RnPeopleTime_NS++;
  147.         }
  148.         
  149.         if (RnPeopleTime_EW > 0)
  150.         {
  151.                 RnPeopleTime_EW--;
  152.         }
  153.         else if(RnPeopleTime_EW < 0)
  154.         {
  155.                 RnPeopleTime_EW++;
  156.         }
  157. }

  158. void Display()                        //lcd显示显示
  159. {
  160.         /* 显示南北方向信息 */
  161.         if (DispState == 0)
  162.         {
  163.                 Write1602_Str(0, 1, StrNS1, 16);// 屏幕第一行
  164.                 sprintf(StrNum,"   %4.2d%4.2d%4.2d",(int)RnTime_NS,(int)RnLeftTime_NS,(int)RnPeopleTime_NS);
  165.                 Write1602_Str(0, 0, StrNum, 16);// 屏幕第二行
  166.         }
  167.         else if (DispState == 1)
  168.         {
  169.                 Write1602_Str(0, 1, StrEW1, 16);//写字符串
  170.                 sprintf(StrNum,"   %4.2d%4.2d%4.2d",(int)RnTime_EW,(int)RnLeftTime_EW,(int)RnPeopleTime_EW);
  171.                 Write1602_Str(0, 0, StrNum, 16);// 屏幕第二行
  172.         }
  173. }

  174. void FlashLED()                                                //交通灯的变化
  175. {
  176.         if(State == 0)                                                //正常运行模式
  177.         {
  178.                 if(Time_NS==0 || Time_WE==0)   //南北或东西方向有时间为0
  179.                 {
  180.                         switch(index)                           //改变红绿灯的状态,状态机
  181.                         {
  182.                                 case 0:                      /* 南北方向直行绿灯、南北人行绿灯,南北左转红灯、东西直行红灯、东西左转红灯 */
  183.                                 {
  184.                                         index=1;           //下次进入时切换方向
  185.                                         Time_NS = TimeGreen_NS;        // 南北直行方向绿灯剩余时间
  186.                                         Time_WE=TimeGreen_NS + TimeLeftGreen_NS + TimeYellow * 2; //东西直行方向的等待时间
  187.                                        
  188.                                         /* 计算各个方向的剩余时间和等待时间 */
  189.                                         RnTime_NS = Time_NS;
  190.                                         RnTime_EW = -(TimeGreen_NS + TimeLeftGreen_NS + TimeYellow * 2);
  191.                                         RnLeftTime_NS = -TimeYellow - RnTime_NS;
  192.                                         RnLeftTime_EW = -(TimeGreen_EW + TimeYellow) + RnTime_EW;
  193.                                         RnPeopleTime_NS = RnTime_NS;        // 人行时间为对应方向的直行时间
  194.                                         RnPeopleTime_EW = RnTime_EW;
  195.                                        
  196.                                         /* 南北方向直行绿灯、南北人行绿灯,南北左转红灯、东西直行红灯、东西左转红灯 */
  197.                                         /* 直行交通灯 */
  198.                                         LedRedNS = 0;                // 南北直行方向红灯
  199.                                         LedGreenNS = 1;                // 南北直行方向绿灯
  200.                                         LedYellowNS = 0;        // 南北直行方向黄灯
  201.                                         LedRedEW = 1;                // 东西直行方向红灯
  202.                                         LedGreenEW = 0;                // 东西直行方向绿灯
  203.                                         LedYellowEW = 0;        // 东西直行方向黄灯

  204.                                         /* 直行交通灯 */
  205.                                         LedLeftRedNS = 1;        // 南北左转方向红灯
  206.                                         LedLeftGreenNS = 0;        // 南北左转方向绿灯
  207.                                         LedLeftYellowNS = 0;// 南北左转方向黄灯
  208.                                         LedLeftRedEW = 1;        // 东西左转方向红灯
  209.                                         LedLeftGreenEW = 0;        // 东西左转方向绿灯
  210.                                         LedLeftYellowEW = 0;// 东西左转方向黄灯

  211.                                         /* 人行道交通灯 */
  212.                                         LedPeopleRedNS = 0;                // 南北人行红灯
  213.                                         LedPeopleGreenNS = 1;        // 南北人行绿灯
  214.                                         LedPeopleRedEW = 1;                // 东西人行红灯
  215.                                         LedPeopleGreenEW = 0;        // 东西人行绿灯
  216.                                 }break;
  217.                                 case 1:          /* 南北方向直行黄灯、南北人行红灯,南北左转红灯、东西直行红灯、东西人行红灯 */
  218.                                 {
  219.                                         index=2;       //下次进入时切换方向
  220.                                         Time_NS = TimeYellow;        // 南北直行方向黄灯剩余时间
  221.                                          
  222.                                         /* 计算各个方向的剩余时间和等待时间 */
  223.                                         RnTime_NS -= (TimeLeftGreen_NS + TimeGreen_EW + TimeLeftGreen_EW + TimeYellow * 4);
  224.                                         RnPeopleTime_NS = RnTime_NS;        // 人行时间为对应方向的直行时间
  225.                                        
  226.                                         /* 南北方向直行黄灯、南北人行红灯,南北左转红灯、东西直行红灯、东西人行红灯 */
  227.                                         /* 直行交通灯 */
  228.                                         LedRedNS = 0;                // 南北直行方向红灯
  229.                                         LedGreenNS = 0;                // 南北直行方向绿灯
  230.                                         LedYellowNS = 1;        // 南北直行方向黄灯
  231.                                         LedRedEW = 1;                // 东西直行方向红灯
  232.                                         LedGreenEW = 0;                // 东西直行方向绿灯
  233.                                         LedYellowEW = 0;        // 东西直行方向黄灯

  234.                                         /* 直行交通灯 */
  235.                                         LedLeftRedNS = 1;        // 南北左转方向红灯
  236.                                         LedLeftGreenNS = 0;        // 南北左转方向绿灯
  237.                                         LedLeftYellowNS = 0;// 南北左转方向黄灯
  238.                                         LedLeftRedEW = 1;        // 东西左转方向红灯
  239.                                         LedLeftGreenEW = 0;        // 东西左转方向绿灯
  240.                                         LedLeftYellowEW = 0;// 东西左转方向黄灯

  241.                                         /* 人行道交通灯 */
  242.                                         LedPeopleRedNS = 1;                // 南北人行红灯
  243.                                         LedPeopleGreenNS = 0;        // 南北人行绿灯
  244.                                         LedPeopleRedEW = 1;                // 东西人行红灯
  245.                                         LedPeopleGreenEW = 0;        // 东西人行绿灯
  246.                                 }break;
  247.                                 case 2:           /* 南北方向直行红灯、南北人行红灯,南北左转绿灯、东西直行红灯、东西左转红灯,东西人行红灯 */
  248.                                 {
  249.                                         index=3;         //下次进入时切换方向
  250.                                         Time_NS = TimeLeftGreen_NS;        // 南北左转方向绿灯剩余时间
  251.                                        
  252.                                         /* 计算各个方向的剩余时间和等待时间 */
  253.                                         RnLeftTime_NS += TimeLeftGreen_NS;
  254.                                        
  255.                                         /* 南北方向直行红灯、南北人行红灯,南北左转绿灯、东西直行红灯、东西左转红灯,东西人行红灯 */
  256.                                         /* 直行交通灯 */
  257.                                         LedRedNS = 1;                // 南北直行方向红灯
  258.                                         LedGreenNS = 0;                // 南北直行方向绿灯
  259.                                         LedYellowNS = 0;        // 南北直行方向黄灯
  260.                                         LedRedEW = 1;                // 东西直行方向红灯
  261.                                         LedGreenEW = 0;                // 东西直行方向绿灯
  262.                                         LedYellowEW = 0;        // 东西直行方向黄灯

  263.                                         /* 左转交通灯 */
  264.                                         LedLeftRedNS = 0;        // 南北左转方向红灯
  265.                                         LedLeftGreenNS = 1;        // 南北左转方向绿灯
  266.                                         LedLeftYellowNS = 0;// 南北左转方向黄灯
  267.                                         LedLeftRedEW = 1;        // 东西左转方向红灯
  268.                                         LedLeftGreenEW = 0;        // 东西左转方向绿灯
  269.                                         LedLeftYellowEW = 0;// 东西左转方向黄灯

  270.                                         /* 人行道交通灯 */
  271.                                         LedPeopleRedNS = 1;                // 南北人行红灯
  272.                                         LedPeopleGreenNS = 0;        // 南北人行绿灯
  273.                                         LedPeopleRedEW = 1;                // 东西人行红灯
  274.                                         LedPeopleGreenEW = 0;        // 东西人行绿灯
  275.                                 }break;
  276.                                 case 3:           /* 南北方向直行红灯、南北人行红灯,南北左转黄灯、东西直行红灯、东西左转红灯,东西人行红灯 */
  277.                                 {
  278.                                         index=4;         //下次进入时切换方向
  279.                                         Time_NS = TimeYellow;        // 南北左转方向黄灯剩余时间
  280.                                        
  281.                                         /* 计算各个方向的剩余时间和等待时间 */
  282.                                         RnLeftTime_NS -= (TimeGreen_EW + TimeLeftGreen_EW + TimeGreen_NS + TimeYellow * 4);
  283.                                        
  284.                                         /* 南北方向直行红灯、南北人行红灯,南北左转黄灯、东西直行红灯、东西左转红灯,东西人行红灯 */
  285.                                         /* 直行交通灯 */
  286.                                         LedRedNS = 1;                // 南北直行方向红灯
  287.                                         LedGreenNS = 0;                // 南北直行方向绿灯
  288.                                         LedYellowNS = 0;        // 南北直行方向黄灯
  289.                                         LedRedEW = 1;                // 东西直行方向红灯
  290.                                         LedGreenEW = 0;                // 东西直行方向绿灯
  291.                                         LedYellowEW = 0;        // 东西直行方向黄灯

  292.                                         /* 左转交通灯 */
  293.                                         LedLeftRedNS = 0;        // 南北左转方向红灯
  294.                                         LedLeftGreenNS = 0;        // 南北左转方向绿灯
  295.                                         LedLeftYellowNS = 1;// 南北左转方向黄灯
  296.                                         LedLeftRedEW = 1;        // 东西左转方向红灯
  297.                                         LedLeftGreenEW = 0;        // 东西左转方向绿灯
  298.                                         LedLeftYellowEW = 0;// 东西左转方向黄灯

  299.                                         /* 人行道交通灯 */
  300.                                         LedPeopleRedNS = 1;                // 南北人行红灯
  301.                                         LedPeopleGreenNS = 0;        // 南北人行绿灯
  302.                                         LedPeopleRedEW = 1;                // 东西人行红灯
  303.                                         LedPeopleGreenEW = 0;        // 东西人行绿灯
  304.                                 }break;
  305.                                 case 4:           /* 南北方向直行红灯、南北人行红灯,南北左转红灯、东西直行绿灯、东西左转红灯,东西人行绿灯 */
  306.                                 {
  307.                                         index=5;         //下次进入时切换方向
  308.                                         Time_NS = TimeGreen_EW + TimeLeftGreen_EW + TimeYellow * 2;        // 南北方向直行的等待时间
  309.                                         Time_WE = TimeGreen_EW; //东西直行方向绿灯的剩余时间
  310.                                        
  311.                                         /* 计算各个方向的剩余时间和等待时间 */
  312.                                         RnTime_EW += TimeGreen_EW;
  313.                                         RnPeopleTime_EW = RnTime_EW;
  314.                                        
  315.                                         /* 南北方向直行红灯、南北人行红灯,南北左转红灯、东西直行绿灯、东西左转红灯,东西人行绿灯 */
  316.                                         /* 直行交通灯 */
  317.                                         LedRedNS = 1;                // 南北直行方向红灯
  318.                                         LedGreenNS = 0;                // 南北直行方向绿灯
  319.                                         LedYellowNS = 0;        // 南北直行方向黄灯
  320.                                         LedRedEW = 0;                // 东西直行方向红灯
  321.                                         LedGreenEW = 1;                // 东西直行方向绿灯
  322.                                         LedYellowEW = 0;        // 东西直行方向黄灯

  323.                                         /* 直行交通灯 */
  324.                                         LedLeftRedNS = 1;        // 南北左转方向红灯
  325.                                         LedLeftGreenNS = 0;        // 南北左转方向绿灯
  326.                                         LedLeftYellowNS = 0;// 南北左转方向黄灯
  327.                                         LedLeftRedEW = 1;        // 东西左转方向红灯
  328.                                         LedLeftGreenEW = 0;        // 东西左转方向绿灯
  329.                                         LedLeftYellowEW = 0;// 东西左转方向黄灯

  330.                                         /* 人行道交通灯 */
  331.                                         LedPeopleRedNS = 1;                // 南北人行红灯
  332.                                         LedPeopleGreenNS = 0;        // 南北人行绿灯
  333.                                         LedPeopleRedEW = 0;                // 东西人行红灯
  334.                                         LedPeopleGreenEW = 1;        // 东西人行绿灯
  335.                                 }break;
  336.                                 case 5:           /* 南北方向直行红灯、南北人行红灯,南北左转红灯、东西直行黄灯、东西左转红灯,东西人行红灯 */
  337.                                 {
  338.                                         index=6;         //下次进入时切换方向
  339.                                         Time_WE = TimeYellow; //东西直行方向黄灯的剩余时间
  340.                                        
  341.                                         /* 计算各个方向的剩余时间和等待时间 */
  342.                                         RnTime_EW -= (TimeLeftGreen_EW + TimeGreen_NS + TimeLeftGreen_NS + TimeYellow * 4);
  343.                                         RnPeopleTime_EW = RnTime_EW;        // 人行时间为对应方向的直行时间
  344.                                        
  345.                                         /* 南北方向直行红灯、南北人行红灯,南北左转红灯、东西直行绿灯、东西左转红灯,东西左转红灯 */
  346.                                         /* 直行交通灯 */
  347.                                         LedRedNS = 1;                // 南北直行方向红灯
  348.                                         LedGreenNS = 0;                // 南北直行方向绿灯
  349.                                         LedYellowNS = 0;        // 南北直行方向黄灯
  350.                                         LedRedEW = 0;                // 东西直行方向红灯
  351.                                         LedGreenEW = 0;                // 东西直行方向绿灯
  352.                                         LedYellowEW = 1;        // 东西直行方向黄灯

  353.                                         /* 直行交通灯 */
  354.                                         LedLeftRedNS = 1;        // 南北左转方向红灯
  355.                                         LedLeftGreenNS = 0;        // 南北左转方向绿灯
  356.                                         LedLeftYellowNS = 0;// 南北左转方向黄灯
  357.                                         LedLeftRedEW = 1;        // 东西左转方向红灯
  358.                                         LedLeftGreenEW = 0;        // 东西左转方向绿灯
  359.                                         LedLeftYellowEW = 0;// 东西左转方向黄灯

  360.                                         /* 人行道交通灯 */
  361.                                         LedPeopleRedNS = 1;                // 南北人行红灯
  362.                                         LedPeopleGreenNS = 0;        // 南北人行绿灯
  363.                                         LedPeopleRedEW = 1;                // 东西人行红灯
  364.                                         LedPeopleGreenEW = 0;        // 东西人行绿灯
  365.                                 }break;
  366.                                 case 6:           /* 南北方向直行红灯、南北人行红灯,南北左转红灯、东西直行红灯、东西左转绿灯,东西人行红灯 */
  367.                                 {
  368.                                         index=7;         //下次进入时切换方向
  369.                                         Time_WE = TimeLeftGreen_EW; //东西直行方向黄灯的剩余时间
  370.                                        
  371.                                         /* 计算各个方向的剩余时间和等待时间 */
  372.                                         RnLeftTime_EW += TimeLeftGreen_EW;
  373.                                        
  374.                                         /* 南北方向直行红灯、南北人行红灯,南北左转红灯、东西直行红灯、东西左转绿灯,东西人行红灯 */
  375.                                         /* 直行交通灯 */
  376.                                         LedRedNS = 1;                // 南北直行方向红灯
  377.                                         LedGreenNS = 0;                // 南北直行方向绿灯
  378.                                         LedYellowNS = 0;        // 南北直行方向黄灯
  379.                                         LedRedEW = 1;                // 东西直行方向红灯
  380.                                         LedGreenEW = 0;                // 东西直行方向绿灯
  381.                                         LedYellowEW = 0;        // 东西直行方向黄灯

  382.                                         /* 直行交通灯 */
  383.                                         LedLeftRedNS = 1;        // 南北左转方向红灯
  384.                                         LedLeftGreenNS = 0;        // 南北左转方向绿灯
  385.                                         LedLeftYellowNS = 0;// 南北左转方向黄灯
  386.                                         LedLeftRedEW = 0;        // 东西左转方向红灯
  387.                                         LedLeftGreenEW = 1;        // 东西左转方向绿灯
  388.                                         LedLeftYellowEW = 0;// 东西左转方向黄灯

  389.                                         /* 人行道交通灯 */
  390.                                         LedPeopleRedNS = 1;                // 南北人行红灯
  391.                                         LedPeopleGreenNS = 0;        // 南北人行绿灯
  392.                                         LedPeopleRedEW = 1;                // 东西人行红灯
  393.                                         LedPeopleGreenEW = 0;        // 东西人行绿灯
  394.                                 }break;
  395.                                 case 7:           /* 南北方向直行红灯、南北人行红灯,南北左转红灯、东西直行红灯、东西左转黄灯,东西人行红灯 */
  396.                                 {
  397.                                         index=0;         //下次进入时切换方向
  398.                                         Time_WE = TimeYellow; //东西直行方向黄灯的剩余时间
  399.                                        
  400.                                         /* 计算各个方向的剩余时间和等待时间 */
  401.                                         RnLeftTime_EW -= (TimeGreen_NS + TimeLeftGreen_NS + TimeGreen_EW + TimeYellow * 4);
  402.                                        
  403.                                         /* 南北方向直行红灯、南北人行红灯,南北左转红灯、东西直行红灯、东西左转黄灯,东西人行红灯 */
  404.                                         /* 直行交通灯 */
  405.                                         LedRedNS = 1;                // 南北直行方向红灯
  406.                                         LedGreenNS = 0;                // 南北直行方向绿灯
  407.                                         LedYellowNS = 0;        // 南北直行方向黄灯
  408.                                         LedRedEW = 1;                // 东西直行方向红灯
  409.                                         LedGreenEW = 0;                // 东西直行方向绿灯
  410.                                         LedYellowEW = 0;        // 东西直行方向黄灯

  411.                                         /* 直行交通灯 */
  412.                                         LedLeftRedNS = 1;        // 南北左转方向红灯
  413.                                         LedLeftGreenNS = 0;        // 南北左转方向绿灯
  414.                                         LedLeftYellowNS = 0;// 南北左转方向黄灯
  415.                                         LedLeftRedEW = 0;        // 东西左转方向红灯
  416.                                         LedLeftGreenEW = 0;        // 东西左转方向绿灯
  417.                                         LedLeftYellowEW = 1;// 东西左转方向黄灯

  418.                                         /* 人行道交通灯 */
  419.                                         LedPeopleRedNS = 1;                // 南北人行红灯
  420.                                         LedPeopleGreenNS = 0;        // 南北人行绿灯
  421.                                         LedPeopleRedEW = 1;                // 东西人行红灯
  422.                                         LedPeopleGreenEW = 0;        // 东西人行绿灯
  423.                                 }break;
  424.                                 
  425.                                 default:break;
  426.                         }
  427.                 }
  428.                 Display();                        //数码管显示剩余时间
  429.                
  430.                 /* index==2或者index==4或者index==6或者index==0时处于黄灯状态,黄灯闪烁 */
  431.                 if (index == 2)
  432.                 {
  433.                         /* IntTimes=50时为1秒,25为0.5秒,此处用于交通灯闪烁 */
  434.                         if(IntTimes < 25)
  435.                         {
  436.                                 LedYellowNS = 0;        // 南北直行方向黄灯
  437.                         }
  438.                         else
  439.                         {
  440.                                 LedYellowNS = 1;        // 南北直行方向黄灯
  441.                         }
  442.                 }
  443.                 else if (index == 4)
  444.                 {
  445.                         /* IntTimes=50时为1秒,25为0.5秒,此处用于交通灯闪烁 */
  446.                         if(IntTimes < 25)
  447.                         {
  448.                                 LedLeftYellowNS = 0;// 南北左转方向黄灯
  449.                         }
  450.                         else
  451.                         {
  452.                                 LedLeftYellowNS = 1;// 南北左转方向黄灯
  453.                         }
  454.                 }
  455.                 else if (index == 6)
  456.                 {
  457.                         /* IntTimes=50时为1秒,25为0.5秒,此处用于交通灯闪烁 */
  458.                         if(IntTimes < 25)
  459.                         {
  460.                                 LedYellowEW = 0;        // 东西直行方向黄灯
  461.                         }
  462.                         else
  463.                         {
  464.                                 LedYellowEW = 1;        // 东西直行方向黄灯
  465.                         }
  466.                 }
  467.                 else if (index == 0)
  468.                 {
  469.                         /* IntTimes=50时为1秒,25为0.5秒,此处用于交通灯闪烁 */
  470.                         if(IntTimes < 25)
  471.                         {
  472.                                 LedLeftYellowEW = 0;// 东西左转方向黄灯
  473.                         }
  474.                         else
  475.                         {
  476.                                 LedLeftYellowEW = 1;// 东西左转方向黄灯
  477.                         }
  478.                 }
  479.         }
  480.         else if(State == 1)                                                        //设置南北直行时间
  481.         {
  482.                 sprintf(StrNum,"%2.2d              ",(int)TimeGreen_NS);
  483.                 Write1602_Str(0, 0, StrNum, 16);// 屏幕第二行
  484.         }
  485.         else if(State == 2)                                                        //设置南北左转时间
  486.         {
  487.                 sprintf(StrNum,"     %2.2d         ",(int)TimeGreen_EW);
  488.                 Write1602_Str(0, 0, StrNum, 16);// 屏幕第二行
  489.         }
  490.         else if(State == 3)                                                        //设置东西直行时间
  491.         {
  492.                 sprintf(StrNum,"         %2.2d     ",(int)TimeLeftGreen_NS);
  493.                 Write1602_Str(0, 0, StrNum, 16);// 屏幕第二行
  494.         }
  495.         else if(State == 4)                                                        //设置东西左转时间
  496.         {
  497.                 sprintf(StrNum,"              %2.2d",(int)TimeLeftGreen_EW);
  498.                 Write1602_Str(0, 0, StrNum, 16);// 屏幕第二行
  499.         }
  500. }

  501. void SetModel()                                                        //红绿灯设置模式
  502. {
  503.         if(State == 0)      //当前为正常运行模式
  504.         {
  505.                 State=1;        //状态切换为设置南北通行时间
  506.                 Write1602_Str(0, 1, Str, 16);// 屏幕第一行
  507. //                CopyLightP1=P1;        //备份指示灯状态
  508. //                CopyLightP3=P3;        //备份指示灯状态
  509.         }
  510.         else                           //当前为设置东西通行时间
  511.         {
  512.                 State=0;        //状态切换为设置正常运行模式
  513. //                P1=CopyLight;        //还原交通灯状态
  514.         index=0;                                                //交通灯重新启动
  515.         Time_NS=0;
  516.         Time_WE=0;        
  517.                
  518.                 RnTime_NS = 0;
  519.                 RnTime_EW = 0;
  520.                 RnLeftTime_NS = 0;
  521.                 RnLeftTime_EW = 0;
  522.                 RnPeopleTime_NS = 0;
  523.                 RnPeopleTime_EW = 0;
  524.         }
  525. }

  526. void ADDTime()                        //红绿灯时间加
  527. {
  528.         if(State==1)               //当前为设置南北通行时间
  529.         {
  530.                 if(TimeGreen_NS < 99)
  531.                         TimeGreen_NS++;  //南北通行时间加一
  532.         }
  533.         else if(State==2)   //当前为设置东西通行时间
  534.         {
  535.                 if(TimeGreen_EW < 99)
  536.                         TimeGreen_EW++;  //东西通行时间加一
  537.         }
  538.         else if(State==3)   //当前为设置东西通行时间
  539.         {
  540.                 if(TimeLeftGreen_NS < 99)
  541.                         TimeLeftGreen_NS++;  //东西通行时间加一
  542.         }
  543.         else if(State==4)   //当前为设置东西通行时间
  544.         {
  545.                 if(TimeLeftGreen_EW < 99)
  546.                         TimeLeftGreen_EW++;  //东西通行时间加一
  547.         }
  548. }
  549. void SUBTime()                        //红绿灯时间减
  550. {
  551.         if(State==1)               //当前为设置南北通行时间
  552.         {
  553.                 if(TimeGreen_NS>1)
  554.                         TimeGreen_NS--;  //南北通行时间加一
  555.         }
  556.         else if(State==2)   //当前为设置东西通行时间
  557.         {
  558.                 if(TimeGreen_EW>1)
  559.                         TimeGreen_EW--;  //东西通行时间加一
  560.         }
  561.         else if(State==3)   //当前为设置东西通行时间
  562.         {
  563.                 if(TimeLeftGreen_NS>1)
  564.                         TimeLeftGreen_NS--;  //东西通行时间加一
  565.         }
  566.         else if(State==4)   //当前为设置东西通行时间
  567.         {
  568.                 if(TimeLeftGreen_EW>1)
  569.                         TimeLeftGreen_EW--;  //东西通行时间加一
  570.         }
  571. }

  572. void MoveModel()                // 移动
  573. {
  574.         if (State > 0)
  575.         {
  576.                 State++;
  577.                 if(State > 4)
  578.                 {
  579.                         State = 1;
  580.                 }
  581.         }
  582. }

  583. void ChangeDisp()                        //切换显示
  584. {
  585.         if(State==0)                       //当前为正常运行模式
  586.     {
  587.         if (DispState == 0)
  588.                 {
  589.                         DispState = 1;
  590.                 }
  591.                 else if (DispState == 1)
  592.                 {
  593.                         DispState = 0;
  594.                 }
  595.     }
  596. }

  597. void KeyScan()                                          //按键扫描
  598. {
  599.     if(KeyChangeDisp == 0)                             //设置按键按下
  600.     {
  601.         DelayMs(10);                                            //延时消抖
  602.         if(KeyChangeDisp == 0)                         //确认按键按下
  603.         {
  604.             ChangeDisp();                                        //切换显示
  605.                         while(KeyChangeDisp == 0);                //等待按键弹起
  606.         }
  607.     }
  608.         if(KeySet == 0)                                     //设置按键按下
  609.     {
  610.         DelayMs(10);                                            //延时消抖
  611.         if(KeySet == 0)                                 //确认按键按下
  612.         {
  613.             SetModel();                                        //切换显示
  614.                         while(KeySet == 0);                                //等待按键弹起
  615.         }
  616.     }
  617.         if(KeyMove == 0)                                 //设置按键按下
  618.     {
  619.         DelayMs(10);                                    //延时消抖
  620.         if(KeyMove == 0)                             //确认按键按下
  621.         {
  622.             MoveModel();                                        //移动设置位置
  623.                         while(KeyMove == 0);                        //等待按键弹起
  624.         }
  625.     }
  626.     if(KeyAdd == 0)                                 //设置按键按下
  627.     {
  628.         DelayMs(10);                                    //延时消抖
  629.         if(KeyAdd == 0)                             //确认按键按下
  630.         {
  631.              ADDTime();                                                //红绿灯时间加
  632.                         while(KeyAdd == 0);                                //等待按键弹起
  633.         }
  634.     }
  635.     if(KeySub == 0)                                 //设置按键按下
  636.     {
  637.         DelayMs(10);                                    //延时消抖
  638.         if(KeySub == 0)                             //确认按键按下
  639.         {
  640.             SUBTime();                                                //红绿灯时间减
  641.                         while(KeySub == 0);                                //等待按键弹起
  642.         }
  643.     }
  644. }
复制代码

Keil5代码与Proteus7与8.13仿真下载:
交通灯.rar (93.07 KB, 下载次数: 32)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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