找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5971|回复: 7
收起左侧

单片机交通灯原理图加pcb工程文件+源程序

  [复制链接]
ID:350762 发表于 2019-10-14 20:55 | 显示全部楼层 |阅读模式
Altium Designer画的交通灯原理图和PCB图如下:(51hei附件中可下载工程文件)
0.png 0.png 0.png

单片机源程序如下:
  1. /***************************************************
  2.      基于单片机的交通灯设计
  3. ***************************************************/
  4. #include <reg52.h> //52系列单片机头文件
  5. #define uchar  unsigned char
  6. #define uint  unsigned int
  7. #define ON   0
  8. #define OFF  1
  9. sbit D1 = P1^3; //数码管位选引脚
  10. sbit C1 = P1^2;  
  11. sbit B1 = P1^1;  
  12. sbit A1 = P1^0;
  13. sbit NS_GRE = P2^5; //定义LED灯引脚     
  14. sbit NS_YEL = P2^4;
  15. sbit NS_RED = P2^3;   
  16. sbit EW_GRE = P2^2;  
  17. sbit EW_YEL = P2^1;  
  18. sbit EW_RED = P2^0;
  19. uchar flag=1; //方向标志位 1南北,0东西           初始化flag=1即南北方向先行
  20. #define YELTime 4   //黄灯时间 4s
  21. #define EWTime  28+YELTime  //东西红灯28s
  22. #define NSTime  16+YELTime  //南北红灯16s
  23. uchar t=EWTime;
  24. uchar tt=0;
  25. sbit Key1 = P3^2;  //按键引脚定义
  26. sbit Key2 = P3^4;
  27. uchar  keyflag = 0; //紧急情况标志位,1为紧急情况  
  28. uchar table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //共阳数码管
  29. #define EW_RED_ON()   do { EW_RED=ON;EW_GRE=OFF;EW_YEL=OFF; } while (0)
  30. #define EW_YEL_ON()   do { EW_RED=OFF;EW_GRE=OFF;EW_YEL=ON; } while (0)
  31. #define EW_GRE_ON()   do { EW_RED=OFF;EW_GRE=ON;EW_YEL=OFF; } while (0)
  32. #define NS_RED_ON()   do { NS_RED=ON;NS_GRE=OFF;NS_YEL=OFF; } while (0)
  33. #define NS_YEL_ON()   do { NS_RED=OFF;NS_GRE=OFF;NS_YEL=ON; } while (0)
  34. #define NS_GRE_ON()   do { NS_RED=OFF;NS_GRE=ON;NS_YEL=OFF; } while (0)
  35. /***************************************************
  36. * 延时函数
  37. ***************************************************/
  38. void Delay10uS(uint z)
  39. {
  40.     uint i,a,b;
  41.     for(i=0;i<z;i++){
  42.     for(b=1;b>0;b--)
  43.     for(a=2;a>0;a--);
  44.     }
  45. }
  46. /***************************************************
  47. *               东西方向显示函数
  48. *num1 数值的十位  num2 数值的各位
  49. ***************************************************/
  50. void display1(uchar num1,uchar num2)
  51. {            
  52.       P0=0XFF;   
  53.       P0=table[num1];      
  54.       A1=ON;   
  55.       Delay10uS(1);     
  56.       A1=OFF;
  57.           P0=0XFF;   
  58.       P0=table[num2];   
  59.       B1=ON;   
  60.       Delay10uS(1);   
  61.       B1=OFF;
  62.           P0=0XFF;  
  63. }
  64. /***************************************************
  65. *               南北方向显示函数
  66. *num3 数值的十位  num4 数值的各位
  67. ***************************************************/
  68. void display2(uchar num3,uchar num4)
  69. {   
  70.              P0=0XFF;
  71.       P0=table[num3];   
  72.       C1=ON;   
  73.       Delay10uS(1);   
  74.       C1=OFF;
  75.           P0=0XFF;     
  76.       P0=table[num4];     
  77.       D1=ON;      
  78.       Delay10uS(1);   
  79.       D1=OFF;
  80.           P0=0XFF;     
  81. }
  82. /***************************************************
  83. *               定时器初始化函数
  84. ***************************************************/
  85. void Timer_Init(void)
  86. {
  87.     TMOD=0x01;             //定时器工作方式
  88.     TH0=(65536-50000)/256; //定时器初值     50ms中断一次
  89.     TL0=(65536-50000)%256;
  90.     ET0=1;                 //使能定时器中断
  91.     TR0=1;                 //启动定时器0
  92. }
  93. /***************************************************
  94. *               按键检测函数
  95. ***************************************************/
  96. void Key_Scan()
  97. {
  98.         //--检测按键1--//
  99.         if (Key1==0)                //检测按键K1是否按下
  100.         {
  101.                 Delay10uS(200);        //消除抖动
  102.                 if (Key1==0)        //再次检测按键是否按下
  103.                 {
  104.                    keyflag=1;        //将紧急情况标志位置1
  105.                 }
  106.         }
  107.                 if (Key2==0)        //检测按键K1是否按下
  108.         {
  109.                 Delay10uS(200);        //消除抖动
  110.                 if (Key2==0)        //再次检测按键是否按下
  111.                 {
  112.                    keyflag=0;        //将紧急情况标志位置0
  113.                    flag=1;                //重新从南北方向开始
  114.                    t=EWTime;
  115.                 }
  116.         }
  117. }

  118. void main()                   //主函数
  119. {
  120.     Timer_Init();    //定时器初始化  
  121.     EA=1;            //打开全局中断   
  122.     NS_GRE = OFF;    //所有的灯都灭   
  123.     NS_YEL = OFF;
  124.     NS_RED = OFF;   
  125.     EW_GRE = OFF;  
  126.     EW_YEL = OFF;  
  127.     EW_RED = OFF;   
  128.     P0 = 0xFF;      //数码管显示灭
  129.         while(1)
  130.         {
  131.                  Key_Scan();
  132.                 if(flag==1)          //南北方向先开始
  133.                 {
  134.                    display1(t/10, t%10);      //东西方向显示时间
  135.                    display2(t/10, t%10);      //南北方向显示时间
  136.            EW_RED_ON();               //东西方向保持红灯
  137.                    if(t>4)        //绿灯时间
  138.                    {
  139.                              NS_GRE_ON();            //南北方向保持绿灯        
  140.                    }
  141.                    if(t>=0&&t<5)        NS_YEL_ON();   //南北方向保持黄灯
  142.                    if(t==0)         //时间为0
  143.                    {
  144.                      flag=0;        //南北方向结束,flag=0,开始东西方向
  145.                          t=NSTime;  //加载南北方向红灯时间
  146.                    }
  147.                 }
  148.                 if(flag==0)
  149.                 {
  150.                    display1(t/10, t%10);      //东西方向显示时间
  151.                    display2(t/10, t%10);      //南北方向显示时间
  152.            NS_RED_ON();               //南北方向保持红灯
  153.                    if(t>4)
  154.                    {
  155.                             EW_GRE_ON();           //东西方向保持绿灯        
  156.                    }
  157.                    if(t>=0&&t<5)        EW_YEL_ON();//东西方向保持黄灯
  158.                    if(t==0)
  159.                    {
  160.                      flag=1;         //东西方向结束,flag=1,开始南北方向
  161.                          t=EWTime;         //加载东西方向红灯时间
  162.                    }
  163.             }
  164.                 if(keyflag == 1)   //如果急停按键按下 红灯全亮 数码管显示关闭
  165.                 {      
  166.            P0 = 0xFF;           //数码管显示灭
  167.            EW_RED_ON();         //东西方向红灯
  168.            NS_RED_ON();         //南北方向红灯
  169.                flag=2;                                //标志位flag=2,即东西、南北方向的其他操作停止
  170.          }
  171.    }
  172. }
  173. void timer1(void) interrupt 1
  174. {               
  175.     TH0=(65536-50000)/256;  //重新装入初值
  176.     TL0=(65536-50000)%256;
  177.         tt++;
  178.         if(tt==20)        //表示1S时间到了
  179.         {
  180.          tt=0;
  181.          t--;          //数码管显示时间减一
  182.         }   
  183. }           
