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

QQ登錄

只需一步,快速開始

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

51單片機(jī)交通燈仿真與實(shí)物 源程序注釋十分詳細(xì)

  [復(fù)制鏈接]
ID:208154 發(fā)表于 2017-6-5 19:52 | 顯示全部樓層 |閱讀模式
51單片機(jī)交通燈的實(shí)物圖:
0.png 0.png

本proteus仿真文件是proteus7.4版本創(chuàng)建的,請(qǐng)用7.4版本或更高版本打開,較低版本可能出現(xiàn)無(wú)法打開的現(xiàn)象。
0.png

0.png 0.png

單片機(jī)源程序如下:
  1. /***************51單片機(jī)交通燈設(shè)計(jì)*******************/

  2. #include <reg52.h>
  3. #include <intrins.h>
  4. #define        uint unsigned int
  5. #define uchar unsigned char
  6. uchar night_flag=0;                                //深夜標(biāo)志位
  7. uchar time_cl=0;                                //定義時(shí)間控制標(biāo)志位  取0        
  8. uchar flag=0;                                        //方向通行標(biāo)志位
  9. uchar B_N_D_flag=1;                                //定義北南通燈行標(biāo)志位
  10. uchar X_D_D_flag=1;                                //定義西東通燈行標(biāo)志位
  11. uchar i,j;                                                //定義變量i
  12. uchar t=3;                                                //數(shù)碼管動(dòng)態(tài)掃描延時(shí)時(shí)間基數(shù)
  13. uchar num=0;                                        //時(shí)間基數(shù)初始化為0
  14. //uchar num_night=0;                                //深夜模式時(shí)間基數(shù)為0
  15. uchar time=30;                                        //time初始化定為30秒
  16. int bei,nan,xi,dong;            //定義  北  南  西  東
  17. uchar code Data[]={0x18,0x7B,0x89,0x49,0x6A,0x4C,0x0C,0x79,0x08,0x48,0xEF};
  18. //定義數(shù)組  數(shù)碼管   0    1    2    3    4    5    6    7    8    9    -
  19. /***************定義  紅黃綠燈**************/
  20. sbit    B_R=P1^2;                                //北面  紅燈
  21. sbit    B_Y=P1^1;                                //北面  黃燈
  22. sbit    B_G=P1^0;                                //北面        綠燈
  23. sbit    N_R=P2^0;                                //南面        紅燈
  24. sbit    N_Y=P2^1;                                //南面        黃燈
  25. sbit        N_G=P2^2;                                //南面        綠燈
  26. sbit    X_R=P2^5;//西面        紅燈
  27. sbit    X_Y=P2^6;                                //西面        黃燈
  28. sbit    X_G=P2^7;                                //西面        綠燈

  29. sbit    D_R=P3^7;                                //東面  紅燈
  30. sbit    D_Y=P3^6;                                //東面        黃燈
  31. sbit    D_G=P3^5;                                //東面  綠燈

  32. sbit    s1=P3^4;//時(shí)間減
  33. sbit    s2=P3^3;//時(shí)間加
  34. sbit    s3=P3^1;//白天和夜間模式控制切換口
  35. sbit    s4=P3^2;//進(jìn)入時(shí)間可以設(shè)置狀態(tài)的切換口
  36. /***************定義  數(shù)碼管*****************/
  37. #define        SMG_XS        P0                                //數(shù)碼管數(shù)據(jù)顯示
  38. #define        SMG_KZ        P2                                //數(shù)碼管控制顯示
  39. sbit   smg1=P2^4;//定義數(shù)碼管1控制口
  40. sbit   smg2=P2^3;//定義數(shù)碼管2控制口
  41. void delay(uint time);// 定義延時(shí)程序
  42. void disp_init();//顯示初始化
  43. void disp(bei,nan,xi,dong);




  44. void Time0_init()                                //定時(shí)器0初始化函數(shù)
  45. {
  46.         TMOD=0x01;                                        //定時(shí)器0為方式1
  47.         TL0=(65536-50000)%256;
  48.         TH0=(65536-50000)/256;                //12M晶振 定時(shí)時(shí)間50ms
  49.         ET0=1;                                                //開定時(shí)器0中斷
  50.         EA=1;                                                //開總中斷
  51.         TR0=1;                                                //啟動(dòng)定時(shí)器0
  52. }

  53. void night_mode()                                //深夜模式
  54. {
  55.         B_R=1;
  56.         B_Y=~B_Y;                                        //北 黃燈取反
  57.         B_G=1;
  58.         N_R=1;
  59.         N_Y=~N_Y;                                        //南 黃燈取反
  60.         N_G=1;

  61.         X_R=1;                                       
  62.         X_Y=~X_Y;                                        //西 黃燈取反
  63.         X_G=1;
  64.         D_R=1;
  65.         D_Y=~D_Y;                                        //東 黃燈取反
  66.         D_G=1;        
  67. }

  68. void B_N_G()                                        //北南通(綠燈)  西東(紅燈)                        
  69. {
  70.         B_G=0;                                                //北  綠燈亮
  71.         N_G=0;                                                //南  綠燈亮
  72.         B_R=1;
  73.         B_Y=1;
  74.         N_R=1;
  75.         N_Y=1;

  76.         X_R=0;                                                //西  紅燈亮
  77.         D_R=0;                                                //東  紅燈亮
  78.         X_Y=1;
  79.         X_G=1;
  80.         D_Y=1;
  81.         D_G=1;
  82. }

  83. void X_D_G()                                        //西東通(綠燈)  北南(紅燈)                        
  84. {
  85.         B_G=1;
  86.         N_G=1;
  87.         B_R=0;                                                //北  紅燈亮
  88.         B_Y=1;
  89.         N_R=0;                                                //南  紅燈亮
  90.         N_Y=1;

  91.         X_R=1;
  92.         D_R=1;
  93.         X_Y=1;
  94.         X_G=0;                                                //西  綠燈亮
  95.         D_Y=1;
  96.         D_G=0;                                                //東  綠燈亮
  97. }

  98. void B_N_tong()                                        //北南 通行
  99. {
  100.         if(B_N_D_flag==1)                        //當(dāng)北南通燈行標(biāo)志位為1
  101.         {
  102.                 B_N_G();                                //北南通(綠燈)  西東(紅燈)
  103.                 B_N_D_flag=0;                        //北南通燈行標(biāo)志位置0
  104.         }
  105.         while(num==20)                                //當(dāng)1s時(shí)間到
  106.         {
  107.                 num=0;                                        //num清0
  108.                 bei--;                                        //北時(shí)間 減1
  109.                 nan--;                                        //南時(shí)間 減1
  110.                 xi--;                                        //西時(shí)間 減1
  111.                 dong--;                                        //東時(shí)間 減1
  112.                 if(bei<=6&&bei>=0||nan<=6&&nan>=0)                //當(dāng)北和南時(shí)間在0到6秒之間
  113.                 {
  114.                         if(bei<=6&&bei>3||nan<=6&&nan>3)        //進(jìn)一步判斷北和南時(shí)間是否在3到6秒之間
  115.                         {
  116.                                 B_G=~B_G;                                                //北  綠燈取反
  117.                                 N_G=~N_G;                                                //南  綠燈取反
  118.                         }
  119.                         if(bei<=3&&nan<=3)                                        //進(jìn)一步判斷北和南時(shí)間是否在3秒以內(nèi)
  120.                         {
  121.                                 B_G=1;                                                        //北  綠燈不亮
  122.                                 N_G=1;                                                        //南  綠燈不亮
  123.                                 B_Y=0;                                                        //北  黃燈亮
  124.                                 N_Y=0;                                                        //南  黃燈亮
  125.                         }
  126.                 }
  127.                 else                                                                        //否則(即北和南時(shí)間不在0到6秒之間)
  128.                 {
  129.                         B_G=0;                                                                //北  綠燈亮
  130.                         N_G=0;                                                                //南  綠燈亮
  131.                         B_Y=1;                                                                //北  黃燈不亮
  132.                         N_Y=1;                                                                //南  黃燈不亮
  133.                 }
  134.         }
  135. }

  136. void X_D_tong()                                                                        //西東  通行
  137. {
  138.         if(X_D_D_flag==1)                                                        //當(dāng)西東通燈行標(biāo)志位為1
  139.         {
  140.                 X_D_G();                                                                //西東通(綠燈)  北南(紅燈)
  141.                 X_D_D_flag=0;                                                        //西東通燈行標(biāo)志位置0
  142.         }
  143.         while(num==20)                                                                //當(dāng)1s時(shí)間到
  144.         {
  145.                 num=0;                                                                        //num清0
  146.                 bei--;                                                                        //北時(shí)間 減1
  147.                 nan--;                                                                        //南時(shí)間 減1               
  148.                 xi--;                                                                        //西時(shí)間 減1
  149.                 dong--;                                                                        //東時(shí)間 減1        
  150.                 if(xi<=6&&xi>=0||dong<=6&&xi>=0)                //當(dāng)西和東時(shí)間在0到6秒之間
  151.                 {
  152.                         if(xi<=6&&xi>3||dong<=6&&dong>3)        //進(jìn)一步判斷西和東時(shí)間是否在3到6秒之間
  153.                         {
  154.                                 X_G=~X_G;                                                //西  綠燈取反
  155.                                 D_G=~D_G;                                                //東  綠燈取反
  156.                         }
  157.                         if(xi<=3&&dong<=3)                                        //進(jìn)一步判斷西和東時(shí)間是否在3秒以內(nèi)
  158.                         {
  159.                                 X_G=1;                                                        //西  綠燈不亮
  160.                                 D_G=1;                                                        //東  綠燈不亮
  161.                                 X_Y=0;                                                        //西  黃燈亮
  162.                                 D_Y=0;                                                        //東  黃燈亮
  163.                         }
  164.                 }
  165.                 else                                                                        //否則(即西和東時(shí)間不在0到6秒之間)
  166.                 {
  167.                         X_G=0;                                                                //西  綠燈亮
  168.                         D_G=0;                                                                //東  綠燈亮
  169.                         X_Y=1;                                                                //西  黃燈不亮
  170.                         D_Y=1;//東  黃燈不亮        
  171.                 }
  172.         }               
  173. }

  174. void Time0() interrupt 1                                                //定時(shí)器0中斷服務(wù)函數(shù)
  175. {
  176.         TH0=(65536-50000)/256;                                                //重新載裝初值,設(shè)置50ms中斷一次
  177.         TL0=(65536-50000)%256;
  178.         num++;                                                                                //時(shí)間基數(shù)加1
  179. }
  180.                
  181. void main()                                                                                //主函數(shù)入口                                                                                       
  182. {
  183.         bei=nan=xi=dong=time;                                                //把time值賦給北 南 西 東
  184.         disp_init();                        //顯示初始化
  185.         Time0_init();                //定時(shí)器0初始化函數(shù)               
  186.         while(1)                //無(wú)限循環(huán)
  187.         {  
  188.                 if(s4==0)                                                                //當(dāng)P3.0按下(調(diào)整時(shí)間允許鍵)
  189.                 {
  190.                         delay(5);                                                        //延時(shí)去抖
  191.                         s4=1;                                                //關(guān)閉數(shù)碼管顯示
  192.                         if(s4==0)                                                    //再次確定按鍵是否按下
  193.                         {
  194.                                 time_cl=~time_cl;//時(shí)間控制標(biāo)志位取反(開/關(guān)時(shí)間控制標(biāo)志位)        
  195.                                 if(time_cl==0)                                        //如果時(shí)間控制標(biāo)志位為0
  196.                                 {
  197.                                         TL0=(65536-50000)%256;
  198.                                         TH0=(65536-50000)/256;                //12M晶振 定時(shí)時(shí)間50ms
  199.                                         TR0=1;                                                //開啟定時(shí)器0
  200.                                         num=0;                                                //num初始化為0        
  201.                                 }        
  202.                         }        
  203.                         while(s4==0);                                                //等待按鍵松開
  204.                 }
  205.                
  206.                 if(s3==0)                                                                //當(dāng)P3.7按下(開/關(guān) 深夜模式)
  207.                 {
  208.                         delay(5);                                                        //延時(shí)去抖
  209.                     s3=1;                                                //關(guān)閉數(shù)碼管顯示
  210.                         if(s3==0)
  211.                         {
  212.                                 night_flag=~night_flag;                        //深夜標(biāo)志位取反(開/關(guān)深夜模式),1表示開,0表示關(guān)
  213.                                 if(night_flag==1)                                //如果深夜模式開
  214.                                 {
  215.                                         TR0=0;                                                //關(guān)閉定時(shí)器0
  216.                                         num=0;                                                //時(shí)間基數(shù)清0
  217.                                         TL0=(65536-50000)%256;
  218.                                         TH0=(65536-50000)/256;                //12M晶振 定時(shí)時(shí)間50ms
  219.                                         TR0=1;                                                //開啟定時(shí)器0
  220.                                         SMG_KZ=0xff;                                //關(guān)閉數(shù)碼管顯示        
  221.                                 }
  222.                                 else                                                         //否則night_flag=0表示深夜模式關(guān)(紅綠燈正常運(yùn)行)                                       
  223.                                 {
  224.                                         TR0=0;                                                //關(guān)閉定時(shí)器0
  225.                                         num=0;                                                //時(shí)間基數(shù)清0
  226.                                         TL0=(65536-50000)%256;
  227.                                         TH0=(65536-50000)/256;                //12M晶振 定時(shí)時(shí)間50ms
  228.                                         TR0=1;                                                //開啟定時(shí)器0
  229.                                         B_N_D_flag=1;                                //定義北南通燈行標(biāo)志位
  230.                                         X_D_D_flag=1;                                //定義西東通燈行標(biāo)志位        
  231.                                         if(bei<=3&&nan<=3)                        //判斷北和南時(shí)間是否在3秒以內(nèi)
  232.                                         {
  233.                                                 B_Y=1;
  234.                                                 N_Y=1;
  235.                                         }
  236.                                         if(xi<=3&&dong<=3)                        //判斷西和東時(shí)間是否在3秒以內(nèi)
  237.                                         {
  238.                                                 X_Y=1;
  239.                                                 D_Y=1;
  240.                                         }                                
  241.                                 }
  242.                         }
  243.                         while(s3==0);                                                                        
  244.                 }
  245.                 if(night_flag==0)                                                //如果深夜標(biāo)志位為0,表示關(guān)閉深夜模式,紅綠燈正常運(yùn)行
  246.                 {
  247.                         if(time_cl==0)                                                        //如果time_cl=0(不允許調(diào)整時(shí)間),即紅綠燈正常運(yùn)行
  248.                         {        
  249.                                 if(flag==0)                                                        //flag=0表示北南通行允許
  250.                                 {
  251.                                         B_N_tong();                                                //北南 通行
  252.                                         if(bei==0)                                                //北南通行時(shí)間到
  253.                                         {
  254.                                                 flag=~flag;                                        //西東 通行允許
  255.                                                 B_N_D_flag=1;                                //北南通燈行標(biāo)志位置1
  256.                                         }
  257.                                 }
  258.                                 else                                                                //flag=1表示西東通行允許
  259.                                 {
  260.                                         X_D_tong();                                                //西東 通行
  261.                                         if(xi==0)                                                //西東通行時(shí)間到
  262.                                         {
  263.                                                 flag=~flag;                                        //北南 通行允許
  264.                                                 X_D_D_flag=1;                                //西東通燈行標(biāo)志位置1
  265.                                         }
  266.                                 }
  267.         
  268.                                 disp(bei,nan,xi,dong);                                //顯示時(shí)間數(shù)據(jù)
  269.                                 if(bei==0&&nan==0&&xi==0&&dong==0)        //如果 北 南 西 東時(shí)間到(為0)
  270.                                 {
  271.                                         TR0=0;                                                        //關(guān)閉定時(shí)器0
  272.                                         TL0=(65536-50000)%256;                        
  273.                                         TH0=(65536-50000)/256;                        //12M晶振 定時(shí)時(shí)間50ms
  274.                                         for(j=0;j<3;j++)                                //延時(shí)顯示閃爍3下
  275.                                         {
  276.                                                 for(i=0;i<10;i++)                        //for語(yǔ)句延時(shí)
  277.                                                 {
  278.                                                         disp(bei,nan,xi,dong);  //顯示函數(shù)
  279.                                                 
  280.                                                 }
  281.                                                 SMG_KZ=0xff;                                //關(guān)閉顯示
  282.                                                 delay(200);                                        //延時(shí)一下
  283.                                         }
  284.                                         bei=time;                                                //time值賦給北
  285.                                         nan=time;                                                //time值賦給南
  286.                                         xi=time;                                                //time值賦給西
  287.                                         dong=time;                                                //time值賦給東
  288.                                         TR0=1;                                                        //開啟定時(shí)器0
  289.                                 }
  290.                                 else                                                                //否則
  291.                                 {}                                                                        //空操作
  292.                         }
  293.                         else                                                                        //如果time_cl==1(允許時(shí)間調(diào)整)
  294.                         {
  295.                                 TR0=0;                                                                //關(guān)閉定時(shí)器
  296.                                 TL0=(65536-50000)%256;
  297.                                 TH0=(65536-50000)/256;                                //12M晶振 定時(shí)時(shí)間50ms
  298.                                 num=0;                                                                //時(shí)間基數(shù)清0
  299.                                 bei=nan=xi=dong=time;                                //time值賦給 北 南 西 東
  300.                                 disp(bei,nan,xi,dong);                                //顯示時(shí)間數(shù)據(jù)
  301.                                 if(s2==0)                                                        //當(dāng)P3.1按鍵按下(操作時(shí)間加1)
  302.                                 {
  303.                                         delay(5);                                                //延時(shí)去抖
  304.                                         if(s2==0)                                                //再次確定按鍵是否按下
  305.                                         {
  306.                                                 time++;                                                //時(shí)間加1
  307.                                         }        
  308.                                         while(s2==0);                                        //等待按鍵松開        
  309.                                 }
  310.                                 if(bei==100&&nan==100&&xi==100&&dong==100)        //如果北 南 西 東 時(shí)間到100
  311.                                 {        
  312.                                         time=1;                                                        //time等于1
  313.                                 }
  314.                                 if(s1==0)                                                        //當(dāng)P3.6按鍵按下(操作時(shí)間減1)               
  315.                                 {                                                                                
  316.                                         delay(5);                                                //延時(shí)去抖
  317.                                         if(s1==0)                                                //再次確定按鍵是否按下
  318.                                         {
  319.                                                 time--;                                                //time減1
  320.                                         }
  321.                                         while(s1==0);                                        //等待按鍵松開
  322.                                 }
  323.                                 if(bei==0&&nan==0&&xi==0&&dong==0)        //如果北 南 西 東 時(shí)間到0
  324.                                 {
  325.                                         time=99;                                                //time等于99
  326.                                 }        
  327.                         }
  328.                 }
  329.                 else                                                                                //否則深夜標(biāo)志位為1,表示開啟深夜模式
  330.                 {               
  331.                         if(num==20)                                                                //當(dāng)1s時(shí)間到
  332.                         {
  333.                                 num=0;                                                                //50ms時(shí)間基數(shù)清0
  334.                                 night_mode();                                                //深夜模式
  335.                         }                                
  336.                 }
  337.   //  disp(69,69,69,69);                        
  338.         }
  339.    
  340. }






  341. void disp(bei,nan,xi,dong)                 //顯示(北 南 西 東)時(shí)間函數(shù)
  342. {
  343.         SMG_XS=Data[bei/10];                //顯示北的十位
  344.         smg1=0;                                //允許北十位顯示
  345.         delay(t);                                        //小延時(shí)一下,使數(shù)碼管顯示更清楚
  346.     smg1=1;                        //關(guān)閉數(shù)碼管顯示(消隱)
  347.         SMG_XS=Data[bei%10];                //顯示北的個(gè)位
  348.         smg2=0;                        //允許北個(gè)位顯示
  349.     delay(t);                                        //小延時(shí)一下,使數(shù)碼管顯示更清楚
  350.         smg2=1;                        //關(guān)閉數(shù)碼管顯示(消隱)        
  351.         SMG_XS=Data[nan/10];                //顯示南的十位        
  352. //SMG_KZ=0xf7;                                //允許南十位顯示
  353.     smg1=0;
  354.           delay(t);                                        //小延時(shí)一下,使數(shù)碼管顯示更清楚
  355.         smg1=1;
  356.     //SMG_KZ=0xff;                                //關(guān)閉數(shù)碼管顯示(消隱)
  357.         SMG_XS=Data[nan%10];                //顯示南的個(gè)位
  358.         //SMG_KZ=0xfb;                                //允許南個(gè)位顯示
  359.     smg2=0;        
  360.     delay(t);                                        //小延時(shí)一下,使數(shù)碼管顯示更清楚
  361.         //SMG_KZ=0xff;                                //關(guān)閉數(shù)碼管顯示(消隱)
  362.     smg2=1;
  363.         SMG_XS=Data[xi/10];                        //顯示西的十位        
  364.   //        SMG_KZ=0xdf;                                //允許西十位顯示
  365.         smg1=0;
  366.     delay(t);                                        //小延時(shí)一下,使數(shù)碼管顯示更清楚
  367.         smg1=1;
  368.     //SMG_KZ=0xff;                                //關(guān)閉數(shù)碼管顯示(消隱)
  369.         SMG_XS=Data[xi%10];                        //顯示西的個(gè)位
  370.         smg2=0;
  371.     //SMG_KZ=0xef;                                //允許西個(gè)位顯示
  372.         delay(t);                                        //小延時(shí)一下,使數(shù)碼管顯示更清楚
  373.         smg2=1;
  374.     //SMG_KZ=0xff;                                //關(guān)閉數(shù)碼管顯示(消隱)

  375.         SMG_XS=Data[dong/10];                //顯示東的十位               
  376.         smg1=0;
  377.     //SMG_KZ=0x7f;                                //允許東十位顯示
  378.         delay(t);                                        //小延時(shí)一下,使數(shù)碼管顯示更清楚
  379.         smg1=1;
  380.     //SMG_KZ=0xff;                                //關(guān)閉數(shù)碼管顯示(消隱)
  381.         SMG_XS=Data[dong%10];                //顯示東的個(gè)位
  382.         smg2=0;//
  383. ……………………

  384. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:
ID216 模塊相關(guān)資料 交通燈.zip (794.82 KB, 下載次數(shù): 90)


評(píng)分

參與人數(shù) 3黑幣 +15 收起 理由
阿玲玲玲 + 5 回帖助人的獎(jiǎng)勵(lì)!
bhbsh + 5 贊一個(gè)!
cccchen + 5 很給力!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:1 發(fā)表于 2017-6-6 04:07 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

ID:208951 發(fā)表于 2017-6-12 15:59 | 顯示全部樓層
贊一個(gè)
回復(fù)

使用道具 舉報(bào)

ID:72444 發(fā)表于 2017-6-20 12:03 | 顯示全部樓層
贊一個(gè)
回復(fù)

使用道具 舉報(bào)

ID:321448 發(fā)表于 2018-7-12 13:53 | 顯示全部樓層
非常好的資料
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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