久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8077|回復: 2
收起左側

51單片機交通信號燈Proteus仿真小制作(程序注釋很詳細)

[復制鏈接]
ID:317366 發表于 2019-6-1 23:16 | 顯示全部樓層 |閱讀模式
一個在科技節上的小制作交通信號燈仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png

單片機源程序如下:
  1. #include <reg52.h>                  //調用單片機頭文件
  2. #define uchar unsigned char   //宏定義"uchar"代替"unsigned char"。
  3. #define uint  unsigned int          //宏定義"uint"用來定義無符號整型數。
  4. #define LED_a                0                  //數碼管段選的a段接在段選IO口的第0位
  5. #define LED_b                1
  6. #define LED_c                2
  7. #define LED_d                3
  8. #define LED_e                4
  9. #define LED_f                5
  10. #define LED_g                6
  11. #define LED_dp                7

  12. uchar code DisplayOther[]={
  13.         0xff,                         //0                空
  14.         0x7f,                         //1                "."
  15.         0xbf,                        //2                "-"
  16.         0xa7                        //3                c
  17. };

  18. //數碼管段選定義        0        1        2        3        4        5        6        7        8        9
  19. uchar code smg_du[10] = {
  20.         0xc0,                //0
  21.         0xf9,                //1
  22.         0xa4,                //2
  23.         0xb0,                //3
  24.         0x99,                //4
  25.         0x92,                //5
  26.         0x82,                //6
  27.         0xf8,                //7
  28.         0x80,                //8
  29.         0x90,                //9
  30. };               
  31. uchar dis_smg[4] = {0xc0,0xf5,0x8c,0x94};               

  32. //數碼管位選定義
  33. sbit smg1 = P2^0;            //東西數碼管2
  34. sbit smg2 = P2^1;            //東西數碼管1
  35. sbit smg3 = P2^2;                //南北數碼管2
  36. sbit smg4 = P2^3;                //南北數碼管1

  37. char count = 0;        //東西  南北 倒計時變量

  38. sbit nb_red    = P1^0;                //南北紅燈
  39. sbit nb_green  = P1^2;                //南北綠燈
  40. sbit nb_yellow = P1^1;                //南北黃燈

  41. sbit dx_red    = P1^3;            //東西紅燈
  42. sbit dx_green  = P1^5;                //東西綠燈
  43. sbit dx_yellow = P1^4;                //東西黃燈

  44. uchar flag_jtd_mode;    //交通燈的模式 根據時間
  45. bit flag_1s = 1;                //進入南北方向切換的標志位
  46. bit flag_500ms;
  47. bit flag_dx_nb;                    //東西南北模式
  48. uchar flag_5m_value;
  49. uchar dx_time = 30,nb_time = 30;   //東西、南北的時間
  50. uchar flag_jdgz ;     //交通管制

  51. /********************************************************************
  52. * 名稱 : uchar ChangeFor(uchar dat)
  53. * 功能 : 交換一個字節位的位置,用于數碼管顯示
  54. * 輸入 : 需要改變的數
  55. * 輸出 : 改變后的數
  56. ***********************************************************************/


  57. uchar ChangeFor(uchar dat){
  58.         uchar temp=0;
  59.         if(dat&0x01)        
  60.                 temp|=0x01<<LED_a;
  61.         if(dat&0x02)
  62.                 temp|=0x01<<LED_b;
  63.         if(dat&0x04)
  64.                 temp|=0x01<<LED_c;
  65.         if(dat&0x08)
  66.                 temp|=0x01<<LED_d;
  67.         if(dat&0x10)
  68.                 temp|=0x01<<LED_e;
  69.         if(dat&0x20)
  70.                 temp|=0x01<<LED_f;
  71.         if(dat&0x40)
  72.                 temp|=0x01<<LED_g;
  73.         if(dat&0x80)
  74.                 temp|=0x01<<LED_dp;
  75.         return temp;
  76. }

  77. /***********************數碼管位選函數*****************************/
  78. void smg_we_switch(uchar i){
  79.         switch(i){
  80.                 case 0: smg1 = 0;  smg2 = 1; smg3 = 1;  smg4 = 1; break;
  81.                 case 1: smg1 = 1;  smg2 = 0; smg3 = 1;  smg4 = 1; break;
  82.                 case 2: smg1 = 1;  smg2 = 1; smg3 = 0;  smg4 = 1; break;
  83.                 case 3: smg1 = 1;  smg2 = 1; smg3 = 1;  smg4 = 0; break;
  84.         }        
  85. }

  86. /****************************延時1ms函數****************************/
  87. void delay_1ms(uint q){
  88.         uint i,j;
  89.         for(i=0;i<q;i++)
  90.                 for(j=0;j<110;j++);
  91. }

  92. /***************************數碼管顯示函數*****************************/
  93. void DisplayScan(){
  94.         static uchar i;
  95.         {
  96.                 {               
  97.                 P0 = 0xff;                  //消隱     
  98.                         smg_we_switch(i);                                    //位選
  99.                 P0 = ChangeFor(dis_smg[i]);                  //段選         
  100.                 delay_1ms(3);
  101.                 }
  102.                 i++;
  103.                 if(i>=4)
  104.                         i=0;
  105.         }
  106. }

  107. /*********************定時器0、定時器1初始化******************/
  108. void time0_init(){         
  109.         TMOD = 0x01;                    //設置定時器0為工作模式1 (16-bit)
  110.         TL0 = 15536;                    //給定時器低位賦初始值                65536-15536=50000us=50ms,即50ms一個中斷
  111.         TH0 = 15536 >> 8;               //給定時器高位賦初始值
  112.         TR0 = 1;                        //開啟定時器0
  113.         ET0 = 1;                        //允許定時器0中斷
  114.         EA = 1;                         //開啟全局中斷
  115. }

  116. /*********************交通燈處理函數*********************************/
  117. void traffic_light_dispose(){
  118.         if(flag_1s == 1){//如果切換標志為1
  119.                 flag_1s = 0;        //清零標志位
  120.                 if(count == 0){
  121.                         if(flag_dx_nb == 1)
  122.                                 count = nb_time;          //南北時間
  123.                         else
  124.                                 count = dx_time;          //東西時間
  125.                         flag_dx_nb = ~flag_dx_nb;                //切換南北時間
  126.                 }
  127.                 count --;
  128.         }

  129. /***********************南北時間*********************************/
  130.                 if(flag_dx_nb == 0){  
  131.                         if(count > 3){
  132.                                 
  133.                                 dis_smg[0] = smg_du[count % 10] ;
  134.                                 dis_smg[1] = smg_du[count / 10] ;
  135.                                 dis_smg[2] = smg_du[(count-3) % 10] ;
  136.                                 dis_smg[3] = smg_du[(count-3) / 10] ;

  137.                                 dx_red    = 1;  //滅
  138.                                 dx_yellow = 1;        //滅
  139.                                 nb_green  =        1;        //滅
  140.                                 nb_yellow = 1;        //滅
  141.                                 dx_green  =        0;        //亮
  142.                                 nb_red    = 0;  //亮
  143.                                 flag_5m_value = 0;        
  144.                         }
  145.                         else if(count <= 3){                 //當小于3秒時  黃燈閃爍

  146.                                 dis_smg[0] = smg_du[count % 10] ;
  147.                                 dis_smg[1] = smg_du[count / 10] ;
  148.                                 dis_smg[2] = smg_du[count % 10] ;
  149.                                 dis_smg[3] = smg_du[count / 10] ;

  150.                                 dx_red    = 1;    //滅
  151.                                 dx_green  =        1;          //滅
  152.                                 nb_green  =        1;          //滅
  153.                                 nb_yellow = 1;          //滅
  154.                                 nb_red    = 0;    //亮
  155.                                 
  156.                                 if(flag_500ms == 0){                //黃燈閃爍
  157.                                         dx_yellow = 0;//亮        
  158.                                 }
  159.                                 else{
  160.                                         dx_yellow = 1;//滅        
  161.                                 }
  162.                         }
  163.                 }
  164.                
  165. /***********************東西時間*********************************/
  166.                 if(flag_dx_nb == 1){  
  167.                         if(count > 3){
  168.                                 
  169.                                 dis_smg[0] = smg_du[(count-3) % 10] ;
  170.                                 dis_smg[1] = smg_du[(count-3) / 10] ;
  171.                                 dis_smg[2] = smg_du[count % 10] ;
  172.                                 dis_smg[3] = smg_du[count / 10] ;
  173.                                 

  174.                                 dx_red    = 0;     //亮
  175.                                 nb_green  =        0;           //亮
  176.                                 nb_yellow = 1;           //滅
  177.                                 dx_green  =        1;           //滅
  178.                                 dx_yellow = 1;           //滅
  179.                                 nb_red    = 1;     //滅
  180.                                 flag_5m_value = 0;        
  181.                         }
  182.                         else if(count <= 3){                 //當小于3秒時  黃燈閃爍
  183.                         
  184.                                 dis_smg[0] = smg_du[count % 10] ;
  185.                                 dis_smg[1] = smg_du[count / 10] ;
  186.                                 dis_smg[2] = smg_du[count % 10] ;
  187.                                 dis_smg[3] = smg_du[count / 10] ;

  188.                                 dx_red    = 0;     //滅
  189.                                 dx_green  =        1;           //滅
  190.                                 dx_yellow = 1;           //滅
  191.                                 nb_red    = 1;     //滅
  192.                                 nb_green  =        1;           //滅
  193.                                 
  194.                                 if(flag_500ms == 0){           //黃燈閃爍
  195.                                         nb_yellow = 0;        //亮        
  196.                                 }
  197.                                 else{
  198.                                         nb_yellow = 1;        //滅        
  199.                                 }
  200.                         }
  201.         }                        
  202. }

  203. uchar key_can;         //按鍵值

  204. //按鍵定義
  205. sbit Key1=P1^6;                                 //設置鍵
  206. sbit Key2=P1^7;                                 //加按鍵
  207. sbit Key3=P3^2;                                 //減按鍵
  208. sbit Key4=P3^3;                                 //交通管制鍵
  209. //========================================================================
  210. // 函數: uchar Key_Scan()
  211. // 應用: temp=uchar Key_Scan();
  212. // 描述: 按鍵掃描并返回按下的鍵值
  213. // 返回: 按下的鍵值
  214. // 日期: 2019-03-31
  215. // 備注: 該函數帶松手檢測,按下鍵返回一次鍵值后返回0,直至第二次按鍵按下
  216. //========================================================================
  217. uchar Key_Scan(){
  218.         static uchar key_up=1;//按鍵松開標志
  219.         if(key_up&&(Key1==0||Key2==0||Key3==0||Key4==0)){
  220.                 delay_1ms(10);//去抖動
  221.                 key_up=0;
  222.         if(Key1==0)                return 1;
  223.         else if(Key2==0)return 2;
  224.         else if(Key3==0)return 3;
  225.         else if(Key4==0)return 4;
  226.         }
  227.         else if(Key1==1&&Key2==1&&Key3==1&&Key4==1)
  228.                 key_up=1;            
  229.          return 0;// 無按鍵按下
  230. }

  231. uchar menu_1;//縱橫加減標示

  232. /********************設置函數*****************/

  233. void setting(){
  234.         if(key_can == 4){   //交通管制按鍵
  235.                 flag_jdgz ++;
  236.                 if(flag_jdgz > 5)
  237.                         flag_jdgz = 0;        
  238.                 if(flag_jdgz == 1){         //  全部亮紅燈
  239.                         dx_red    = 0;   //亮
  240.                         nb_red    = 0;   //亮
  241.                         dx_green  =        1;         //滅
  242.                         dx_yellow = 1;         //滅
  243.                         nb_green  =        1;         //滅
  244.                         nb_yellow = 1;         //滅                        
  245.                 }
  246.                 if(flag_jdgz == 2){         //  全部亮黃燈
  247.                         dx_red    = 1;  //滅
  248.                         dx_green  =        1;        //滅
  249.                         nb_red    = 1;  //滅
  250.                         nb_green  =        1;        //滅
  251.                         nb_yellow = 0;        //亮                        
  252.                         dx_yellow = 0;        //亮
  253.                 }
  254.                 if(flag_jdgz == 3){         //  全部亮綠燈
  255.                         dx_green  =        0;         //亮
  256.                         nb_green  =        0;         //亮
  257.                         dx_red    = 1;   //滅
  258.                         dx_yellow = 1;         //滅
  259.                         nb_red    = 1;   //滅
  260.                         nb_yellow = 1;         //滅                        
  261.                 }               
  262.                 if(flag_jdgz == 4){         //  東西綠燈  南北紅燈
  263.                         dx_red    = 0;   //亮
  264.                         nb_green  =        0;         //亮
  265.                         dx_green  =        1;         //滅
  266.                         dx_yellow = 1;         //滅
  267.                         nb_red    = 1;   //滅
  268.                         nb_yellow = 1;         //滅                        
  269.                 }
  270.                 if(flag_jdgz == 5){         //  南北綠燈  東西紅燈
  271.                         dx_green  =        0;          //亮
  272.                         nb_red    = 0;   //亮  
  273.                         dx_red    = 1;   //滅
  274.                         dx_yellow = 1;         //滅
  275.                         nb_green  =        1;         //滅
  276.                         nb_yellow = 1;         //滅                        
  277.                 }
  278.         }
  279.         
  280.         if(key_can == 1){          //設置鍵
  281.                 menu_1 ++;
  282.                 if(menu_1 >= 3){
  283.                         menu_1  = 0;
  284.                 }
  285.         }

  286.         if(menu_1 == 1){           //設置東西的時間
  287.                 if(key_can == 2){
  288.                         dx_time ++ ;                //加1
  289.                         if(dx_time > 99)        //時間最大值為99s
  290.                                 dx_time = 99;
  291.                 }
  292.                 if(key_can == 3){
  293.                         dx_time -- ;                //減1
  294.                         if(dx_time <= 5)        //時間最小值為5s
  295.                                 dx_time = 5;
  296.                 }
  297.                 dis_smg[0] = smg_du[(dx_time-1) % 10] ;        
  298.                 dis_smg[1] = smg_du[(dx_time-1) / 10] ;        
  299.                 dis_smg[2] = DisplayOther[2] ;
  300.                 dis_smg[3] = DisplayOther[2] ;
  301.         }        
  302.         
  303.         if(menu_1 == 2){           //設置南北的時間
  304.                 if(key_can == 2){
  305.                         nb_time ++ ;                //加1
  306.                         if(nb_time > 99)        //時間最大值為99s
  307.                                 nb_time = 99;
  308.                 }
  309.                 if(key_can == 3){
  310.                         nb_time -- ;                //減1
  311.                         if(nb_time <= 5)        //時間最小值為5s
  312.                                 nb_time = 5;
  313.                 }
  314.                 dis_smg[0] = DisplayOther[2] ;
  315.                 dis_smg[1] = DisplayOther[2] ;
  316.                 dis_smg[2] = smg_du[(nb_time-1) % 10] ;
  317.                 dis_smg[3] = smg_du[(nb_time-1) / 10] ;
  318.         }
  319. }

  320. /*********************************主函數********************************/
  321. void main(){
  322.         time0_init();
  323.         while(1){
  324.                 key_can=Key_Scan();
  325.                 if(key_can)
  326.                         setting();
  327.                 if((menu_1 == 0) && (flag_jdgz == 0))
  328.                         traffic_light_dispose();
  329.                 DisplayScan();        
  330.         }
  331. }  

  332. /*********************定時器0中斷服務程序************************/
  333. void time0_int() interrupt 1 {                           
  334.         static uchar value;                                 //定時10ms中斷一次
  335.         TL0 = 15536;                    //給定時器低位重裝初始值                65536-15536=50000us=50ms,即50ms一個中斷
  336.         TH0 = 15536 >> 8;               //給定時器高位重裝初始值
  337.         value ++;
  338.         flag_5m_value++;
  339.         if(flag_5m_value % 10 == 0)
  340.                 flag_500ms = ~flag_500ms;
  341.         if(value >= 20){
  342.                 value = 0;
  343.                 flag_1s = 1;
  344.         }
  345. }
