找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机交通灯按键时间修改不管用

  [复制链接]
跳转到指定楼层
楼主
能进入修改模式加减修改时间,可是一旦退出修改模式后,数码管还是按照修改前的时间倒计时,时间根本就没变的,请问需要修改哪里呢?谢谢

单片机源程序:
  1. #include <reg52.h>            
  2. #define uchar unsigned char   
  3. #define u8 unsigned char   
  4. #define uint  unsigned int      

  5. //上下南北主干道
  6. //左右东西辅干道

  7. u8 code DisplayOther[]={
  8. 0xff,         //  空
  9. 0x7f,        //   "."
  10. 0xbf,        //   "-"
  11. 0xa7         //  c
  12. };

  13. //数码管段选定义   0    1    2     3      4      5       6      7        8      9        a      b        c       d         e       f        -
  14. uchar code smg_du[17] = {
  15. 0xc0,        //0
  16. 0xf9,        //1
  17. 0xa4,        //2
  18. 0xb0,        //3
  19. 0x99,        //4
  20. 0x92,        //5
  21. 0x82,        //6
  22. 0xf8,        //7
  23. 0x80,        //8
  24. 0x90,        //9
  25. 0x88,        //A
  26. 0x83,        //b
  27. 0xc6,        //C
  28. 0xa1,        //d
  29. 0x86,        //E
  30. 0x8e        //F
  31. };        
  32. uchar dis_smg[8 ] = {0xc0,0xf5,0x8c,0x94,0xb1,0x92,0x82,0xf4};        
  33. uchar smg_i = 4;    //显示数码管的个位数

  34. //数码管位选定义
  35. sbit smg_we1 = P2^0;        //东西数码管2
  36. sbit smg_we2 = P2^1;            //东西数码管1
  37. sbit smg_we3 = P2^3;            //南北数码管2
  38. sbit smg_we4 = P2^2;            //南北数码管1


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

  40. sbit nb_red    = P1^0;        //南北红灯
  41. sbit nb_green  = P1^2;        //南北绿灯
  42. sbit nb_yellow = P1^1;        //南北黄灯    1

  43. sbit dx_red    = P1^3;        //东西红灯
  44. sbit dx_green  = P1^5;        //东西绿灯1
  45. sbit dx_yellow = P1^4;        //东西黄灯1

  46. uchar flag_jtd_mode;  //交通灯的模式 根据时间
  47. bit flag_1s = 1;        //进入南北方向切换的标志位
  48. bit flag_500ms;
  49. bit flag_dx_nb;         //东西南北模式
  50. uchar flag_5m_value;
  51. uchar i;
  52. uchar flag_alarm;    //模式
  53. //uchar dx_time = 30,nb_time = 20;   //东西、南北的时间
  54. uchar dx_time = 20,nb_time = 30;   //东西、南北的时间
  55. uchar flag_jdgz ;     //交通管制

  56. /********************************************************************
  57. * 名称 : u8 ChangeFor(u8 dat)
  58. * 功能 : 交换一个字节位的位置,用于数码管显示
  59. * 输入 : 需要改变的数
  60. * 输出 : 改变后的数
  61. ***********************************************************************/
  62. #define LED_a        6    //数码管段选的a段接在段选IO口的第0位
  63. #define LED_b        5
  64. #define LED_c        0
  65. #define LED_d        2
  66. #define LED_e        1
  67. #define LED_f        4
  68. #define LED_g        3
  69. #define LED_dp    7

  70. u8 ChangeFor(u8 dat)
  71. {
  72.     u8 temp=0;
  73.     if(dat&0x01)        //判断数据的第一位是否为1
  74.         temp|=0x01<<LED_a;//如果为1,放到控制数码管a段的位置
  75.     if(dat&0x02)
  76.         temp|=0x01<<LED_b;
  77.     if(dat&0x04)
  78.         temp|=0x01<<LED_c;
  79.     if(dat&0x08)
  80.         temp|=0x01<<LED_d;
  81.     if(dat&0x10)
  82.         temp|=0x01<<LED_e;
  83.     if(dat&0x20)
  84.         temp|=0x01<<LED_f;
  85.     if(dat&0x40)
  86.         temp|=0x01<<LED_g;
  87.     if(dat&0x80)
  88.         temp|=0x01<<LED_dp;
  89.     return temp;
  90. }

  91. /***********************数码位选函数*****************************/
  92. //i:    0,东西数码管2
  93. //        1,东西数码管1
  94. //        2,南北数码管2
  95. //        3,南北数码管1
  96. void smg_we_switch(uchar i)
  97. {
  98.     switch(i)
  99.     {
  100.         case 0: smg_we1 = 0;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 1; break;
  101.         case 1: smg_we1 = 1;  smg_we2 = 0; smg_we3 = 1;  smg_we4 = 1; break;
  102.         case 2: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 0;  smg_we4 = 1; break;
  103.         case 3: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 0; break;
  104.     }   
  105. }


  106. /********************************************************************
  107. * 名称 : delay_1ms()
  108. * 功能 : 延时1ms函数
  109. * 输入 : q
  110. * 输出 : 无
  111. ***********************************************************************/
  112. void delay_1ms(uint q)
  113. {
  114.     uint i,j;
  115.     for(i=0;i<q;i++)
  116.         for(j=0;j<110;j++);
  117. }


  118. /********************************************************************
  119. * 名称 : display()
  120. * 功能 : 数码管显示
  121. * 输入 : 无
  122. * 输出 : 无
  123. ***********************************************************************/
  124. void DisplayScan()
  125. {
  126.     static uchar i;
  127. //    if(T_MS_SCAN>=3)
  128.     {
  129.         {        
  130.         P0 = 0xff;              //消隐
  131.             smg_we_switch(i);                    //位选
  132.         P0 =    ChangeFor(dis_smg[i]);          //段选      
  133.         delay_1ms(3);
  134.         }
  135.         i++;
  136.         if(i>=4)
  137.             i=0;
  138. //        T_MS_SCAN=0;
  139.     }
  140. }
  141. /*********************定时器0、定时器1初始化******************/
  142. void time0_init()      
  143. {
  144.     TMOD = 0x01;                    //设置定时器0为工作模式1 (16-bit)
  145.     TL0 = 15536;                    //给定时器低位赋初始值        65536-15536=50000us=50ms,即50ms一个中断
  146.     TH0 = 15536 >> 8;               //给定时器高位赋初始值
  147.     TR0 = 1;                        //开启定时器0
  148.     ET0 = 1;                        //允许定时器0中断
  149.     EA = 1;                         //开启全局中断
  150. }

  151. /*********************交通灯处理函数*********************************/
  152. void jiaotongdeng_dis()
  153. {
  154.     if(flag_1s == 1)//如果切换标志为1
  155.     {
  156.         flag_1s = 0;    //清零标志位
  157.         if(dx_s == 0)
  158.         {
  159.             if(flag_dx_nb == 1)
  160.                 dx_s = nb_time;      //南北时间
  161.             else
  162.                 dx_s = dx_time;      //东西时间
  163.             flag_dx_nb = ~flag_dx_nb;        //切换南北时间
  164.         }
  165.         dx_s --;
  166.     }

  167. /***********************南北时间*********************************/
  168.         if(flag_dx_nb == 0)  
  169.         {
  170.             if(dx_s > 3)
  171.             {
  172.                 dis_smg[0] = smg_du[dx_s % 10] ;
  173.                 dis_smg[1] = smg_du[dx_s / 10] ;
  174.                 dis_smg[2] = smg_du[(dx_s-3) % 10] ;
  175.                 dis_smg[3] = smg_du[(dx_s-3) / 10] ;

  176.                 dx_red    = 1;  //灭
  177.                 dx_yellow = 1;    //灭
  178.                 nb_green  =    1;    //灭
  179.                 nb_yellow = 1;    //灭
  180.                 dx_green  =    0;    //亮
  181.                 nb_red    = 0;  //亮
  182.                 flag_5m_value = 0;   
  183.             }else if(dx_s <= 3)         //当小于3秒时  黄灯要闪了
  184.             {
  185.                 dis_smg[0] = smg_du[dx_s % 10] ;
  186.                 dis_smg[1] = smg_du[dx_s / 10] ;
  187.                 dis_smg[2] = smg_du[dx_s % 10] ;
  188.                 dis_smg[3] = smg_du[dx_s / 10] ;

  189.                 dx_red    = 1;    //灭
  190.                 dx_green  =    1;      //灭
  191.                 nb_green  =    1;      //灭
  192.                 nb_yellow = 1;      //灭
  193.                 nb_red    = 0;    //亮
  194.                 if(flag_500ms == 0)
  195.                 {
  196.                     dx_yellow = 0;//亮   
  197.                 }
  198.                 else
  199.                 {
  200.                     dx_yellow = 1;//灭   
  201.                 }
  202.             }
  203.         }
  204. /***********************东西时间*********************************/
  205.         if(flag_dx_nb == 1)  
  206.         {
  207.             if(dx_s > 3)
  208.             {
  209.                 dis_smg[2] = smg_du[dx_s % 10] ;
  210.                 dis_smg[3] = smg_du[dx_s / 10] ;
  211.                 dis_smg[0] = smg_du[(dx_s-3) % 10] ;
  212.                 dis_smg[1] = smg_du[(dx_s-3) / 10] ;

  213.                 dx_red    = 0;     //亮
  214.                 nb_green  =    0;       //亮
  215.                 nb_yellow = 1;       //灭
  216.                 dx_green  =    1;       //灭
  217.                 dx_yellow = 1;       //灭
  218.                 nb_red    = 1;     //灭
  219.                 flag_5m_value = 0;   
  220.             }else if(dx_s <= 3)         //当小于3秒时  黄灯要闪了
  221.             {
  222.                 dis_smg[0] = smg_du[dx_s % 10] ;
  223.                 dis_smg[1] = smg_du[dx_s / 10] ;
  224.                 dis_smg[2] = smg_du[dx_s % 10] ;
  225.                 dis_smg[3] = smg_du[dx_s / 10] ;

  226.                 dx_red    = 0;     //灭
  227.                 dx_green  =    1;       //灭
  228.                 dx_yellow = 1;       //灭
  229.                 nb_red    = 1;     //灭
  230.                 nb_green  =    1;       //灭
  231.                 if(flag_500ms == 0)       //黄灯闪烁
  232.                 {
  233.                     nb_yellow = 0;    //亮   
  234.                 }
  235.                 else
  236.                 {
  237.                     nb_yellow = 1;    //灭   
  238.                 }
  239.             }
  240.     }            
  241. }
  242. uchar key_can;     //按键值

  243. //按键
  244. sbit Key1=P1^6;                 //设置键
  245. sbit Key2=P1^7;                 //加按键
  246. sbit Key3=P3^2;                 //减按键
  247. sbit Key4=P3^3;                 //交通管制键
  248. //========================================================================
  249. // 函数: u8 Key_Scan()
  250. // 应用: temp=u8 Key_Scan();
  251. // 描述: 按键扫描并返回按下的键值
  252. // 参数: NONE
  253. // 返回: 按下的键值
  254. // 备注: 该函数带松手检测,按下键返回一次键值后返回0,直至第二次按键按下
  255. //========================================================================
  256. u8 Key_Scan()
  257. {     
  258.     static u8 key_up=1;//按键按松开标志
  259.     if(key_up&&(Key1==0||Key2==0||Key3==0||Key4==0))
  260.     {
  261.         delay_1ms(10);//去抖动
  262.         key_up=0;
  263.         if(Key1==0)            return 1;
  264.         else if(Key2==0)return 2;
  265.         else if(Key3==0)return 3;
  266.         else if(Key4==0)return 4;
  267.     }
  268.     else if(Key1==1&&Key2==1&&Key3==1&&Key4==1)
  269.         key_up=1;         
  270.      return 0;// 无按键按下
  271. }


  272. uchar flag_s;
  273. uchar menu_1;//纵横加减标示


  274. /********************设置函数*****************/
  275. void key_with()
  276. {
  277.     if(key_can == 4)   //交通管制按键
  278.     {
  279.         flag_jdgz ++;
  280.         if(flag_jdgz > 5)
  281.             flag_jdgz = 0;   
  282.         if(flag_jdgz == 1)     //  全部亮红灯
  283.         {
  284.             dx_red    = 0;  //亮
  285.             nb_red    = 0;  //亮
  286.             dx_green  =    1;    //灭
  287.             dx_yellow = 1;    //灭
  288.             nb_green  =    1;    //灭
  289.             nb_yellow = 1;    //灭            
  290.         }
  291.         if(flag_jdgz == 2)     //  东西绿灯  南北红灯
  292.         {
  293.             dx_red    = 0;  //亮
  294.             nb_green  =    0;    //亮
  295.             dx_green  =    1;    //灭
  296.             dx_yellow = 1;    //灭
  297.             nb_red    = 1;  //灭
  298.             nb_yellow = 1;    //灭            
  299.         }
  300.         if(flag_jdgz == 3)     //  南北绿灯  东西红灯
  301.         {
  302.             dx_green  =    0;    //亮
  303.             nb_red    = 0;  //亮
  304.             dx_red    = 1;  //灭
  305.             dx_yellow = 1;    //灭
  306.             nb_green  =    1;    //灭
  307.             nb_yellow = 1;    //灭            
  308.         }
  309.         if(flag_jdgz == 4)     //  南北绿灯  东西绿灯
  310.         {
  311.             dx_green  =    0;    //亮
  312.             nb_green  =    0;    //亮
  313.             dx_red    = 1;  //灭
  314.             dx_yellow = 1;    //灭
  315.             nb_red    = 1;  //灭
  316.             nb_yellow = 1;    //灭            
  317.         }
  318.         if(flag_jdgz == 5)     //  南北黄灯  东西黄灯
  319.         {
  320.             dx_red    = 1;  //灭
  321.             dx_green  =    1;    //灭
  322.             nb_red    = 1;  //灭
  323.             nb_green  =    1;    //灭
  324.             nb_yellow = 0;    //亮            
  325.             dx_yellow = 0;    //亮
  326.         }
  327.     }
  328.     if(key_can == 1)      //设置键
  329.     {
  330.         menu_1 ++;
  331.         if(menu_1 >= 3)
  332.         {
  333.             menu_1  = 0;
  334.         }
  335.     }

  336.     if(menu_1 == 1)       //设置东西的时间
  337.     {
  338.         if(key_can == 2)
  339.         {
  340.             dx_time ++ ;        //加1
  341.             if(dx_time > 99)    //时间最大值为99s
  342.                 dx_time = 99;
  343.         }
  344.         if(key_can == 3)
  345.         {
  346.             dx_time -- ;        //减1
  347.             if(dx_time <= 5)//时间最小值为5s
  348.                 dx_time = 5;
  349.         }
  350.         dis_smg[0] = smg_du[(dx_time-1) % 10] ;    //显示为A
  351.         dis_smg[1] = smg_du[(dx_time-1) / 10] ;    //显示为A
  352.         dis_smg[2] = DisplayOther[2] ;        //显示东西设置的时候
  353.         dis_smg[3] = DisplayOther[2] ;   
  354.     }
  355.    
  356.     if(menu_1 == 2)       //设置南北的时间
  357.     {
  358.         if(key_can == 2)
  359.         {
  360.             nb_time ++ ;        //加1
  361.             if(nb_time > 99)//时间最大值为99s
  362.                 nb_time = 99;
  363.         }
  364.         if(key_can == 3)
  365.         {
  366.             nb_time -- ;        //减1
  367.             if(nb_time <= 5)//时间最小值为5s
  368.                 nb_time = 5;
  369.         }
  370.         dis_smg[0] = DisplayOther[2] ;    //显示为B
  371.         dis_smg[1] = DisplayOther[2] ;    //显示为B
  372.         dis_smg[2] = smg_du[(nb_time-1) % 10] ;        //显示东西设置的时候
  373.         dis_smg[3] = smg_du[(nb_time-1) / 10] ;   
  374.     }
  375. }

  376. /********************************************************************
  377. * 名称 : main()
  378. * 功能 : 实现灯的闪烁
  379. * 输入 : 无
  380. * 输出 : 无
  381. ***********************************************************************/
  382. void main()
  383. {
  384.     time0_init();
  385.     dx_s = nb_time;      //东西时间
  386.     while(1)
  387.     {
  388.         key_can=Key_Scan();
  389.         if(key_can )
  390.             key_with();
  391.         if((menu_1 == 0) && (flag_jdgz == 0))
  392.             jiaotongdeng_dis();
  393.         DisplayScan();   
  394.     }
  395. }  

  396. /*********************定时器0中断服务程序************************/
  397. void time0_int() interrupt 1  
  398. {                           
  399.     static uchar value;             //定时10ms中断一次
  400.     TL0 = 15536;                    //给定时器低位重装初始值        65536-15536=50000us=50ms,即50ms一个中断
  401.     TH0 = 15536 >> 8;               //给定时器高位重装初始值
  402.     value ++;
  403.     flag_5m_value++;
  404.     if(flag_5m_value % 10 == 0)
  405.         flag_500ms = ~flag_500ms;
  406.     if(value >= 20)
  407.     {
  408.         value = 0;
  409.         flag_1s = 1;
  410.     }
  411. }
