单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4730|回复: 10
打印 上一主题 下一主题
收起左侧

51单片机交通灯制作 74HC245驱动 带实物 程序 原理图 仿真

  [复制链接]
跳转到指定楼层
楼主
单片机交通灯的制作实物图:


Altium Designer画的原理图如下:(51hei附件中可下载工程文件):


制作过程:


51单片机交通灯仿真原理图如下(proteus仿真工程文件可到51hei附件中下载):


单片机源程序如下:
  1. #include <reg51.h>                                //头文件
  2. #define uchar unsigned char
  3. #define uint  unsigned int                //宏定义

  4. uchar data buf[4];                                        //秒显示的变量
  5. uchar data sec_dx=20;                          //东西数默认
  6. uchar data sec_nb=30;                        //南北默认值
  7. uchar data set_timedx=20;                //设置东西方向的时间
  8. uchar data set_timenb=30;                //设置南北方向的时间
  9. int n;
  10. uchar data countt0,countt1;//定时器0中断次数
  11. //定义6组开关
  12. sbit  k4=P3^7;      //切换方向
  13. sbit  k1=P3^5;                //时间加
  14. sbit  k2=P3^6;                //时间减
  15. sbit  k3=P3^4;                //确认
  16. sbit  k5=P3^1;                //禁止
  17. sbit  k6=P1^5;                //夜间模式


  18. sbit Red_nb=P2^6;                //南北红灯标志
  19. sbit Yellow_nb=P2^5;        //南北黄灯标志
  20. sbit Green_nb=P2^4;     //南北绿灯标志

  21. sbit Red_dx=P2^3;                //东西红灯标志
  22. sbit Yellow_dx=P2^2;        //东西黄灯标志
  23. sbit Green_dx=P2^1;                //东西绿灯标志
  24.         
  25. sbit Buzz=P3^0;               
  26. bit set=0;                                //调时方向切换键标志 =1时,南北,=0时,东西
  27. bit dx_nb=0;                        //东西南北控制位
  28. bit shanruo=0;                        //闪烁标志位
  29. bit yejian=0;                        //夜间黄灯闪烁标志位

  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. //函数的声明部分
  44. void delay(int ms);                        //延时子程序
  45. void key();                                        //按键扫描子程序
  46. void key_to1();                                //键处理子程序
  47. void key_to2();
  48. void key_to3();
  49. void display();                                //显示子程序
  50. void logo();                                   //开机LOGO
  51. void Buzzer();
  52. //主程序
  53. void main()
  54. {
  55.         TMOD=0X11;                                           //定时器设置
  56.         TH1=0X3C;               
  57.         TL1=0XB0;
  58.         TH0=0X3C;                                        //定时器0置初值 0.05S
  59.         TL0=0XB0;
  60.         EA=1;                                                //开总中断
  61.         ET0=1;                                                //定时器0中断开启
  62.         ET1=1;                                           //定时器1中断开启
  63.         TR0=1;                                                //启动定时0
  64.         TR1=0;                                                         //关闭定时1
  65.         EX0=1;                                                //开外部中断0
  66.         EX1=1;                                                //开外部中断1
  67.     logo();                                                //开机初始化
  68.         P2=0Xc3;                                        // 开始默认状态,东西绿灯,南北黄灯   
  69.     sec_nb=sec_dx+5;                         //默认南北通行时间比东西多5秒
  70.         while(1)                                          //主循环
  71.         {         
  72.                 key();                                         //调用按键扫描程序
  73.                 display();                                 //调用显示程序
  74.         }        
  75. }
  76. //函数的定义部分
  77. void key(void)        //按键扫描子程序
  78. {         
  79.         if(k1!=1)                                                        //当K1(时间加)按下时
  80.         {
  81.                 display();                                       //调用显示,用于延时消抖
  82.                 if(k1!=1)                                                        //如果确定按下
  83.                 {
  84.                           TR0=0;                                               //关定时器        
  85.                         shanruo=0;                                        //闪烁标志位关
  86.                         P2=0x00;                                        //灭显示
  87.                         TR1=0;                                                        //启动定时1
  88.                         if(set==0)                                        //设置键按下
  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 ;                 //设置的数值赋给东西南北
  97.                         sec_dx=set_timedx;                        
  98.                           do
  99.                          {
  100.                                 display();                                 //调用显示,用于延时
  101.                         }
  102.                         while(k1!=1);                         //等待按键释放
  103.                 }
  104.         }

  105.         if(k2!=1)                                                        //当K2(时间减)按键按下时
  106.         {               
  107.                 display();                                       //调用显示,用于延时消抖  
  108.                 if(k2!=1)                                                //如果确定按下
  109.                 {        
  110.                          TR0=0;                                         //关定时器0        
  111.                         shanruo=0;                                        //闪烁标志位关
  112.                         P2=0x00;                                        //灭显示
  113.                         TR1=0;                                                //关定时器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 ;                         //设置的数值赋给东西南北
  123.                         sec_dx=set_timedx;
  124.                           do        
  125.                     {
  126.                                 display();                       //调用显示,用于延时
  127.                         }
  128.                         while(k2!=1);                           //等待按键释放
  129.                 }
  130.         }

  131.         if(k3!=1)                                                        //当K3(确认)键按下时
  132.         {        
  133.                 display();                                       //调用显示,用于延时消抖
  134.                 if(k3!=1)                                                //如果确定按下
  135.                 {
  136.                         TR0=1;                                                  //启动定时器0
  137.                         sec_nb=set_timenb;                                //从中断回复,仍显示设置过的数值
  138.                         sec_dx=set_timedx;                                //显示设置过的时间
  139.                         TR1=0;                                                        //关定时器1        
  140.                         if(set==0)                                                //时间倒时到0时
  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)                                                        //当K4(切换)键按下
  158.     {
  159.                 display();                                       //调用显示,用于延时消抖
  160.                 if(k4!=1)                                                //如果确定按下
  161.                 {  
  162.                          TR0=0;                                                //关定时器0        
  163.                         set=!set;                                        //取反set标志位,以切换调节方向
  164.                         TR1=0;                                                //关定时器1
  165.                         dx_nb=set;
  166.                         do
  167.                         {
  168.                                 display();                            //调用显示,用于延时
  169.                         }                                
  170.                         while(k4!=1);                          //等待按键释放
  171.                 }
  172.         }        

  173.         if(k5!=1)                                                        //当K5(禁止)键按下时
  174.         {
  175.                    display();                                       //调用显示,用于延时消抖
  176.                    if(k5!=1)                                                //如果确定按下
  177.                    {         
  178.                     TR0=0;                                                //关定时器
  179.                         P2=0x00;                                        //灭显示
  180.                         Red_dx=1;
  181.                         Red_nb=1;                                        //全部置红灯
  182.                         TR1=0;
  183.                         sec_dx=00;                                        //四个方向的时间都为00
  184.                         sec_nb=00;
  185.                         do
  186.                         {
  187.                                 display();                                 //调用显示,用于延时
  188.                         }        
  189.                         while(k5!=1);                        //等待按键释放        
  190.                    }
  191.         }
  192.         if(k6!=1)                                                        //当K6(夜间模式)按下
  193.         {
  194.                    display();                                       //调用显示,用于延时消抖
  195.                    if(k6!=1)                                                //如果确定按下
  196.                    {         
  197.                     TR0=0;                                                //关定时器
  198.                         P2=0x00;
  199.                         TR1=1;
  200.                         sec_dx=00;                                        //四个方向的时间都为00
  201.                         sec_nb=00;
  202.                         do
  203.                         {
  204.                                 display();                           //调用显示,用于延时
  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位 东西秒个位
  214.         buf[3]=sec_dx/10;                 //第3位 南北秒十位
  215.         buf[0]=sec_dx%10;                 //第4位 南北秒个位               
  216.         P1=0xff;                          // 初始灯为灭的
  217.         P0=0x00;                                 ////灭显示
  218.         P1=0xfe;                           //片选LED1
  219.         P0=table[buf[1]];                //送东西时间十位的数码管编码                        
  220.         delay(1);                                //延时
  221.         P1=0xff;                                //关显示
  222.         P0=0x00;                                //灭显示
  223.                                                    
  224.         P1=0xfd;                     //片选LED2
  225.         P0=table[buf[2]];                 //送东西时间个位的数码管编码
  226.         delay(1);                                 //延时
  227.         P1=0xff;                                //关显示
  228.         P0=0x00;                                //关显示
  229.         P1=0Xfb;                                  //片选LED3
  230.         P0=table[buf[3]];                //送南北时间十位的数码管编码
  231.         delay(1);                                //延时
  232.         P1=0xff;                                 //关显示
  233.         P0=0x00;                                 //关显示
  234.         P1=0Xf7;                                 //片选LED4        
  235.         P0=table[buf[0]];                //送南北时间个位的数码管编码
  236.         delay(1);                                //延时
  237. }

  238. void time0(void) interrupt 1 using 1          //定时中断子程序
  239. {
  240.         TH0=0X3C;                                                        //重赋初值
  241.         TL0=0XB0;                                                        //12m晶振50ms//重赋初值
  242.         TR0=1;                                                                //重新启动定时器
  243.         countt0++;                                                        //软件计数加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;                                                //蜂鸣器关
  251.                 }                                                   
  252.             if((sec_dx<=5)&&(dx_nb==1)&&(shanruo==1))                  //南北黄灯闪               
  253.         {  
  254.                         Green_nb=0;
  255.                         Yellow_nb=0;
  256.                         Buzz=0;                                           //蜂鸣器关
  257.                 }        
  258.         }
  259.                
  260.         if(countt0==20)                                  // 定时器中断次数=20时(即1秒时)
  261.         {        countt0=0;                                                //清零计数器
  262.                 sec_dx--;                                                //东西时间减1
  263.                 sec_nb--;                                                //南北时间减1

  264.                 if((sec_nb<=5)&&(dx_nb==0)&&(shanruo==1))                  //东西黄灯闪               
  265.         {
  266.                         Green_dx=0;
  267.                         Yellow_dx=1;
  268.                         Buzz=1;                                                 //蜂鸣器关
  269.                 }                                                   
  270.             if((sec_dx<=5)&&(dx_nb==1)&&(shanruo==1))                  //南北黄灯闪               
  271.         {  
  272.                         Green_nb=0;
  273.                         Yellow_nb=1;
  274.                         Buzz=1;                                                 //蜂鸣器关
  275.                 }                                                                 
  276.                 if(sec_dx==0&&sec_nb==5)                 //当东西倒计时到0时,重置5秒,用于黄灯闪烁时间   
  277.                 {
  278.                         sec_dx=5;
  279.                         shanruo=1;
  280.                 }
  281.                 if(sec_nb==0&&sec_dx==5)                //当南北倒计时到0时,重置5秒,用于黄灯闪烁时间   
  282.                 {
  283.                         sec_nb=5;
  284.                         shanruo=1;
  285.                 }
  286.                 if(dx_nb==0&&sec_nb==0)                        //当黄灯闪烁时间倒计时到0时,
  287.                 {
  288.                      Buzz=1;                                                //蜂鸣器开
  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)                        //当黄灯闪烁时间到
  298.                 {
  299.                         P2=0X00;                                        //重置东西南北的红绿灯状态
  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         //定时中断子程序
  310. {
  311.         TH1=0X3C;                                                        //重赋初值
  312.         TL1=0XB0;                                                        //12m晶振50ms//重赋初值
  313.         countt1++;                                                        //软件计数加1
  314.         if(countt1==10)                                           // 定时器中断次数=10时(即0.5秒)
  315.         {
  316.                         Yellow_nb=0;                                //南北黄灯灭
  317.                         Yellow_dx=0;                                //东西黄灯灭
  318.         }
  319.         if(countt1==20)                                  // 定时器中断次数=20时(即1秒时)
  320.         {        countt1=0;                                                //清零计数器
  321.                         Yellow_nb=1;                                        //南北黄灯亮
  322.                         Yellow_dx=1;                                  //东西黄灯亮
  323.         }        
  324. }


  325. //外部中断0
  326. void int0(void) interrupt 0 using 1           //只允许东西通行
  327. {
  328.         TR0=0;                                                                //关定时器0
  329.         TR1=0;                                                                //关定时器1
  330. ……………………

  331. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
74hc245----51单片机交通灯.zip (16.9 MB, 下载次数: 106)



评分

参与人数 2黑币 +10 收起 理由
牛嗨生 + 5 很给力!
tieq1952 + 5 很给力!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 转播转播 分享分享 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
admin 发表于 2017-6-8 02:28 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

板凳
海勿渊 发表于 2017-12-8 00:44 | 只看该作者
楼主你好呐,请问你有这个交通灯里的74HC245的Altium库吗?做原理图的时候一直找不到这个芯片的库
回复

使用道具 举报

地板
tieq1952 发表于 2017-12-8 08:21 | 只看该作者
动手能力很强,继续努力!
回复

使用道具 举报

5#
水台人云 发表于 2018-4-26 09:38 | 只看该作者
很实用,下载下来学学
回复

使用道具 举报

6#
258369 发表于 2018-7-23 09:21 | 只看该作者
学习学习
回复

使用道具 举报

7#
文凤轩 发表于 2018-8-19 17:14 来自手机 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

8#
3154407 发表于 2019-5-15 11:16 | 只看该作者
请问一下74HC245起到的作用是什么啊?
回复

使用道具 举报

9#
dj3365191 发表于 2019-5-15 15:41 | 只看该作者
不错,很好
回复

使用道具 举报

10#
,。 发表于 2019-5-16 21:18 | 只看该作者
有不加蜂鸣器的程序吗
回复

使用道具 举报

11#
nathan008 发表于 2019-5-17 22:04 | 只看该作者
谢谢作者
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51Hei单片机16群 联系QQ:125739409;技术交流QQ群7344883

Powered by 单片机教程网

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