程序出了点问题,求解决

2019-03-24 20:12发布

课设一个星期了,程序和原理图遇到了很多问题,剩这三个还没有解决,麻烦各位大神给点意见,救救孩子!
求解决这三个问题:倒计时不运紧急模式没有反应修改时间也没有反应
  1. #include <iom168v.h>
  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<<EEWE));//等待上一次写操作结束
  69.     EEAR = uiAddress;//设置地址和数据寄存器
  70.     EEDR = ucData;
  71.     EECR |= (1<<EEMWE); //置位EEMWE
  72.     EECR |= (1<<EEWE);//置位EEWE 以启动写操作E
  73. }
  74. void EEPROM_READ(unsigned int uiAddress)
  75. {
  76.     while(EECR & (1<<EEWE)); //等待上一次写操作结束
  77.     EEAR = uiAddress;//设置地址寄存器
  78.     EECR |= (1<<EERE); //设置EERE 以启动读操作
  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. }


复制代码

此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
y909334873
1楼-- · 2019-03-25 07:40
这种问题就一步步找一个问题,一个功能一个功能注释,倒计时不正常找定时器工作正不正常,显示功能部分正不正常等等,模式切换不了是按键判断问题,还是逻辑上面有冲突,一点点的抠大多数情况下都能定位到大概的的问题位置在想解决办法
Li_Lei
2楼-- · 2019-03-25 08:07
不太好帮,看程序就得看大半天
零三苏九岳志
3楼-- · 2019-03-25 09:56
帮忙你顶一顶

一周热门 更多>