复制代码


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

使用道具 举报

沙发
ID:123289 发表于 2017-11-24 12:16 | 只看该作者
改完了存一下
回复

使用道具 举报

板凳
ID:242293 发表于 2017-11-24 22:22 | 只看该作者

有道理
回复

使用道具 举报

地板
ID:267205 发表于 2017-12-26 16:37 | 只看该作者
老哥,你这是怎么改的啊,我看了半天没看出来,很难受
回复

使用道具 举报

5#
ID:267231 发表于 2017-12-26 17:04 | 只看该作者
不错不错不错
回复

使用道具 举报

6#
ID:84283 发表于 2017-12-26 19:02 | 只看该作者
改完后,标志位IF 进去存下。
回复

使用道具 举报

7#
ID:267639 发表于 2017-12-27 12:44 | 只看该作者
不错不错,正在研究
回复

使用道具 举报

8#
ID:267205 发表于 2017-12-27 15:00 | 只看该作者
有没有老哥解释下怎么保存啊,怎么有点看不懂,难受的不行
回复

使用道具 举报

9#
ID:464230 发表于 2019-5-2 10:10 | 只看该作者
qq1105424012 发表于 2017-12-26 19:02
改完后,标志位IF 进去存下。

怎么存啊,能解释下吗
回复

使用道具 举报

