找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机四项交通灯程序,带按键

  [复制链接]
跳转到指定楼层
楼主
这是我做的51单片机交通灯设计。
用了一个多星期,
里面包含了keil源代码和proteus的仿真图。






交通灯.rar (97.68 KB, 下载次数: 158)
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. uchar data a[4];
  5. uchar data time_dx=20;//东西数默认
  6. uchar data time_nb=30;//南北默认值
  7. uchar data set_timedx=20;//存放设置的数值
  8. uchar data set_timenb=30;
  9. int n; uchar data b;//定时器中断次数

  10. sbit k1=P3^4;//时间加按键
  11. sbit k2=P3^5;//时间减按键
  12. sbit k3=P2^7;//确认/恢复按键
  13. sbit k4=P3^0;//切换方向按键
  14. sbit k5=P3^1;//紧急按键(都不通行60s)
  15. sbit k6=P3^2;//东西通行60s (使用外部中断T0)
  16. sbit k7=P3^3;//南北通行60s (使用外部中断T1)

  17. sbit Yellow_nb=P2^5; //南北黄灯
  18. sbit Yellow_dx=P2^2; //东西黄灯
  19. sbit Green_nb=P2^4; //东西绿灯
  20. sbit Green_dx=P2^1;//南北绿灯
  21. sbit Red_nb=P2^6;//南北红灯
  22. sbit Red_dx=P2^3;//东西红灯
  23. bit time=0;//灯状态循环标志
  24. bit set=1;//调时方向切换键标志
  25. uchar code table[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
  26.                        0x7d,0x07,0x7f,0x6f,0x00}; //共阴数码管编码

  27. void key();//按键扫描子程序
  28. void key_t1();//键处理子程序
  29. void key_t2();
  30. void key_t3();
  31. void display();//显示子程序
  32. void logo(); //开机 LOGO
  33. void delay(int ms);//延时子程序

  34. void main()
  35. {
  36.     TMOD=0X01;//使用定时器T0的模式1
  37.     TH0=0XD8; //定时器T0的高8位赋初值
  38.     TL0=0XF0;// 定时器T0的低8位赋初值
  39.     EA=1; //开总中断
  40.     ET0=1;//定时器T0中断允许
  41.     TR0=1;//开定时器
  42.     EX0=1;//开外部中断0
  43.     EX1=1;//开外部中断1
  44.     logo();//调用logo子程序,显示开机logo
  45.     P2=0Xc3;// 开始默认状态,东西绿灯,南北红灯
  46.     time_nb=time_dx+5; //南北比东西大5s
  47.     while(1)
  48.     {  
  49.         key(); //调用按键扫描程序
  50.                 display(); //调用显示程序  
  51.     }
  52. }

  53. void key() //按键扫描子程序
  54. {
  55.     if(k1!=1) //k1时间加
  56.         {  
  57.             delay(10);  
  58.                 if(k1!=1)  
  59.                 {
  60.                     while(k1!=1) //如果检测到k1按下,则调用key_to1子程序
  61.                         {
  62.                             key_t1();
  63.                                 for(n=0;n<60;n++)//用一个循环,延时,以达到消抖,使每按一次按钮只加一个数
  64.                                 { display();}
  65.                         }  
  66.                 }
  67.         }
  68.         if(k2!=1) //k2时间减
  69.         {  
  70.             delay(10);  
  71.                 if(k2!=1)  
  72.                 {
  73.                     while(k2!=1) //如果检测到k2按下,则调用key_to2子程序
  74.                         {
  75.                             key_t2();
  76.                                 for(n=0;n<60;n++)//用一个循环,延时,以达到消抖,使每按一次按键只减一个数
  77.                                 { display();}
  78.                         }  
  79.                 }
  80.         }
  81.         if(k3!=1)//k3确认/恢复
  82.         {  
  83.             TR0=1; //启动定时器
  84.         time_nb=set_timenb; //从中断回复,显示设置的数值
  85.                 time_dx=set_timedx;  
  86.                 if(time==0) //检测灯循环标志位,若time=0,则南北绿灯,东西红灯,并南北时间比东西大5s
  87.                 { P2=0X99;time_nb=time_dx+5; }  
  88.                 else { P2=0xC3;time_dx=time_nb+5; }//否则东西绿灯,南北红灯,并东西时间比南北大5s
  89.         }  
  90.         if(k4!=1) //k4切换方向
  91.         {  TR0=0;
  92.            delay(5);  
  93.            if(k4!=1)  
  94.            {while(k4!=1); set=!set;}//如果检测到k4按下,则改变方向标志位set
  95.         }
  96.         if(k5!=1) //k5紧急按键,都不通行
  97.         {
  98.             delay(5);
  99.                 if(k5!=1)
  100.                 {
  101.                     while(k5!=1)//如果检测到k5按下,则调用key_to3子程序
  102.                         key_t3();
  103.                 }
  104.         }
  105. }

  106. void key_t1() // 加时间
  107. {
  108.     TR0=0; //关定时器
  109.         if(set==0)
  110.             set_timenb++; //南北加 1S
  111.         else
  112.             set_timedx++; //东西加 1S
  113.         if(set_timenb==100)//加到 100时置 1   
  114.             set_timenb=1;
  115.         if(set_timedx==100)  
  116.             set_timedx=1;  
  117.         time_nb=set_timenb; //设置的数值赋给南北
  118.         time_dx=set_timedx;//设置的数值赋给东西
  119. }

  120. void key_t2() //减时间
  121. {
  122.     TR0=0; //关定时器
  123.         if(set==0)
  124.             set_timenb--; //南北减 1S
  125.     else
  126.             set_timedx--; //东西减 1S
  127.         if(set_timenb==0)  
  128.             set_timenb=99;
  129.         if(set_timedx==0)  
  130.                 set_timedx=99; //减到 1 时重置 99
  131.         time_nb=set_timenb ; //设置的数值赋给南北
  132.         time_dx=set_timedx;//设置的数值赋给东西
  133. }

  134. void key_t3() //紧急(都不通行)
  135. {
  136.     TR0=1; //打开定时器
  137.         P2=0Xc9;
  138.         time_dx=60;
  139.         time_nb=60;
  140. }

  141. void display() //显示子程序
  142. {  
  143.      a[0]=time_dx/10; //东西十位
  144.         a[1]=time_dx%10; //东西个位
  145.         a[2]=time_nb/10; //南北十位
  146.         a[3]=time_nb%10; //南北个位
  147.         P1=0xff; // 初始灯为灭的
  148.         P0=0x00;
  149.         P1=0xfe; //片选 LCD1
  150.         P0=table[a[0]];
  151.         delay(1);  
  152.         P1=0xff;
  153.         P0=0x00;
  154.         P1=0xfd; //片选 LCD2
  155.         P0=table[a[1]];
  156.         delay(1);
  157.         P1=0xff;
  158.         P0=0x00;
  159.         P1=0Xfb; //片选 LCD3  
  160.         P0=table[a[2]];
  161.         delay(1);  
  162.         P1=0xff;
  163.         P0=0x00;  
  164.         P1=0Xf7;  
  165.         P0=table[a[3]]; //片选 LCD4
  166.         delay(1);
  167. }

  168. void time0(void) interrupt 1 using 1 //定时中断子程序
  169. {
  170.     b++;
  171.         if(b==19) // 定时器中断次数
  172.         {
  173.             b=0;  
  174.                 time_dx--;  
  175.                 time_nb--;  
  176.                 if(time_nb<=5&&time==0) //东西黄灯闪
  177.                 {   Green_dx=0;Yellow_dx=!Yellow_dx;}
  178.                 if(time_dx<=5&&time==1) //南北黄灯闪
  179.                 {   Green_nb=0;Yellow_nb=!Yellow_nb;}
  180.         if(time_dx==0&&time_nb==5)  
  181.                 time_dx=5;  
  182.             if(time_nb==0&&time_dx==5)  
  183.                 time_nb=5;
  184.             if(time==0&&time_nb==0)
  185.             {
  186.                 P2=0x99;time=!time;
  187.                     time_nb=set_timenb;
  188.                     time_dx=set_timenb+5;
  189.             }  
  190.             if(time==1&&time_dx==0)  
  191.             {
  192.                 P2=0Xc3;
  193.                     time=!time;
  194.                     time_dx=set_timedx;
  195.                     time_nb=set_timedx+5;
  196.             }  
  197.         }
  198. }

  199. void int0(void) interrupt 0 using 1  //使用外部中断控制,东西通行,南北不通行
  200. {
  201.     TR0=1;//打开定时器
  202.         P2=0Xc3;//东西绿灯,南北红灯  
  203.         time_dx=60;
  204.         time_nb=60;
  205. }

  206. void int1(void) interrupt 2 using 1  //使用外部中断控制,南北通行,东西不通行
  207. {
  208.     TR0=1; //打开定时器
  209.         P2=0X99;//南北绿灯,东西红灯  
  210.         time_nb=60;
  211.         time_dx=60;
  212. }

  213. void logo()//开机显示"- -"
  214. {
  215.     for(n=0;n<50;n++)
  216.         { P0=0x40;
  217.       P1=0xfe;
  218.           delay(1);
  219.           P1=0xfd;
  220.           delay(1);
  221.           P1=0Xfb;
  222.           delay(1);
  223.           P1=0Xf7;
  224.           delay(1);
  225.           P1 = 0xff;
  226.           }
  227. }

  228. void delay(int ms) //延时子程序
  229. {
  230.     uint j,k;
  231.         for(j=0;j<ms;j++)
  232.         for(k=0;k<124;k++);
  233. }        
复制代码



请大家多多指教。

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:863537 发表于 2020-12-19 17:40 来自手机 | 只看该作者
谢谢了 最近正在做单片机设计 学习!!
回复

使用道具 举报

板凳
ID:79544 发表于 2021-11-16 17:16 | 只看该作者
楼主辛苦感谢分享!!!!!!!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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