復制代碼
0.png
所有資料51hei提供下載:
科技節——基于51單片機的交通燈項目.zip (1.41 MB, 下載次數: 96)
回復

使用道具 舉報

ID:549797 發表于 2019-6-7 13:44 | 顯示全部樓層
大神們,這個電路圖需不需要接鎖存器或者譯碼器
回復

使用道具 舉報

ID:544298 發表于 2019-6-10 12:29 | 顯示全部樓層
這里面沒有DSN文件 別被他一個圖騙了
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: www.操.com| 91精品国产综合久久福利软件 | 久操福利| 精品一区二区三区四区视频 | 亚洲国产精品视频一区 | 在线观看视频91 | 久久久久中文字幕 | 国产精品久久久久久久毛片 | av一级一片 | 在线观看免费高清av | 国产日韩精品久久 | 天天久久 | 国产精品久久久久久高潮 | 亚洲手机视频在线 | 中文字幕av亚洲精品一部二部 | www.黄色网 | 久久久久国产精品午夜一区 | 日日夜夜天天 | 国产精品欧美一区二区三区 | 妞干网av | 亚洲激情专区 | av黄色在线观看 | 日韩一区二区黄色片 | 日韩中文视频 | 一区二区三区国产视频 | 欧美成人精品在线观看 | 91精品国产91久久综合桃花 | 91精品国产一二三 | 四虎影院在线播放 | 精品无码三级在线观看视频 | 亚洲一区精品在线 | 可以在线观看av的网站 | 久久aⅴ乱码一区二区三区 亚洲国产成人精品久久久国产成人一区 | 在线观看欧美一区 | 日韩激情一区 | 欧美色综合天天久久综合精品 | 国产乱码精品一区二区三区五月婷 | 午夜视频在线免费观看 | 在线一级片 | 久久亚洲精品久久国产一区二区 | 中文字字幕一区二区三区四区五区 |