10#
ID:997689 发表于 2021-12-28 11:15 | 只看该作者
网络标号是不是标错了啊,数码管显示不了


回复

使用道具 举报

11#
ID:988078 发表于 2021-12-28 15:04 | 只看该作者
改完再次编译,重新开始调
回复

使用道具 举报

12#
ID:997689 发表于 2021-12-29 10:14 | 只看该作者
897024066 发表于 2021-12-28 15:04
改完再次编译,重新开始调

数码管十位显示不了怎么改啊

回复

使用道具 举报

13#
ID:997689 发表于 2021-12-29 10:19 | 只看该作者
897024066 发表于 2021-12-28 15:04
改完再次编译,重新开始调

为啥我的十位显示不了啊
回复

使用道具 举报

14#
ID:161164 发表于 2021-12-29 14:22 | 只看该作者
18870442543 发表于 2021-12-29 10:19
为啥我的十位显示不了啊

代码没问题


请检查仿真/硬体接线
回复

使用道具 举报

15#
ID:997689 发表于 2021-12-30 08:33 | 只看该作者

有根线没连
回复

使用道具 举报

16#
ID:997689 发表于 2021-12-31 01:10 | 只看该作者
三极管驱动模块有啥作用啊


回复

使用道具 举报

17#
ID:744327 发表于 2021-12-31 08:47 | 只看该作者
代码没有问题,可能仿真软件有问题。
回复

使用道具 举报

18#
ID:869404 发表于 2022-4-3 14:25 | 只看该作者
为什么我的p0口是不确定状态
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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