找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机交通灯程序

[复制链接]
ID:662089 发表于 2020-7-25 19:25 | 显示全部楼层 |阅读模式
这是写完的交通灯程序,在单片机上是能用的。因为很多时候单片机上能跑的程序在PROTEUS上不能跑,所以我没有搭建仿真,也不是用PCB板,只是在实验板上跑了一下,是能用的。具体实现的功能有
显示红绿灯:初始化状态为一向60s,另一向40s开始倒计时。然后,40s走完后,再走20s,然后就两向换倒计时的秒数。
现在有两个按键有具体功能:一个是按下停止刷新,再按一次继续刷新;一个是模式切换按键,按一下,为紧急模式,再按一下为正常模式,再按一下为特殊模式;重复按三下后转为初始化模式。代码在下面,希望对群友有用。

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. typedef unsigned int u16;
  4. typedef unsigned char u8;
  5. u8 digtub[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //用于实物显示的0~9
  6. //u8 digtub[]={0xC0,0xf9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};        //用于Proteus显示用的0~9

  7. u8  dat[8];//欲显示的数据

  8. sbit LSA=P2^2;
  9. sbit LSB=P2^3;
  10. sbit LSC=P2^4;//以上三个是数码管位选位
  11. sbit lred=P2^0;//东西方红灯
  12. sbit lgreen=P3^4;//东西方绿灯
  13. sbit lyellow=P2^7;//东西方黄灯
  14. sbit rred=P2^5;        //南北方红灯
  15. sbit rgreen=P2^1;//南北方绿灯
  16. sbit ryellow=P2^6;//南北向黄灯
  17. sbit KEY1=P3^1;        //按键1
  18. sbit KEY2=P3^2;        //按键2
  19. sbit KEY3=P3^3;        //按键3
  20. sbit KEY4=P3^0;
  21. #define RRED(x) {if((x))rred=0;else{rred=1;}}  //南北向红灯开关函数
  22. #define LRED(x) {if((x))lred=0;else{lred=1;}}  //东西向红灯开关函数
  23. #define RGREEN(x) {if((x))rgreen=0;else{rgreen=1;}}         //南北向绿灯开关函数
  24. #define LGREEN(x) {if((x))lgreen=0;else{lgreen=1;}}          //东西向绿灯开关函数
  25. #define RETURN_RYELLOW {ryellow=~ryellow;}        //南北向黄灯闪烁函数
  26. #define RETURN_LYELLOW {lyellow=~lyellow;}        //东西向黄灯闪烁函数
  27. sbit L1=P3^4;
  28. sbit L2=P3^5;


  29. void key_init();
  30. void display();
  31. void vestmode();  
  32. /********************************************************************************************
  33. ************************定时初始化函数**********************************************************/
  34. void timer_init()
  35. {
  36. TMOD|=0X01;
  37. TH0=(65536-50000)/256;
  38. TL0=(65536-50000)%256;
  39. TR0=1;
  40. EA=1;
  41. ET0=1;
  42. }
  43. /*********************************************************************************************************
  44. ************************以上是定时初始化函数**********************************************************/

  45. /***************************************************************************************************
  46. ************************以下是延时函数***************************************************************/
  47. void delay(u16 ms)
  48. {
  49. u16 i;
  50. for(ms;ms>0;ms--)
  51.    {
  52.    for(i=0;i<120;i++);
  53.    }
  54. }
  55. /***************************************************************************************************
  56. ************************以上是延时函数***************************************************************/
  57. u16 opendis;
  58. void main()
  59. {
  60.     timer_init();
  61. while(1)
  62.     {
  63.         if(!opendis)display();
  64.     key_init();
  65.         vestmode();
  66.         }

  67. }
  68. bit givenum;//开关红绿灯秒数赋值的标志位
  69. u16 staticgreen=30;         //固定绿灯值可通过按键修改
  70. u16 staticred=10;   //固定红灯值可通过按键修改
  71. u8 NSNUM[3]={40,20,60};        //南北方向红绿灯秒数[1]红灯;[2]右转红灯;[3]绿灯
  72. u8 EWNUM[3]={60,20,40};        //东西方向红绿灯秒数[1]绿灯;[2]红灯;[3]右转红灯

  73. /**********************
  74. 这个是定时中断函数************/
  75. void time0() interrupt 1
  76. {
  77. static u16 num=0;
  78. static u8 ewnum;//东西方向60s绿灯
  79. static u8 nsnum;//南北方向40s红灯
  80. static u16  nsflag=0;//南北向黄灯次数或转换红绿方向的标志
  81. static u16 ewflag=0;//东西向黄灯次数或转换红绿方向的标志
  82. u16 Rgreen,Lgreen; //Rgreen南北向绿灯灭标志        ;Lgreen东西向绿灯灭标志;lreturn右转红灯值(方便修改)




  83. if(!givenum){ewnum=EWNUM[0];nsnum=NSNUM[0];}//二次赋值,为了方便修改


  84. TH0=(65536-50000)/256;
  85. TL0=(65536-50000)%256;

  86. num++;          //num=20时刚好计数是1s。
  87. if(num==20)
  88. {
  89. givenum=1;
  90. num=0;
  91. ewnum--;
  92. nsnum--;
  93. if(nsnum==0){if(nsflag>=2){nsflag=0;RGREEN(0);}else{nsflag++;}nsnum=NSNUM[nsflag];}//南北向数码管循环显示。
  94. if(ewnum==0){if(ewflag>=2){ewflag=0;}else{ewflag++;}ewnum=EWNUM[ewflag];}//东西向数码管循环显示。
  95. if(nsflag==0||nsflag==1){RRED(1);}//南北向直行或右转时的红灯
  96. if(nsnum>0&&nsnum<5){
  97.                      RETURN_RYELLOW;
  98.                                          RRED(0);RGREEN(0);Rgreen=1;//南北向红绿灯都灭
  99.                     }//大于0小于5时黄灯
  100. if(nsflag==2&&!Rgreen){RGREEN(1);}//南北绿灯

  101. if(ewflag==0||ewflag==1){LRED(1);}//东西向直行或右转时的红灯
  102. if(ewnum>0&&ewnum<5){
  103.                      RETURN_LYELLOW;
  104.                                          LRED(0);LGREEN(0);Lgreen=1;//东西向红绿灯都灭
  105.                     }//大于0小于5时黄灯
  106. if(ewflag==2&&!Lgreen){LGREEN(1);}//南北绿灯


  107. dat[0]=digtub[ewnum/10];//东西方向红绿灯的十位                                                          
  108. dat[1]=digtub[ewnum%10];//东西方向红绿灯的个位
  109. dat[2]=digtub[nsnum/10];
  110. dat[3]=digtub[nsnum%10];
  111. dat[6]=digtub[ewnum/10];//东西方向红绿灯的十位                                                          
  112. dat[7]=digtub[ewnum%10];//东西方向红绿灯的个位
  113. dat[4]=digtub[nsnum/10];
  114. dat[5]=digtub[nsnum%10];
  115. }                                                                                                                                                                       

  116. }
  117. /********************上面是定时中断函数*******************
  118. *********************************************/

  119. /*这个是按键程序*******************************************************
  120. ***************************************************************************/
  121. static u16 modesign[6]={1,2,3};//模式选择标志
  122. static u16 keymode;
  123. static u16 ewgreen;
  124. u16 ll;
  125. void key_init()
  126. {  
  127. static u16 i=0;

  128. if(KEY1==0)//开关数码管显示按键
  129.    {
  130.    delay(100);                         
  131.    if(KEY1==0){TR0=~TR0;}
  132.    while(!KEY1);
  133.    }

  134. if(KEY2==0)        //切换模式按键
  135.    {                                                                                    
  136.    delay(100);
  137.    if(KEY2==0){
  138.                keymode=modesign[i++];
  139.                if(i>3){i=0;}         
  140.    }
  141.    while(!KEY2);
  142.    }

  143. if(KEY3==0)//后台修改红绿灯值,
  144.    {
  145.    delay(100);
  146.    if(KEY3==0);
  147.    while(!KEY3);
  148.    }
  149. if(KEY4==0)//后台修改红绿灯值,
  150.    {
  151.    delay(100);
  152.    if(KEY4==0);
  153.    while(!KEY4);
  154.    }
  155. }
  156. /***********************************************************************************************/

  157. /***************************************************************************************************/
  158. void display()
  159. {
  160. u16        i;
  161.     for(i=0;i<8;i++)
  162.            {
  163.            switch(i)
  164.                  {
  165.                          case 0:LSA=0;LSB=0;LSC=0;P0=dat[1];break; //第一个数码管
  166.                          case 1:LSA=1;LSB=0;LSC=0;P0=dat[0];break; //第二个数码管
  167.                          case 2:LSA=0;LSB=1;LSC=0;P0=dat[5];break;//第三个数码管
  168.                          case 3:LSA=1;LSB=1;LSC=0;P0=dat[4];break; //第四个数码管
  169.                          case 4:LSA=0;LSB=0;LSC=1;P0=dat[7];break; //第五个数码管
  170.                          case 5:LSA=1;LSB=0;LSC=1;P0=dat[6];break; //第六个数码管
  171.                          case 6:LSA=0;LSB=1;LSC=1;P0=dat[3];break; //第七个数码管
  172.                          case 7:LSA=1;LSB=1;LSC=1;P0=dat[2];break; //第八个数码管
  173.                          }
  174.            }
  175. }
  176. /***************************************************************************************************
  177. ****************************************************************************************************
  178. ***********************************************************************************************/
  179. void vestmode()         //切换模式按键:keymode:1 紧急模式 ; 2 正常模式;3 特殊模式
  180. {
  181.   if(keymode==1){
  182.                EWNUM[0]=45;EWNUM[1]=30;EWNUM[2]=15;
  183.                NSNUM[0]=30;NSNUM[1]=15;NSNUM[2]=45;
  184.                givenum =0;
  185.                            keymode=0;          
  186.                            }
  187.    if(keymode==2){
  188.                EWNUM[0]=60;EWNUM[1]=40;EWNUM[2]=20;
  189.                NSNUM[0]=40;NSNUM[1]=20;NSNUM[2]=60;
  190.                givenum =0;
  191.                            keymode=0;                 
  192.                            }
  193.     if(keymode==3)         //特殊模式后,继续按3次,会初始化到正常模式
  194.                     {
  195.                opendis=~opendis;
  196.                            keymode=0;
  197.                            }
  198. }

  199. /***************************************************************************************************
  200. ****************************************************************************************************
  201. ***********************************************************************************************/
复制代码

所有程序51hei提供下载:
交通灯.rar (71.28 KB, 下载次数: 8)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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