单片机/MCU论坛
直播中

谢紫欣

5年用户 5经验值
私信 关注
[问答]

请问怎样能让倒计时成功运作,紧急模式有反应,修改时间有反应呢?

  1. #include
  2. const unsigned char disp[] ={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //段选码
  3. unsigned char xs[4]= {0xC0,0xC0,0xC0,0xC0};                                                                        

  4. unsigned char gs=0; //绿灯
  5. unsigned char ys=0; //黄灯
  6. unsigned char green_second = 9 , yellow_second = 3 ; //用于修改时间的变量

  7. unsigned char k=0; //显示刷新标志

  8. unsigned char flag=0; //转换红绿灯标志位
  9. unsigned char flag1=0; //切换交通灯模式标志位
  10. unsigned char flag2=0; //紧急模式下的切换模式
  11. unsigned char flag3=0; //修改时间

  12. unsigned int Udelay = 1000;
  13. //主频为1M
  14. void delay_1us(void)      //1us延时,实测8us
  15. {
  16. asm("nop");                  //1时钟周期
  17. }

  18. void delay_3us(void)     //3us,实8us
  19. {  
  20. asm("nop");
  21. }

  22. void delay_10us(void)  //10us,实9us
  23. {
  24.    asm("nop");
  25.    asm("nop");
  26. }

  27. void delay_50us(void)    //50us,实47us
  28. {
  29. delay_10us();
  30. delay_10us();
  31. delay_10us();
  32. delay_10us();
  33. delay_10us();
  34. }

  35. void delay_100us(void)   //100us,实96us
  36. {
  37.   delay_50us();
  38.   delay_50us();
  39. }


  40. void delay_n100us(unsigned char n100us)   //几百us延时
  41. {
  42.   while(n100us--);
  43.   delay_100us();
  44. }
  45. //延时函数
  46. void delay(unsigned int x)
  47. {
  48.    while(x--);
  49. }

  50. //IO配置函数
  51. void io_init(void)
  52. {
  53.    DDRD = 0xFF;
  54.    PORTD = 0xFF;
  55.    
  56.    DDRB = 0b00111111;
  57.    PORTB = 0xFF;
  58.    
  59.    
  60.    DDRC = 0b00111100;
  61.    PORTC = 0b00111111;
  62.    PORTC|=0b00111100;//4位位控总不变
  63.    
  64. }

  65. //EEPROM写入、读取
  66. void EEPROM_WRITE(unsigned int uiAddress, unsigned char ucData)
  67. {
  68.     while(EECR & (1<
  69.     EEAR = uiAddress;//设置地址和数据寄存器
  70.     EEDR = ucData;
  71.     EECR |= (1<
  72.     EECR |= (1<
  73. }
  74. void EEPROM_READ(unsigned int uiAddress)
  75. {
  76.     while(EECR & (1<
  77.     EEAR = uiAddress;//设置地址寄存器
  78.     EECR |= (1<
  79.     return /*EEDR*/; //自数据寄存器返回数据
  80. }

  81. //译码函数
  82. void decode(unsigned char a/*, unsigned char b*/)
  83. {  
  84.    /*switch(b)
  85.    {
  86.       case 0 :*/
  87.           xs[0] = disp[a / 10];
  88.           xs[1] = disp[a % 10];
  89.          /*break;
  90.           case 1 :*/
  91.           xs[2] = disp[a / 10];
  92.           xs[3] = disp[a % 10];
  93.          /*break;
  94.    }*/
  95. }

  96. void shutdownLED(void)
  97. {
  98.    xs[0] = 0xff;xs[1] = 0xff;xs[2] = 0xff;xs[3] = 0xff; //关闭显示清空段选段选
  99.    TCCR0B = 0x00;
  100.    TCCR1B = 0x00;
  101.    PORTC|=0b00111100; //关位选
  102. }



  103. //修改时间
  104. /*void changetime(void)
  105. {
  106.    
  107.    //只能在普通模式下改变时间
  108.    if( ((PINB & 0x80) == 0) && ((flag1 == 0)||(flag1 == 3)) )
  109.    {
  110.       PORTB |= 0x3f; //关闭显示灯
  111.           flag3 = (flag3 + 1) % 3;
  112.           if(flag3 == 0)
  113.           {
  114.              flag1 = 0;
  115.                  xs[2] = 0xff;
  116.                  xs[3] = 0xff;
  117.           }
  118.           delay(50000);
  119.    }
  120.    //修改时间
  121.    if(flag3 == 1)
  122.    {
  123.           flag1 = 3;
  124.           //绿灯闪
  125.           PORTB &= ~0x24;
  126.           if((PINC & 0x01) == 0) //+1
  127.           {
  128.              delay_n100us(100);
  129.                  if((PINC & 0x01) == 0)
  130.                  {
  131.                  green_second++;
  132.                      EEPROM_WRITE(0x00, green_second);
  133.                      delay(40000);
  134.                   }
  135.           }
  136.           if((PINC & 0x02) == 0) //-1
  137.           {
  138.              delay_n100us(100);
  139.                  if((PINC & 0x02) == 0)
  140.                  {
  141.                  if(green_second > 0)
  142.                      {
  143.                             green_second--;
  144.                             EEPROM_WRITE(0x00, green_second);
  145.                         delay(40000);
  146.                      }
  147.                   }
  148.           }            
  149.                  
  150.           //数码管2显示绿灯时间
  151.       decode(green_second/*, 1*//*);
  152.    }
  153.    if(flag3 == 2)//2黄灯
  154.    {
  155.       //黄灯闪
  156.           PORTB &= ~0x12;
  157.                  
  158.           if((PINC & 0x01) == 0) //+1
  159.           {
  160.              delay_n100us(100);
  161.                  if((PINC & 0x01) == 0)
  162.                   {
  163.                  yellow_second++;
  164.                      EEPROM_WRITE(0x02, yellow_second);
  165.                      UDR0 = 0x02;
  166.                      delay(10000);
  167.                      UDR0 = yellow_second;
  168.                      delay(40000);
  169.                 }
  170.                 }
  171.           if((PINC & 0x02) == 0) //-1
  172.           {  
  173.              delay_n100us(100);
  174.                  if((PINC & 0x02) == 0)
  175.                    {
  176.                      if(yellow_second > 0)
  177.                      {
  178.                     yellow_second--;
  179.                             EEPROM_WRITE(0x02, yellow_second);
  180.                             UDR0 = 0x02;
  181.                         delay(10000);
  182.                         UDR0 = yellow_second;
  183.                         delay(40000);        
  184.                  }
  185.                         }
  186.           }
  187.           //数码管2显示黄灯时间
  188.           decode(yellow_second/*, 1*//*);
  189.    }
  190. }*/

  191. //红绿灯显示函数
  192. void led(void)
  193. {
  194.    switch(flag1)
  195.    {
  196.       case 0:
  197.           {//日间模式
  198.               TCCR0B = 0x03;
  199.               TCCR1B = 0x0b;
  200.               switch(flag)
  201.               {
  202.                  case 0:         
  203.                         xs[2]= 0xbf;
  204.                             xs[3]= 0xbf;
  205.                             decode(gs/*, 0*/);
  206.                             PORTB |= 0x08; //关闭左右红灯
  207.                     PORTB |= 0x02; //关闭上下黄灯
  208.                 PORTB &= ~0x20; //开启左右绿灯
  209.                             PORTB &= ~0x01; //开启上下红灯
  210.                     
  211.                 break;
  212.              case 1:
  213.                         decode(ys/*, 0*/);
  214.                 PORTB &= ~0x01; //开启上下红灯
  215.                             PORTB |= 0x20; //关闭左右绿灯
  216.                     PORTB &= ~0x10; //开启左右黄灯
  217.                             if(ys <= 3)
  218.                             {
  219.                                decode(ys/*, 1*/);
  220.                             }
  221.                 break;
  222.              case 2:
  223.                         xs[0]= 0xbf;
  224.                             xs[1]= 0xbf;
  225.                             decode(gs/*, 1*/);
  226.                 PORTB |= 0x10; //关闭左右黄灯
  227.                             PORTB |= 0x01; //关闭上下红灯
  228.                     PORTB &= ~0x04; //开启上下绿灯
  229.                             PORTB &= ~0x08; //开启左右红灯
  230.                     
  231.                 break;
  232.              case 3:
  233.                         decode(ys/*, 1*/);
  234.                             PORTB &= ~0x08; //开启左右红灯
  235.                 PORTB |= 0x04; //关闭上下绿灯
  236.                     PORTB &= ~0x02; //开启上下黄灯
  237.                             if(ys <= 3)
  238.                             {
  239.                                decode(ys/*, 0*/);
  240.                             }
  241.                            
  242.                 break;
  243.               }
  244.           break;}
  245.           case 1: //紧急模式
  246.           {
  247.              PORTB |= 0x3f;
  248.                  shutdownLED();
  249.              switch(flag2)
  250.              {  
  251.                 case 0://紧急模式1
  252.                 {
  253.                    PORTB &= ~0x08;//开启左右红灯
  254.                    PORTB &= ~0x01; //开启上下红灯
  255.                    break;
  256.                 }
  257.                 case 1://紧急模式2
  258.                 {
  259.                    PORTB &= ~0x20; //开启左右绿灯
  260.                    PORTB &= ~0x01; //开启上下红灯
  261.                    break;
  262.                 }
  263.                 case 2://紧急模式3
  264.                 {
  265.                            PORTB &= ~0x04;//开启上下绿灯
  266.                            PORTB &= ~0x08;//开启左右红灯
  267.                    break;
  268.                 }
  269.                         //break;//自己加的
  270.              }
  271.              break;
  272.           }
  273.          
  274.           case 2: //夜间模式
  275.           {
  276.              PORTB |= 0x3f;
  277.                  shutdownLED();
  278.                  flag2 = 0;
  279.              PORTB &= ~0x02;//开启上下黄灯
  280.              PORTB &= ~0x10;//开启左右黄灯
  281.              delay(50000);
  282.              PORTB |= 0x02;//关闭上下黄灯
  283.              PORTB |= 0x10;//关闭左右黄灯
  284.              delay(50000);
  285.              break;
  286.       }
  287.           case 3:
  288.           {
  289.                  TCCR1B = 0x00; //关闭计时
  290.                  xs[0] = 0xbf;
  291.                  xs[1] = 0xbf;
  292.                  break;
  293.           }
  294.    }
  295. }


  296. //主函数
  297. void main(void)
  298. {
  299.    gs = green_second;
  300.    ys = yellow_second;
  301.    
  302.    io_init(); //IO口初始化
  303.    
  304.    //定时器初始化
  305.    timer0_init();
  306.    timer1_init();
  307.    
  308.    SREG|=0x80; //开启总中断
  309.    
  310.    //数据写入EEPROM
  311.    EEPROM_READ(0x00/*,green_second*/);delay(10);
  312.    EEPROM_READ(0x02/*,yellow_second*/);delay(10);
  313.    
  314.    if(green_second>50) EEPROM_WRITE(0x00, gs);
  315.    if(yellow_second>50) EEPROM_WRITE(0x02, ys);
  316.    
  317.    
  318.    EEPROM_READ(0x00/*green_second*/);delay(10);
  319.    EEPROM_READ(0x02/* yellow_second*/);delay(10);
  320.    
  321.    gs = green_second;
  322.    ys = yellow_second;
  323.    
  324.    delay(10000);
  325.    while(1)
  326.    {
  327.           //修改模式
  328.       if( ((PINB & 0x40) == 0) && (flag3 == 0))
  329.           {
  330.                    PORTB |= 0x3f;
  331.                  flag1 = (flag1 + 1) % 3;
  332.                  delay(20000);
  333.           }
  334.           //紧急模式下切换
  335.           if( ((PINB & 0x80) == 0) && (flag1 == 1))
  336.           {
  337.              PORTB |= 0x3f;
  338.              flag2 = 0;
  339.                  delay(20000);
  340.           }
  341.           //东西方向
  342.           if( ((PINC & 0x01) == 0) && (flag1 == 1))
  343.           {
  344.              PORTB |= 0x3f;
  345.              flag2 = 1;
  346.                  delay(20000);
  347.           }
  348.           //南北方向
  349.           if( ((PINC & 0x02) == 0) && (flag1 == 1))
  350.           {
  351.              PORTB |= 0x3f;
  352.              flag2 = 2;
  353.                  delay(20000);
  354.           }
  355.           //led显示函数
  356.           led();
  357.           //修改时间函数
  358.           //changetime();
  359.    }
  360. }

  361. // 定时器0的初始化
  362. void timer0_init(void)
  363. {
  364.    TCCR0A = 0x02;  //CTC模式
  365.    TCCR0B = 0x03;  //64分频
  366.    OCR0A = 78;     //5ms 78.125

  367.    TIMSK0 = 0x02;/*比较中断A允许*/
  368.    TIFR0 = 0x02;
  369. }

  370. //定时器1的初始化
  371. void timer1_init(void)
  372. {
  373.    TCCR1A = 0x00; //CTC模式
  374.    TCCR1B = 0x0b; //64分频
  375.    OCR1A = 15625; //1s = 15625
  376.    
  377.    TIMSK1 = 0x02; /*比较中断A允许*/
  378.    TIFR1 = 0x02;
  379. }

  380. extern unsigned char k;
  381. extern unsigned char xs[4];
  382. extern unsigned char green_second, yellow_second;
  383. extern unsigned char gs;
  384. extern unsigned char ys;
  385. extern unsigned char flag;
  386. extern unsigned char flag1; //切换交通灯模式标志位
  387. extern unsigned char flag2; //紧急模式下的切换模式
  388. extern unsigned char flag3; //修改时间

  389. #pragma interrupt_handler Int_TCCR1A:12
  390. void Int_TCCR1A(void)
  391. {
  392.    
  393.    switch(flag)
  394.    {
  395.       case 0 :
  396.              gs--;
  397.                  //decode(gs);//zi+  
  398.                  ys = yellow_second;
  399.                  if(gs == 0)
  400.                  {
  401.                    flag = 1;
  402.                   }
  403.                  break;
  404.           case 1 :
  405.              ys--;
  406.                  //decode(ys);//+
  407.                  gs = green_second;
  408.                  if(ys == 0)
  409.                  {
  410.                    flag = 2;
  411.                   }
  412.                  break;
  413.           case 2 :
  414.              gs--;
  415.                  //decode(gs); //+
  416.              ys = yellow_second;
  417.                  if(gs == 0)
  418.                  {
  419.                    flag = 3;
  420.                   }
  421.                  break;
  422.           case 3 :
  423.              ys--;
  424.                  //decode(ys);//+  
  425.                  gs = green_second;
  426.                  if(ys == 0)
  427.                  {
  428.                    flag = 0;
  429.                    }
  430.                  break;
  431.    }
  432. }
  433. // 中断服务程序的功能:刷新段码与位控制,用变量 K 实现轮流刷新的目的
  434. #pragma interrupt_handler Int_TCCR0A:15
  435. void Int_TCCR0A(void)
  436. {
  437.    k=(++k)%4;
  438.    PORTC|=0b00111100;//关位选   
  439.    PORTD=xs[4];
  440.    switch(k)
  441.    {
  442.       case 0:
  443.           PORTC &= ~0x04;
  444.       //PORTD &= ~0x04;//显示千位
  445.       break;
  446.       case 1:
  447.           PORTC &= ~0x08;
  448.       //PORTD &= ~0x08;//显示百位
  449.       break;
  450.       case 2:
  451.           PORTC &= ~0x10;
  452.       //PORTD &= ~0x80;//显示十位
  453.       break;
  454.       case 3:
  455.           PORTC &= ~0x20;
  456.       //PORTC &= ~0x08;//显示个位
  457.       break;
  458.       default: ;
  459.    }
  460. }


倒计时不能成功运作(一直显示88 88),紧急模式没有反应,修改时间也没有反应
求解决

    罪恶交通灯.rar (2019-3-16 23:43 上传)

    351.13 KB, 下载次数: 12

    程序及原理图

    说明.docx (2019-3-16 23:43 上传)

    14.19 KB, 下载次数: 12

    使用说明

已退回5积分

更多回帖

发帖
×
20
完善资料,
赚取积分