复制代码

所有资料51hei提供下载:
交通灯pcb原理图.zip (8.55 MB, 下载次数: 227)
回复

使用道具 举报

ID:624872 发表于 2019-10-28 08:10 | 显示全部楼层
这个正是我需要的 感谢楼主的共享
回复

使用道具 举报

ID:426861 发表于 2019-10-28 10:24 | 显示全部楼层
感谢分享            
回复

使用道具 举报

ID:320566 发表于 2019-10-28 19:27 | 显示全部楼层
感谢分享            
回复

使用道具 举报

ID:964399 发表于 2021-9-6 16:29 | 显示全部楼层
麻烦问一下,这个是单层板还是双层板
回复

使用道具 举报

ID:961087 发表于 2021-9-14 14:16 | 显示全部楼层
你好,借鉴你的程序,我发现我烧到板子上之后发现数码管显示有问题,有时候好像显示不出来,有时候乱码。不知道什么原因。
#include <REGX52.H>
#define uchar  unsigned char
#define uint  unsigned int
#define ON   0
#define OFF  1
sbit dula=P2^6;
sbit wela=P2^7;
sbit NS_GRE = P1^5;     
sbit NS_YEL = P1^4;
sbit NS_RED = P1^3;   
sbit EW_GRE = P1^2;  
sbit EW_YEL = P1^1;  
sbit EW_RED = P1^0;
uchar flag=1;
#define YELTime 4   
#define EWTime  28+YELTime  
#define NSTime  16+YELTime  
uchar t=EWTime;
uchar tt=0;
sbit Key1=P3^4;  
sbit Key2=P3^5;
uchar keyflag=0;  
uchar table[]={0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
#define EW_RED_ON()   do { EW_RED=ON;EW_GRE=OFF;EW_YEL=OFF; } while (0)
#define EW_YEL_ON()   do { EW_RED=OFF;EW_GRE=OFF;EW_YEL=ON; } while (0)
#define EW_GRE_ON()   do { EW_RED=OFF;EW_GRE=ON;EW_YEL=OFF; } while (0)
#define NS_RED_ON()   do { NS_RED=ON;NS_GRE=OFF;NS_YEL=OFF; } while (0)
#define NS_YEL_ON()   do { NS_RED=OFF;NS_GRE=OFF;NS_YEL=ON; } while (0)
#define NS_GRE_ON()   do { NS_RED=OFF;NS_GRE=ON;NS_YEL=OFF; } while (0)
void delayms(uint xms)
{
        uint i,j;
        for(i=xms;i>0;i--)
        for(j=110;j>0;j--);
}
void display1(uchar num1,uchar num2)
{     
                P0=0xff;
                wela=1;
                P0=0xfc;
                wela=0;
               
                P0=0x00;
                dula=1;
                P0=table[num1];
                dula=0;
                delayms(3);
               
                P0=0xff;
                wela=1;
                P0=0xfd;
                wela=0;
               
                P0=0x00;
                dula=1;
                P0=table[num2];
                dula=0;
                delayms(3);
}

void display2(uchar num3,uchar num4)
{   
         P0=0xff;
         wela=1;
         P0=0xef;
         wela=0;
         
         P0=0x00;
         dula=1;
         P0=table[num3];
         dula=0;
         delayms(3);
         
         P0=0xff;
         wela=1;
         P0=0xdf;
         wela=0;
         
         P0=0x00;
         dula=1;
         P0=table[num4];
         dula=0;
         delayms(3);
}

void INIT(void)
{
        TMOD=0x01;            
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        ET0=1;                 
        TR0=1;
}

void KeyScan()
{        
        if (Key1==0)               
        {
                delayms(10);         
                if (Key1==0)      
                {
                        keyflag=1;      
                }
        }
        if (Key2==0)//¸′λ°′¼ü »Øμ½3õê¼×′쬠  
        {
                delayms(10);
                if (Key2==0)
                {
                        keyflag=0;        
                        flag=1;               
                        t=EWTime;
                }
        }
}

void main()                  
{
        INIT();      
        EA=1;               
        NS_GRE = OFF;        
        NS_YEL = OFF;
        NS_RED = OFF;   
        EW_GRE = OFF;  
        EW_YEL = OFF;  
        EW_RED = OFF;   
        P0 = 0xFF;      
  while(1)
  {
                KeyScan();
                if(flag==1)         
                {
                        display1(t/10, t%10);      
                        display2(t/10, t%10);      
                        EW_RED_ON();
                        NS_GRE_ON();
                if(t>4)        
                {
                        NS_GRE_ON();                    
                }
                if(t>=0&&t<5)    NS_YEL_ON();   
                if(t==0)        
                {
                        flag=0;        
                        t=NSTime;  
                }
                }
                if(flag==0)
                {
                        display1(t/10, t%10);      
                        display2(t/10, t%10);      
                        NS_RED_ON();               
                        if(t>4)
                        {
                                EW_GRE_ON();                  
                        }
                        if(t>=0&&t<5)        EW_YEL_ON();
                        if(t==0)
                        {
                                flag=1;
                                t=EWTime;         
                        }
                }
                if(keyflag == 1)
                {      
                        P0 = 0xFF;           
                        EW_RED_ON();        
                        NS_RED_ON();         
                        flag=2;                              
                }
        }
}
void timer1(void) interrupt 1
{               
        TH0=(65536-50000)/256;  
        TL0=(65536-50000)%256;
        tt++;
        if(tt==20)        
        {
                tt=0;
                t--;         
        }   
}           
回复

使用道具 举报

ID:961087 发表于 2021-9-14 17:12 | 显示全部楼层
王披风 发表于 2021-9-14 14:16
你好,借鉴你的程序,我发现我烧到板子上之后发现数码管显示有问题,有时候好像显示不出来,有时候乱码。不 ...

已经解决了,我用数组显示的位选,成功了,感谢。
回复

使用道具 举报

ID:1059607 发表于 2022-12-29 14:38 | 显示全部楼层
楼主有封装跟库没
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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