找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机的交通灯制作资料 4个数码管显示

[复制链接]
跳转到指定楼层
楼主
里面有仿真图,源代码。.hex文件等等。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


制作出来的实物图如下:


单片机源程序如下:
  1. #include <reg52.h>                 //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义        变量范围0~255
  3. #define uint  unsigned int         //无符号整型 宏定义        变量范围0~65535

  4. //数码管段选定义  0   1   2    3    4    5         6         7          8           9   A        B               
  5. uchar smg_du[]={0x40,0x75,0x0c,0x14,0x31,0x12,0x02,0x74,0x00,0x10,0x20,0x03,};         //断码

  6. uchar dis_smg[4] = {0};           //数码管显示数组的缓冲区

  7. //数码管位选定义
  8. sbit smg_we1 = P2^0;            //数码管位选IO口定义
  9. sbit smg_we2 = P2^1;                //数码管位选IO口定义
  10. sbit smg_we3 = P3^6;                //数码管位选IO口定义
  11. sbit smg_we4 = P3^7;                //数码管位选IO口定义

  12. sbit key1 = P1^0;            //按键IO口定义
  13. sbit key2 = P1^1;                //按键IO口定义
  14. sbit key3 = P1^2;                //按键IO口定义
  15. sbit key4 = P1^3;                //按键IO口定义

  16. uchar menu_1;                            //设置不同参数的变量

  17. char dx_s = 0,nb_s = 0;        //东西  南北 倒计时变量

  18. sbit dx_red    = P2^7;            //东西红灯IO口定义
  19. sbit dx_green  = P2^6;                //东西绿灯IO口定义
  20. sbit dx_yellow = P2^5;                //东西黄灯IO口定义

  21. sbit nb_red    = P2^4;                //南北红灯IO口定义
  22. sbit nb_green  = P2^3;                //南北绿灯IO口定义
  23. sbit nb_yellow = P2^2;                //南北黄灯IO口定义        

  24. bit flag_1s = 0;          //1秒的变量
  25. bit flag_500ms;                  //500毫秒的变量
  26. bit flag_dx_nb = 0;   //东西南北模式
  27. uchar dx_time = 30,nb_time = 20;   //东西、南北的时间
  28. uchar flag_jdgz ;     //交通管制

  29. /***********************数码位选函数*****************************/
  30. void smg_we_switch(uchar i)
  31. {
  32.         switch(i)
  33.         {
  34.                 case 0: smg_we1 = 0;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 1; break;
  35.                 case 1: smg_we1 = 1;  smg_we2 = 0; smg_we3 = 1;  smg_we4 = 1; break;
  36.                 case 2: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 0;  smg_we4 = 1; break;
  37.                 case 3: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 0; break;
  38.         }        
  39. }

  40. /********************************************************************
  41. * 名称 : delay_1ms()
  42. * 功能 : 延时1ms函数
  43. * 输入 : q
  44. * 输出 : 无
  45. ***********************************************************************/
  46. void delay_1ms(uint q)
  47. {
  48.         uint i,j;
  49.         for(i=0;i<q;i++)
  50.                 for(j=0;j<120;j++);
  51. }

  52. uchar i;
  53. /********************************************************************
  54. * 名称 : display()
  55. * 功能 : 数码管显示
  56. * 输入 : 无
  57. * 输出 : 无
  58. ***********************************************************************/
  59. void display()
  60. {
  61.          for(i=0;i<4;i++)
  62.         {               
  63.                 P0 = 0xff;                  //消隐
  64.                 smg_we_switch(i);            //位选
  65.                 P0 = dis_smg;          //段选         
  66.                 delay_1ms(3);                  //延时
  67.         }
  68. }

  69. /*********************定时器0、定时器1初始化******************/
  70. void time0_init()         
  71. {
  72.         EA  = 1;                   //开总中断
  73.         TMOD = 0X01;          //定时器0工作方式1
  74.         ET0 = 1;                  //开定时器0中断
  75.         TR0 = 1;                  //允许定时器0定时
  76.         TH0 = 0x3c;
  77.         TL0 = 0xb0;     //50ms
  78. }

  79. /*********************交通灯处理函数*********************************/
  80. void jiaotongdeng_dis()
  81. {
  82.         if(flag_1s == 1)           //1秒执行一次里面的程序  
  83.         {
  84.                 flag_1s = 0;
  85.                 if(flag_dx_nb == 0)           //南北绿灯时间
  86.                 {
  87.                         dx_s --;                   //东西倒计时时间减1
  88.                         nb_s --;                   //南北倒计时时间减1
  89.                         if(dx_s == 5)
  90.                                 nb_s = 5;
  91.                 }
  92.                 if(flag_dx_nb == 1)           //东西绿灯时间
  93.                 {
  94.                         dx_s --;                   //南北倒计时时间减1
  95.                         nb_s --;                   //东西倒计时时间减1
  96.                         if(nb_s == 5)
  97.                                 dx_s = 5;
  98.                 }
  99.                 if(dx_s <= 0)                  //倒计时时间为0切换东西 南北绿灯时间
  100.                 {
  101.                         flag_dx_nb = ~flag_dx_nb;
  102.                         if(flag_dx_nb == 1)         //东西时间
  103.                         {
  104.                                 dx_s = dx_time;         
  105.                                 nb_s = dx_time + 5;
  106.                         }
  107.                         else                                  //南北时间
  108.                         {
  109.                                 dx_s = nb_time + 5;        
  110.                                 nb_s = nb_time;         
  111.                         }
  112.                 }
  113.         }
  114.         dis_smg[0] = smg_du[dx_s % 10] ;        //显示东西倒计时 时间
  115.         dis_smg[1] = smg_du[dx_s / 10] ;
  116.         dis_smg[2] = smg_du[nb_s % 10] ;        //显示南北倒计时 时间  
  117.         dis_smg[3] = smg_du[nb_s / 10] ;

  118. /***********************南北时间*********************************/
  119.         if(flag_dx_nb == 0)  
  120.         {
  121.                 if(dx_s > 5)
  122.                 {
  123.                         dx_red    = 0;     //东西红灯亮
  124.                         dx_green  =        1;           //东西红灯灭
  125.                         dx_yellow = 1;           //东西黄灯灭
  126.                         nb_red    = 1;     //南北红灯灭
  127.                         nb_green  =        0;           //南北绿灯亮
  128.                         nb_yellow = 1;           //南北黄灯灭

  129.                 }else if(dx_s <= 5)                 //当小于5秒时  黄灯要闪了
  130.                 {
  131.                         dx_red    = 0;     //东西红灯灭
  132.                         dx_green  =        1;           //东西红灯灭
  133.                         dx_yellow = 1;           //东西黄灯灭
  134.                         nb_red    = 1;     //南北红灯灭
  135.                         nb_green  =        1;           //南北绿灯灭
  136.                         if(flag_500ms == 0)           //黄灯闪烁
  137.                         {
  138.                                 nb_yellow = 0;        //亮        
  139.                         }
  140.                         else
  141.                         {
  142.                                 nb_yellow = 1;        //灭        
  143.                         }
  144.                 }
  145.         }
  146. /***********************东西时间*********************************/
  147.         if(flag_dx_nb == 1)  
  148.         {
  149.                 if(nb_s > 5)
  150.                 {
  151.                         dx_red    = 1;  //东西红灯灭
  152.                         dx_green  =        0;        //东西红灯亮
  153.                         dx_yellow = 1;        //东西黄灯灭
  154.                         nb_red    = 0;  //南北红灯亮
  155.                         nb_green  =        1;        //南北绿灯灭
  156.                         nb_yellow = 1;        //南北黄灯灭
  157.                 }else if(nb_s <= 5)                 //当小于5秒时  黄灯要闪了
  158.                 {
  159.                         dx_red    = 1;    //东西红灯灭
  160.                         dx_green  =        1;          //东西红灯灭
  161.                         nb_red    = 0;    //南北红灯亮
  162.                         nb_green  =        1;          //南北绿灯灭
  163.                         nb_yellow = 1;          //南北黄灯灭
  164.                         if(flag_500ms == 0)         //黄灯闪烁
  165.                         {
  166.                                 dx_yellow = 0;//东西黄灯亮        
  167.                         }
  168.                         else
  169.                         {
  170.                                 dx_yellow = 1;//东西黄灯灭        
  171.                         }

  172.                 }
  173.         }                        
  174. }

  175. /********************独立按键程序*****************/
  176. uchar key_can;         //按键值

  177. void key()         //独立按键程序
  178. {
  179.         static uchar key_new;        //key_new  这个变量的功能是做按键松手检测的
  180.         key_can = 0;                //按键值还原成0
  181.          if(key1 == 0 || key2 == 0 || key3 == 0 || key4 == 0)                //有按键按下
  182.         {
  183.                 delay_1ms(1);                     //按键延时消抖动
  184.                 if(key_new == 1)
  185.                 {                                         
  186.                         key_new = 0;                //key_new = 0   说明按键已按下
  187.                         if(key1 == 0)                //确认是按键按下
  188.                                 key_can = 1;         //得到按键值
  189.                         if(key2 == 0)                //确认是按键按下
  190.                                 key_can = 2;         //得到按键值
  191.                         if(key3 == 0)                //确认是按键按下
  192.                                 key_can = 3;         //得到按键值
  193.                         if(key4 == 0)                //确认是按键按下
  194.                                 key_can = 4;         //得到按键值
  195.                 }                        
  196.         }
  197.         else
  198.                 key_new = 1;         //key_new = 1   说明按键已经松开了        
  199. }



  200. /********************设置函数*****************/
  201. void key_with()
  202. {
  203.         if(key_can == 4)   //交通管制按键
  204.         {
  205.                 flag_jdgz ++;
  206.                 if(flag_jdgz > 4)
  207.                         flag_jdgz = 0;        
  208.                 if(flag_jdgz == 1)         //  全部亮红灯
  209.                 {
  210.                         dx_red    = 0;  //东西红灯亮
  211.                         dx_green  =        1;        //东西绿灯灭
  212.                         dx_yellow = 1;        //东西黄灯灭
  213.                         nb_red    = 0;  //南北红灯亮
  214.                         nb_green  =        1;        //南北绿灯灭
  215.                         nb_yellow = 1;        //南北黄灯灭                        
  216.                 }
  217.                 if(flag_jdgz == 2)         //  东西红灯  南北绿灯
  218.                 {
  219.                         dx_red    = 0;  //东西红灯亮
  220.                         dx_green  =        1;        //东西绿灯灭
  221.                         dx_yellow = 1;        //东西黄灯灭
  222.                         nb_red    = 1;  //南北红灯灭
  223.                         nb_green  =        0;        //南北绿灯亮
  224.                         nb_yellow = 1;        //南北黄灯灭                        
  225.                 }
  226.                 if(flag_jdgz == 3)         //  南北红灯  东西绿灯
  227.                 {
  228.                         dx_red    = 1;  //东西红灯灭
  229.                         dx_green  =        0;        //东西绿灯亮
  230.                         dx_yellow = 1;        //东西黄灯灭
  231.                         nb_red    = 0;  //南北红灯亮
  232.                         nb_green  =        1;        //南北绿灯灭
  233.                         nb_yellow = 1;        //南北黄灯灭                        
  234.                 }
  235.                  if(flag_jdgz == 4)         //  南北黄灯闪  东西黄灯闪
  236.                 {
  237.                         dx_red    = 1;  //东西红灯灭
  238.                         dx_green  =        1;        //东西绿灯灭
  239.                          nb_red    = 1;  //南北红灯灭
  240.                         nb_green  =        1;        //南北绿灯灭
  241.                  }
  242.         }
  243.         if(key_can == 1)          //设置键
  244.         {
  245.                 menu_1 ++;
  246.                 if(menu_1 >= 3)
  247.                 {
  248.                         menu_1  = 0;  //menu_1 = 0 是在正常显示界面下
  249.                 }
  250.         }

  251.         if(menu_1 == 1)           //设置东西绿灯的时间
  252.         {
  253.                 if(key_can == 2)
  254.                 {
  255.                         dx_time ++ ;                //设置东西绿灯的时间 加1
  256.                         if(dx_time > 99)
  257.                                 dx_time = 99;
  258.                 }
  259.                 if(key_can == 3)
  260.                 {
  261.                         dx_time -- ;                //设置东西绿灯的时间 减1
  262.                         if(dx_time <= 5)
  263.                                 dx_time = 5;
  264.                 }
  265.                 dis_smg[0] = smg_du[dx_time % 10] ;                //显示设置的东西绿灯的时间 个位数
  266.                 dis_smg[1] = smg_du[dx_time / 10] ;            //显示设置的东西绿灯的时间 十位数
  267.                 dis_smg[2] = smg_du[10] ;        //显示为A
  268.                 dis_smg[3] = smg_du[10] ;        //显示为A
  269.          }        
  270.         if(menu_1 == 2)           //设置南北绿灯的时间
  271.         {
  272.                 if(key_can == 2)
  273.                 {
  274.                         nb_time ++ ;                //设置南北绿灯的时间 加1
  275.                         if(nb_time > 99)
  276.                                 nb_time = 99;
  277.                 }
  278.                 if(key_can == 3)
  279.                 {
  280.                         nb_time -- ;                //设置南北绿灯的时间 减1
  281.                         if(nb_time <= 5)
  282.                                 nb_time = 5;
  283.                 }
  284.                 dis_smg[0] = smg_du[11] ;        //显示为B
  285.                 dis_smg[1] = smg_du[11] ;        //显示为B
  286.                 dis_smg[2] = smg_du[nb_time % 10] ;                //显示设置的南北绿灯的时间 个位数
  287.                 dis_smg[3] = smg_du[nb_time / 10] ;                //显示设置的南北绿灯的时间 十位数
  288.          }
  289. }


  290. /********************************************************************
  291. * 名称 : main()
  292. * 功能 : 实现灯的闪烁
  293. * 输入 : 无
  294. * 输出 : 无
  295. ***********************************************************************/
  296. void main()
  297. {
  298.          time0_init();                  //定时器初始化程序
  299.          dx_s = nb_time + 5;          //南北时间
  300.         nb_s = nb_time ;          //东西时间
  301.         while(1)
  302.         {
  303.                 key();                           //按键函数
  304.                 if(key_can > 0)           //有按键按下
  305.                         key_with();           //按键处理函数
  306.                 if((menu_1 == 0) && (flag_jdgz == 0))
  307.                         jiaotongdeng_dis();           //交通灯处理函数

  308.                 if(flag_jdgz == 4)        //夜间模式
  309.                         if(flag_500ms == 1)                //  南北黄灯闪  东西黄灯闪
  310.                         {
  311.                                 flag_500ms = 0;
  312.                                 nb_yellow = ~nb_yellow;           //  东西黄灯闪
  313.                                 dx_yellow = ~dx_yellow;           //  东西黄灯闪
  314.                         }        
  315.                 display();         //数码管显示函数
  316.         }
  317. }  

  318. /*********************定时器0中断服务程序************************/
  319. void time0_int() interrupt 1  
  320. {                                                   
  321.         static  uchar value;                         //定时50ms中断一次
  322.         TH0 = 0x3c;
  323.         TL0 = 0xb0;     //50ms
  324.         value ++;
  325.          if(value % 10 == 0)
  326.                 flag_500ms = ~flag_500ms;           //定时产生一个500毫秒的变量
  327.         if(value >= 20)
  328.         {
  329.                 value = 0;
  330.                 flag_1s = 1;         //定时产生一个1秒的变量
  331.         }
  332. }
复制代码

Keil代码与Proteus仿真下载: 交通灯 4个数码管 大 1.7z (787.53 KB, 下载次数: 188)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:1112889 发表于 2024-3-15 14:39 来自手机 | 只看该作者
用Proteus8.13打开
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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