找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3244|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)交通燈程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:662089 發(fā)表于 2020-7-25 19:25 | 只看該作者 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
這是寫完的交通燈程序,在單片機(jī)上是能用的。因?yàn)楹芏鄷r候單片機(jī)上能跑的程序在PROTEUS上不能跑,所以我沒有搭建仿真,也不是用PCB板,只是在實(shí)驗(yàn)板上跑了一下,是能用的。具體實(shí)現(xiàn)的功能有
顯示紅綠燈:初始化狀態(tài)為一向60s,另一向40s開始倒計(jì)時。然后,40s走完后,再走20s,然后就兩向換倒計(jì)時的秒數(shù)。
現(xiàn)在有兩個按鍵有具體功能:一個是按下停止刷新,再按一次繼續(xù)刷新;一個是模式切換按鍵,按一下,為緊急模式,再按一下為正常模式,再按一下為特殊模式;重復(fù)按三下后轉(zhuǎn)為初始化模式。代碼在下面,希望對群友有用。

單片機(jī)源程序如下:
  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}; //用于實(shí)物顯示的0~9
  6. //u8 digtub[]={0xC0,0xf9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};        //用于Proteus顯示用的0~9

  7. u8  dat[8];//欲顯示的數(shù)據(jù)

  8. sbit LSA=P2^2;
  9. sbit LSB=P2^3;
  10. sbit LSC=P2^4;//以上三個是數(shù)碼管位選位
  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;}}  //南北向紅燈開關(guān)函數(shù)
  22. #define LRED(x) {if((x))lred=0;else{lred=1;}}  //東西向紅燈開關(guān)函數(shù)
  23. #define RGREEN(x) {if((x))rgreen=0;else{rgreen=1;}}         //南北向綠燈開關(guān)函數(shù)
  24. #define LGREEN(x) {if((x))lgreen=0;else{lgreen=1;}}          //東西向綠燈開關(guān)函數(shù)
  25. #define RETURN_RYELLOW {ryellow=~ryellow;}        //南北向黃燈閃爍函數(shù)
  26. #define RETURN_LYELLOW {lyellow=~lyellow;}        //東西向黃燈閃爍函數(shù)
  27. sbit L1=P3^4;
  28. sbit L2=P3^5;


  29. void key_init();
  30. void display();
  31. void vestmode();  
  32. /********************************************************************************************
  33. ************************定時初始化函數(shù)**********************************************************/
  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. ************************以上是定時初始化函數(shù)**********************************************************/

  45. /***************************************************************************************************
  46. ************************以下是延時函數(shù)***************************************************************/
  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. ************************以上是延時函數(shù)***************************************************************/
  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;//開關(guān)紅綠燈秒數(shù)賦值的標(biāo)志位
  69. u16 staticgreen=30;         //固定綠燈值可通過按鍵修改
  70. u16 staticred=10;   //固定紅燈值可通過按鍵修改
  71. u8 NSNUM[3]={40,20,60};        //南北方向紅綠燈秒數(shù)[1]紅燈;[2]右轉(zhuǎn)紅燈;[3]綠燈
  72. u8 EWNUM[3]={60,20,40};        //東西方向紅綠燈秒數(shù)[1]綠燈;[2]紅燈;[3]右轉(zhuǎn)紅燈

  73. /**********************
  74. 這個是定時中斷函數(shù)************/
  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;//南北向黃燈次數(shù)或轉(zhuǎn)換紅綠方向的標(biāo)志
  81. static u16 ewflag=0;//東西向黃燈次數(shù)或轉(zhuǎn)換紅綠方向的標(biāo)志
  82. u16 Rgreen,Lgreen; //Rgreen南北向綠燈滅標(biāo)志        ;Lgreen東西向綠燈滅標(biāo)志;lreturn右轉(zhuǎn)紅燈值(方便修改)




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


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

  86. num++;          //num=20時剛好計(jì)數(shù)是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];}//南北向數(shù)碼管循環(huán)顯示。
  94. if(ewnum==0){if(ewflag>=2){ewflag=0;}else{ewflag++;}ewnum=EWNUM[ewflag];}//東西向數(shù)碼管循環(huán)顯示。
  95. if(nsflag==0||nsflag==1){RRED(1);}//南北向直行或右轉(zhuǎn)時的紅燈
  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);}//東西向直行或右轉(zhuǎn)時的紅燈
  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. /********************上面是定時中斷函數(shù)*******************
  118. *********************************************/

  119. /*這個是按鍵程序*******************************************************
  120. ***************************************************************************/
  121. static u16 modesign[6]={1,2,3};//模式選擇標(biāo)志
  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)//開關(guān)數(shù)碼管顯示按鍵
  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; //第一個數(shù)碼管
  166.                          case 1:LSA=1;LSB=0;LSC=0;P0=dat[0];break; //第二個數(shù)碼管
  167.                          case 2:LSA=0;LSB=1;LSC=0;P0=dat[5];break;//第三個數(shù)碼管
  168.                          case 3:LSA=1;LSB=1;LSC=0;P0=dat[4];break; //第四個數(shù)碼管
  169.                          case 4:LSA=0;LSB=0;LSC=1;P0=dat[7];break; //第五個數(shù)碼管
  170.                          case 5:LSA=1;LSB=0;LSC=1;P0=dat[6];break; //第六個數(shù)碼管
  171.                          case 6:LSA=0;LSB=1;LSC=1;P0=dat[3];break; //第七個數(shù)碼管
  172.                          case 7:LSA=1;LSB=1;LSC=1;P0=dat[2];break; //第八個數(shù)碼管
  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)         //特殊模式后,繼續(xù)按3次,會初始化到正常模式
  194.                     {
  195.                opendis=~opendis;
  196.                            keymode=0;
  197.                            }
  198. }

  199. /***************************************************************************************************
  200. ****************************************************************************************************
  201. ***********************************************************************************************/
復(fù)制代碼

所有程序51hei提供下載:
交通燈.rar (71.28 KB, 下載次數(shù): 8)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表