找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机七键交通灯程序 紧急模式,夜间模式,时间设定,加时间,减时间,确定,复位

[复制链接]
跳转到指定楼层
楼主
ID:536280 发表于 2020-6-14 13:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
七个按键分别实现,紧急模式,夜间模式,时间设定,加时间,减时间,确定,复位

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

  4. uchar data buf[4];                    //秒显示的变量
  5. uchar data sec_dx=30;              //东西数默认
  6. uchar data sec_nb=30;            //南北默认值
  7. uchar data set_timedx=30;        //设置东西方向的时间
  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. bit set=0;                //调时方向切换键标志 =1时,南北,=0时,东西
  26. bit dx_nb=0;            //东西南北控制位
  27. bit shanruo=0;            //闪烁标志位
  28. bit yejian=0;            //夜间黄灯闪烁标志位

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

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

  99.     if(k2!=1)                            //当K2(时间减)按键按下时
  100.     {        
  101.         display();                       //调用显示,用于延时消抖  
  102.         if(k2!=1)                        //如果确定按下
  103.         {   
  104.              TR0=0;                         //关定时器0   
  105.             shanruo=0;                    //闪烁标志位关
  106.             P2=0x00;                    //灭显示
  107.             TR1=0;                        //关定时器1   
  108.             if(set==0)
  109.                 set_timedx--;              //南北减1S
  110.             else
  111.                 set_timenb--;              //东西减1S
  112.             if(set_timenb==0)
  113.                 set_timenb=99;   
  114.             if(    set_timedx==0 )
  115.                 set_timedx=99;           //减到1重置99
  116.             sec_nb=set_timenb ;             //设置的数值赋给东西南北
  117.             sec_dx=set_timedx;
  118.               do   
  119.             {
  120.                 display();               //调用显示,用于延时
  121.             }
  122.             while(k2!=1);               //等待按键释放
  123.         }
  124.     }

  125.     if(k3!=1)                            //当K3(确认)键按下时
  126.     {   
  127.         display();                       //调用显示,用于延时消抖
  128.         if(k3!=1)                        //如果确定按下
  129.         {
  130.             TR0=1;                          //启动定时器0
  131.             sec_nb=set_timenb;                //从中断回复,仍显示设置过的数值
  132.             sec_dx=set_timedx;                //显示设置过的时间
  133.             TR1=0;                            //关定时器1   
  134.             if(set==0)                        //时间倒时到0时
  135.             {
  136.                 P2=0X00;                     //灭显示
  137.                 Green_dx=1;                        //东西绿灯亮
  138.                 Red_nb=1;                    //南北红灯亮
  139.                 sec_nb=sec_dx;             //回到初值
  140.             }
  141.             else
  142.             {
  143.                 P2=0x00;                    //南北绿灯,东西红灯
  144.                 Green_nb=1;
  145.                 Red_dx=1;
  146.                 sec_dx=sec_nb;
  147.             }
  148.         }
  149.     }
  150.      
  151.     if(k4!=1)                            //当K4(切换)键按下
  152.     {
  153.         display();                       //调用显示,用于延时消抖
  154.         if(k4!=1)                        //如果确定按下
  155.         {  
  156.              TR0=0;                        //关定时器0   
  157.             set=!set;                    //取反set标志位,以切换调节方向
  158.             TR1=0;                        //关定时器1
  159.             dx_nb=set;
  160.             do
  161.             {
  162.                 display();                //调用显示,用于延时
  163.             }               
  164.             while(k4!=1);              //等待按键释放
  165.         }
  166.     }   

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

  232. void time0(void) interrupt 1 using 1      //定时中断子程序
  233. {
  234.     TH0=0X3C;                            //重赋初值
  235.     TL0=0XB0;                            //12m晶振50ms//重赋初值
  236.     TR0=1;                                //重新启动定时器
  237.     countt0++;                            //软件计数加1
  238.     if(countt0==10)                        //加到10也就是半秒
  239.     {
  240.         if((sec_nb<=4)&&(shanruo==1))          //东西黄灯闪        
  241.         {
  242.             Green_dx=0;
  243.             Yellow_dx=0;
  244.         }                           
  245.         if((sec_dx<=4)&&(shanruo==1))          //南北黄灯闪        
  246.         {  
  247.             Green_nb=0;
  248.             Yellow_nb=0;
  249.         }   
  250.     }
  251.         
  252.     if(countt0==20)                          // 定时器中断次数=20时(即1秒时)
  253.     {    countt0=0;                        //清零计数器
  254.         sec_dx--;                        //东西时间减1
  255.         sec_nb--;                        //南北时间减1

  256.         if((sec_nb<=4)&&(shanruo==1))          //东西黄灯闪        
  257.         {
  258.             Green_dx=0;
  259.             Red_dx=0;
  260.             Yellow_dx=1;
  261.         }                           
  262.         if((sec_dx<=4)&&(shanruo==1))          //南北黄灯闪        
  263.         {  
  264.             Green_nb=0;
  265.             Red_nb=0;
  266.             Yellow_nb=1;
  267.         }                                 
  268.         if(sec_dx==4&&sec_nb==4)         //当东西倒计时到0时,重置5秒,用于黄灯闪烁时间   
  269.         {
  270.             shanruo=1;
  271.         }
  272.         if(sec_nb==4&&sec_dx==4)        //当南北倒计时到0时,重置5秒,用于黄灯闪烁时间   
  273.         {
  274.             shanruo=1;
  275.         }
  276.         if(dx_nb==0&&sec_nb==0)            //当黄灯闪烁时间倒计时到0时,
  277.         {
  278.             P2=0x00;                    //重置东西南背方向的红绿灯
  279.             Green_nb=1;
  280.             Red_dx=1;
  281.             dx_nb=!dx_nb;
  282.             shanruo=0;
  283.             sec_nb=set_timenb;            //重赋南北方向的起始值
  284.             sec_dx=set_timenb;        //重赋东西方向的起始值
  285.         }        
  286.         if(dx_nb==1&&sec_dx==0)            //当黄灯闪烁时间到
  287.         {
  288.             P2=0X00;                    //重置东西南北的红绿灯状态
  289.             Green_dx=1;                     //东西绿灯亮
  290.             Red_nb=1;                     //南北红灯亮
  291.             dx_nb=!dx_nb;                 //取反
  292.             shanruo=0;                    //闪烁
  293.             sec_dx=set_timedx;            //重赋东西方向的起始值
  294.             sec_nb=set_timedx;        //重赋南北方向的起始值
  295.         }
  296.     }   
  297. }
  298. void time1(void) interrupt 3     //定时中断子程序
  299. {
  300.     TH1=0X3C;                            //重赋初值
  301.     TL1=0XB0;                            //12m晶振50ms//重赋初值
  302.     countt1++;                            //软件计数加1
  303.     if(countt1==10)                       // 定时器中断次数=10时(即0.5秒)
  304.     {
  305.             Yellow_nb=0;                //南北黄灯灭
  306.             Yellow_dx=0;                //东西黄灯灭
  307.     }
  308.     if(countt1==20)                          // 定时器中断次数=20时(即1秒时)
  309.     {    countt1=0;                        //清零计数器
  310.             Yellow_nb=1;                    //南北黄灯亮
  311.             Yellow_dx=1;                  //东西黄灯亮
  312.     }   
  313. }

  314. void logo()//开机的Logo  "- - - -"
  315. {
  316.     for(n=0;n<50;n++)    //循环显示----50次
  317.        {
  318.         P0=0x40;  //送形“-”
  319.         P1=0xfe;    //第一位显示
  320.         delay(1);    //延时
  321.         P1=0xfd;    //第二位显示
  322.         delay(1);    //延时
  323.         P1=0Xfb;    //第三位显示
  324.         delay(1);    //延时
  325.         P1=0Xf7;    //第四位显示
  326.         delay(1);    //延时
  327.         P1 = 0xff;    //灭显示
  328.     }
  329. }

  330. void delay(int ms)        //延时子程序
  331. {
  332.     uint j,k;
  333.     for(j=0;j<ms;j++)            //延时ms
  334.        for(k=0;k<124;k++);        //大约1毫秒的延时
  335. }
复制代码

由于自己的水平有限,程序肯定还存在很多的问题,欢迎大家批评指正,大家一起提高技术水平:
交通灯程序改后.rar (280.39 KB, 下载次数: 116)
2017单片机交通灯控制 .doc (1.76 MB, 下载次数: 58)
参考资料:http://www.51hei.com/bbs/dpj-189417-1.html
http://www.51hei.com/bbs/dpj-81606-1.html


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

使用道具 举报

沙发
ID:731930 发表于 2020-6-20 21:06 | 只看该作者
没有图···怎么知道是不是自己需要的
回复

使用道具 举报

板凳
ID:828032 发表于 2020-12-8 15:01 | 只看该作者
可以但是仿真运行出错
回复

使用道具 举报

地板
ID:870116 发表于 2020-12-31 11:23 | 只看该作者
运行显示没有错误和警告但是仿真出来不是我们想要的结果
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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