找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 5240|回復(fù): 3
收起左側(cè)

單片機(jī)交通燈設(shè)計(jì) 含代碼,仿真圖

[復(fù)制鏈接]
ID:790961 發(fā)表于 2020-6-27 14:53 | 顯示全部樓層 |閱讀模式
系統(tǒng)硬件電路由單片機(jī)、狀態(tài)燈、LED顯示、驅(qū)動(dòng)電路、按鍵等組成。選用stc89C51單片機(jī)及外圍器件構(gòu)成最小控制系統(tǒng),12個(gè)發(fā)光二極管分成4組紅綠黃三色燈構(gòu)成信號(hào)燈指示模塊。
1、能模擬基本的交通控制系統(tǒng),用紅綠黃燈表示禁行,通行和等待的信號(hào)發(fā)生。
2、按鍵可以控制深夜模式、禁行、東西通行、南北通行、時(shí)間加、時(shí)間減、切換、確定等功能。
3、共四個(gè)二位陰極數(shù)碼管,利用芯片74hc245芯片驅(qū)動(dòng),東南西北各一個(gè)顯示時(shí)間,共12個(gè)發(fā)光二極管,指示通行狀態(tài)。
1c8869251hei65bc4627ee8a845316920.png
  1.   #include <reg51.h>                     //頭文件
  2. #define uchar unsigned char
  3. #define uint  unsigned int               //宏定義
  4. uchar buf[4];                                  //秒顯示的變量
  5. uchar sec_dx=20;                          //東西數(shù)默認(rèn)
  6. uchar sec_nb=30;                          //南北默認(rèn)值
  7. uchar set_timedx=20;                //設(shè)置東西方向的時(shí)間
  8. uchar set_timenb=30;                //設(shè)置南北方向的時(shí)間
  9. int n;
  10. uchar data countt0,countt1;//定時(shí)器0中斷次數(shù)
  11. //定義6組開(kāi)關(guān)
  12. sbit  k4=P3^7;                //切換方向
  13. sbit  k1=P3^5;                //時(shí)間加
  14. sbit  k2=P3^6;                //時(shí)間減
  15. sbit  k3=P3^4;                //確認(rèn)
  16. sbit  k5=P3^1;                //禁止
  17. sbit  k6=P1^5;                //夜間模式


  18. sbit Red_nb=P2^6;        //南北紅燈標(biāo)志
  19. sbit Yellow_nb=P2^5;     //南北黃燈標(biāo)志
  20. sbit Green_nb=P2^4;      //南北綠燈標(biāo)志

  21. sbit Red_dx=P2^3;         //東西紅燈標(biāo)志
  22. sbit Yellow_dx=P2^2;      //東西黃燈標(biāo)志
  23. sbit Green_dx=P2^1;       //東西綠燈標(biāo)志
  24.         
  25. sbit Buzz=P3^0;               
  26. bit set=0;                          //調(diào)時(shí)方向切換鍵標(biāo)志 =1時(shí),南北,=0時(shí),東西
  27. bit dx_nb=0;                        //東西南北控制位
  28. bit shanruo=0;                      //閃爍標(biāo)志位
  29. bit yejian=0;                       //夜間黃燈閃爍標(biāo)志位

  30. uchar code table[11]={        //共陰極字型碼
  31.                      0x3f,           //--0
  32.                      0x06,           //--1
  33.                      0x5b,           //--2
  34.                      0x4f,           //--3
  35.                      0x66,           //--4
  36.                      0x6d,           //--5
  37.                      0x7d,         //--6
  38.                      0x07,         //--7
  39.                      0x7f,         //--8
  40.                      0x6f,         //--9
  41.                      0x00          //--NULL
  42. };

  43. //函數(shù)的聲明部分
  44. void delay(int ms);                        //延時(shí)子程序
  45. void key();                                //按鍵掃描子程序
  46. void key_to1();                            //鍵處理子程序
  47. void key_to2();
  48. void key_to3();
  49. void display();                            //顯示子程序
  50. void logo();                               //開(kāi)機(jī)LOGO
  51. void Buzzer();
  52. //主程序
  53. void main()
  54. {
  55.         TMOD=0X11;                                           //定時(shí)器設(shè)置
  56.         TH1=(65535-50000)/256;               
  57.         TL1=(65535-50000)%256;
  58.         TH0=(65535-50000)/256;                             //定時(shí)器0置初值 0.05S
  59.         TL0=(65535-50000)%256;
  60.         EA=1;                                                //開(kāi)總中斷
  61.         ET0=1;                                               //定時(shí)器0中斷開(kāi)啟
  62.         ET1=1;                                                //定時(shí)器1中斷開(kāi)啟
  63.         TR0=1;                                                //啟動(dòng)定時(shí)0
  64.         TR1=0;                                                         //關(guān)閉定時(shí)1
  65.         EX0=1;                                                //開(kāi)外部中斷0
  66.         EX1=1;                                                //開(kāi)外部中斷1
  67.     logo();                                                //開(kāi)機(jī)初始化
  68.         P2=0Xc3;                                        // 開(kāi)始默認(rèn)狀態(tài),東西綠燈,南北黃燈   
  69.     sec_nb=sec_dx+5;                         //默認(rèn)南北通行時(shí)間比東西多5秒
  70.         while(1)                                          //主循環(huán)
  71.         {         
  72.                 key();                                         //調(diào)用按鍵掃描程序
  73.                 display();                                 //調(diào)用顯示程序
  74.         }        
  75. }
  76. //函數(shù)的定義部分
  77. void key(void)        //按鍵掃描子程序
  78. {         
  79.         if(k1!=1)                                                        //當(dāng)K1(時(shí)間加)按下時(shí)
  80.         {
  81.                 display();                                       //調(diào)用顯示,用于延時(shí)消抖
  82.                 if(k1!=1)                                                        //如果確定按下
  83.                 {
  84.                           TR0=0;                                               //關(guān)定時(shí)器        
  85.                         shanruo=0;                                        //閃爍標(biāo)志位關(guān)
  86.                         P2=0x00;                                        //滅顯示
  87.                         TR1=0;                                                        //啟動(dòng)定時(shí)1
  88.                         if(set==0)                                        //設(shè)置鍵按下
  89.                                 set_timedx++;                   //南北加1S
  90.                         else
  91.                                 set_timenb++;                    //東西加1S
  92.                         if(set_timenb==100)
  93.                                 set_timenb=1;
  94.                         if(        set_timedx==100)
  95.                                 set_timedx=1;                   //加到100置1
  96.                         sec_nb=set_timenb ;                 //設(shè)置的數(shù)值賦給東西南北
  97.                         sec_dx=set_timedx;                        
  98.                           do
  99.                          {
  100.                                 display();                                 //調(diào)用顯示,用于延時(shí)
  101.                         }
  102.                         while(k1!=1);                         //等待按鍵釋放
  103.                 }
  104.         }

  105.         if(k2!=1)                                                        //當(dāng)K2(時(shí)間減)按鍵按下時(shí)
  106.         {               
  107.                 display();                                       //調(diào)用顯示,用于延時(shí)消抖  
  108.                 if(k2!=1)                                                //如果確定按下
  109.                 {        
  110.                          TR0=0;                                         //關(guān)定時(shí)器0        
  111.                         shanruo=0;                                        //閃爍標(biāo)志位關(guān)
  112.                         P2=0x00;                                        //滅顯示
  113.                         TR1=0;                                                //關(guān)定時(shí)器1        
  114.                         if(set==0)
  115.                                 set_timedx--;                          //南北減1S
  116.                         else
  117.                                 set_timenb--;                          //東西減1S
  118.                         if(set_timenb==0)
  119.                                 set_timenb=99;        
  120.                         if(        set_timedx==0 )
  121.                                 set_timedx=99;                   //減到1重置99
  122.                         sec_nb=set_timenb ;                         //設(shè)置的數(shù)值賦給東西南北
  123.                         sec_dx=set_timedx;
  124.                           do        
  125.                     {
  126.                                 display();                       //調(diào)用顯示,用于延時(shí)
  127.                         }
  128.                         while(k2!=1);                           //等待按鍵釋放
  129.                 }
  130.         }

  131.         if(k3!=1)                                                        //當(dāng)K3(確認(rèn))鍵按下時(shí)
  132.         {        
  133.                 display();                                       //調(diào)用顯示,用于延時(shí)消抖
  134.                 if(k3!=1)                                                //如果確定按下
  135.                 {
  136.                         TR0=1;                                                  //啟動(dòng)定時(shí)器0
  137.                         sec_nb=set_timenb;                                //從中斷回復(fù),仍顯示設(shè)置過(guò)的數(shù)值
  138.                         sec_dx=set_timedx;                                //顯示設(shè)置過(guò)的時(shí)間
  139.                         TR1=0;                                                        //關(guān)定時(shí)器1        
  140.                         if(set==0)                                                //時(shí)間倒時(shí)到0時(shí)
  141.                         {
  142.                                 P2=0X00;                                         //滅顯示
  143.                                 Green_dx=1;                                                //東西綠燈亮
  144.                                 Red_nb=1;                                        //南北紅燈亮
  145.                                 sec_nb=sec_dx+5;                         //回到初值
  146.                         }
  147.                         else
  148.                         {
  149.                                 P2=0x00;                                        //南北綠燈,東西紅燈
  150.                                 Green_nb=1;
  151.                                 Red_dx=1;
  152.                                 sec_dx=sec_nb+5;
  153.                         }
  154.                 }
  155.         }
  156.          
  157.         if(k4!=1)                                                        //當(dāng)K4(切換)鍵按下
  158.     {
  159.                 display();                                       //調(diào)用顯示,用于延時(shí)消抖
  160.                 if(k4!=1)                                                //如果確定按下
  161.                 {  
  162.                          TR0=0;                                                //關(guān)定時(shí)器0        
  163.                         set=!set;                                        //取反set標(biāo)志位,以切換調(diào)節(jié)方向
  164.                         TR1=0;                                                //關(guān)定時(shí)器1
  165.                         dx_nb=set;
  166.                         do
  167.                         {
  168.                                 display();                            //調(diào)用顯示,用于延時(shí)
  169.                         }                                
  170.                         while(k4!=1);                          //等待按鍵釋放
  171.                 }
  172.         }        

  173.         if(k5!=1)                                                        //當(dāng)K5(禁止)鍵按下時(shí)
  174.         {
  175.                    display();                                       //調(diào)用顯示,用于延時(shí)消抖
  176.                    if(k5!=1)                                                //如果確定按下
  177.                    {         
  178.                     TR0=0;                                                //關(guān)定時(shí)器
  179.                         P2=0x00;                                        //滅顯示
  180.                         Red_dx=1;
  181.                         Red_nb=1;                                        //全部置紅燈
  182.                         TR1=0;
  183.                         sec_dx=00;                                        //四個(gè)方向的時(shí)間都為00
  184.                         sec_nb=00;
  185.                         do
  186.                         {
  187.                                 display();                                 //調(diào)用顯示,用于延時(shí)
  188.                         }        
  189.                         while(k5!=1);                        //等待按鍵釋放        
  190.                    }
  191.         }
  192.         if(k6!=1)                                                        //當(dāng)K6(夜間模式)按下
  193.         {
  194.                    display();                                       //調(diào)用顯示,用于延時(shí)消抖
  195.                    if(k6!=1)                                                //如果確定按下
  196.                    {         
  197.                     TR0=0;                                                //關(guān)定時(shí)器
  198.                         P2=0x00;
  199.                         TR1=1;
  200.                         sec_dx=00;                                        //四個(gè)方向的時(shí)間都為00
  201.                         sec_nb=00;
  202.                         do
  203.                         {
  204.                                 display();                           //調(diào)用顯示,用于延時(shí)
  205.                         }        
  206.                         while(k6!=1);                        //等待按鍵釋放        
  207.                    }
  208.         }
  209. }
  210. void display(void) //顯示子程序
  211. {               
  212.         buf[1]=sec_nb/10;                 //第1位 東西秒十位
  213.         buf[2]=sec_nb%10;                 //第2位 東西秒個(gè)位
  214.         buf[3]=sec_dx/10;                 //第3位 南北秒十位
  215.         buf[0]=sec_dx%10;                 //第4位 南北秒個(gè)位               
  216.         P1=0xff;                          // 初始燈為滅的
  217.         P0=0x00;                                 ////滅顯示
  218.         P1=0xfe;                           //片選LED1
  219.         P0=table[buf[1]];                //送東西時(shí)間十位的數(shù)碼管編碼                        
  220.         delay(1);                                //延時(shí)
  221.         P1=0xff;                                //關(guān)顯示
  222.         P0=0x00;                                //滅顯示
  223.                                                    
  224.         P1=0xfd;                     //片選LED2
  225.         P0=table[buf[2]];                 //送東西時(shí)間個(gè)位的數(shù)碼管編碼
  226.         delay(1);                                 //延時(shí)
  227.         P1=0xff;                                //關(guān)顯示
  228.         P0=0x00;                                //關(guān)顯示
  229.         P1=0Xfb;                                  //片選LED3
  230.         P0=table[buf[3]];                //送南北時(shí)間十位的數(shù)碼管編碼
  231.         delay(1);                                //延時(shí)
  232.         P1=0xff;                                 //關(guān)顯示
  233.         P0=0x00;                                 //關(guān)顯示
  234.         P1=0Xf7;                                 //片選LED4        
  235.         P0=table[buf[0]];                //送南北時(shí)間個(gè)位的數(shù)碼管編碼
  236.         delay(1);                                //延時(shí)
  237. }

  238. void time0(void) interrupt 1 using 1          //定時(shí)中斷子程序
  239. {
  240.         TH0=(65535-50000)/256;                                                        //重賦初值
  241.         TL0=(65535-50000)%256;                                                        //12m晶振50ms//重賦初值
  242.         TR0=1;                                                                //重新啟動(dòng)定時(shí)器
  243.         countt0++;                                                        //軟件計(jì)數(shù)加1
  244.         if(countt0==10)                                                //加到10也就是半秒
  245.         {
  246.                 if((sec_nb<=5)&&(dx_nb==0)&&(shanruo==1))                  //東西黃燈閃               
  247.         {
  248.                         Green_dx=0;
  249.                         Yellow_dx=0;
  250.                         Buzz=0;                                                //蜂鳴器關(guān)
  251.                 }                                                   
  252.             if((sec_dx<=5)&&(dx_nb==1)&&(shanruo==1))                  //南北黃燈閃               
  253.         {  
  254.                         Green_nb=0;
  255.                         Yellow_nb=0;
  256.                         Buzz=0;                                           //蜂鳴器關(guān)
  257.                 }        
  258.         }
  259.                
  260.         if(countt0==20)                                  // 定時(shí)器中斷次數(shù)=20時(shí)(即1秒時(shí))
  261.         {        countt0=0;                                                //清零計(jì)數(shù)器
  262.                 sec_dx--;                                                //東西時(shí)間減1
  263.                 sec_nb--;                                                //南北時(shí)間減1

  264.                 if((sec_nb<=5)&&(dx_nb==0)&&(shanruo==1))                  //東西黃燈閃               
  265.         {
  266.                         Green_dx=0;
  267.                         Yellow_dx=1;
  268.                         Buzz=1;                                                 //蜂鳴器關(guān)
  269.                 }                                                   
  270.             if((sec_dx<=5)&&(dx_nb==1)&&(shanruo==1))                  //南北黃燈閃               
  271.         {  
  272.                         Green_nb=0;
  273.                         Yellow_nb=1;
  274.                         Buzz=1;                                                 //蜂鳴器關(guān)
  275.                 }                                                                 
  276.                 if(sec_dx==0&&sec_nb==5)                 //當(dāng)東西倒計(jì)時(shí)到0時(shí),重置5秒,用于黃燈閃爍時(shí)間   
  277.                 {
  278.                         sec_dx=5;
  279.                         shanruo=1;
  280.                 }
  281.                 if(sec_nb==0&&sec_dx==5)                //當(dāng)南北倒計(jì)時(shí)到0時(shí),重置5秒,用于黃燈閃爍時(shí)間   
  282.                 {
  283.                         sec_nb=5;
  284.                         shanruo=1;
  285.                 }
  286.                 if(dx_nb==0&&sec_nb==0)                        //當(dāng)黃燈閃爍時(shí)間倒計(jì)時(shí)到0時(shí),
  287.                 {
  288.                      Buzz=1;                                                //蜂鳴器開(kāi)
  289.                         P2=0x00;                                        //重置東西南背方向的紅綠燈
  290.                         Green_nb=1;
  291.                         Red_dx=1;
  292.                         dx_nb=!dx_nb;
  293.                         shanruo=0;
  294.                         sec_nb=set_timenb;                        //重賦南北方向的起始值
  295.                         sec_dx=set_timenb+5;                //重賦東西方向的起始值
  296.                 }               
  297.                 if(dx_nb==1&&sec_dx==0)                        //當(dāng)黃燈閃爍時(shí)間到
  298.                 {
  299.                         P2=0X00;                                        //重置東西南北的紅綠燈狀態(tài)
  300.                         Green_dx=1;                                         //東西綠燈亮
  301.                         Red_nb=1;                                         //南北紅燈亮
  302.                         dx_nb=!dx_nb;                                 //取反
  303.                         shanruo=0;                                        //閃爍
  304.                         sec_dx=set_timedx;                        //重賦東西方向的起始值
  305.                         sec_nb=set_timedx+5;                //重賦南北方向的起始值
  306.                 }
  307.         }        
  308. }
  309. void time1(void) interrupt 3         //定時(shí)中斷子程序
  310. {
  311.         TH1=(65535-50000)/256;                                                        //重賦初值
  312.         TL1=(65535-50000)%256;                                                        //12m晶振50ms//重賦初值
  313.         countt1++;                                                        //軟件計(jì)數(shù)加1
  314.         if(countt1==10)                                           // 定時(shí)器中斷次數(shù)=10時(shí)(即0.5秒)
  315.         {
  316.                         Yellow_nb=0;                                //南北黃燈滅
  317.                         Yellow_dx=0;                                //東西黃燈滅
  318.         }
  319.         if(countt1==20)                                  // 定時(shí)器中斷次數(shù)=20時(shí)(即1秒時(shí))
  320.         {        countt1=0;                                                //清零計(jì)數(shù)器
  321.                         Yellow_nb=1;                                        //南北黃燈亮
  322.                         Yellow_dx=1;                                  //東西黃燈亮
  323.         }        
  324. }


  325. //外部中斷0
  326. void int0(void) interrupt 0 using 1           //只允許東西通行
  327. {
  328.         TR0=0;                                                                //關(guān)定時(shí)器0
  329.         TR1=0;                                                                //關(guān)定時(shí)器1
  330.         P2=0x00;                                                        //滅顯示
  331.         Green_dx=1;                                                        //東西方向置綠燈
  332.         Red_nb=1;                                                        //南北方向?yàn)榧t燈
  333.         sec_dx=00;                                                        //四個(gè)方向的時(shí)間都為00
  334.         sec_nb=00;        
  335. }

  336. //外部中斷1
  337. void int1(void) interrupt 2 using 1                   //只允許南北通行
  338. {
  339.         TR0=0;                                                                //關(guān)定時(shí)器0
  340.         TR1=0;                                                           //關(guān)定時(shí)器1
  341.         P2=0x00;                                                        //滅顯示
  342.         Green_nb=1;                                                        //置南北方向?yàn)榫G燈
  343.         Red_dx=1;                                                        //東西方向?yàn)榧t燈
  344.         sec_nb=00;                                                        //四個(gè)方向的時(shí)間都為00
  345.         sec_dx=00;
  346. }
  347. void logo()//開(kāi)機(jī)的Logo  "- - - -"
  348. {
  349.         for(n=0;n<50;n++)        //循環(huán)顯示----50次
  350.            {
  351.             P0=0x40;  //送形“-”
  352.             P1=0xfe;        //第一位顯示
  353.                 delay(1);        //延時(shí)
  354.             P1=0xfd;        //第二位顯示
  355.                 delay(1);        //延時(shí)
  356.                 P1=0Xfb;        //第三位顯示
  357.                 delay(1);        //延時(shí)
  358.                 P1=0Xf7;        //第四位顯示
  359.                 delay(1);        //延時(shí)
  360.             P1 = 0xff;        //滅顯示
  361.         }
  362. }

  363. void delay(int ms)                //延時(shí)子程序
  364. {
  365.         uint j,k;
  366.         for(j=0;j<ms;j++)                        //延時(shí)ms
  367.            for(k=0;k<124;k++);                //大約1毫秒的延時(shí)
復(fù)制代碼



交通燈.zip

27.46 KB, 下載次數(shù): 130, 下載積分: 黑幣 -5

回復(fù)

使用道具 舉報(bào)

ID:795830 發(fā)表于 2020-7-4 20:39 | 顯示全部樓層
為什么不能顯示剩余時(shí)間呀?大神  求解
回復(fù)

使用道具 舉報(bào)

ID:752566 發(fā)表于 2020-7-8 17:28 | 顯示全部樓層
大神寫(xiě)的很不錯(cuò)。注釋也很棒,
回復(fù)

使用道具 舉報(bào)

ID:797070 發(fā)表于 2020-7-9 17:12 | 顯示全部樓層
大神,為甚么我下載你的程序,所有的燈都是亮的,摁開(kāi)關(guān)也沒(méi)有變化?

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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