2011-04-29 35 views
0

我想读取LEDS旁边的开关,并将LEDS从0循环到任何一个开关按下 如果没有任何按下按下循环通过所有延迟。为此,我用了timer0。由于我在 atmega8515上工作。我用INT0。 这是我实现:循环LEDS IN ATMEGA8515

#include <avr/io.h> 
#include <avr/interrupt.h> 
#include <util/delay.h> 

#define BIT(n) (1 << n) 

volatile uint8_t led, k, switches, i , j = 1; 
      /* uint8_t is the same as unsigned char */ 
int main(void) 
{ 



    DDRB = 0xff;    /* use all pins on PortB for output */ 

    led = 1;     /* init variable representing the LED state */ 
    PORTB = 0XFF; 

    cli(); 

    TCCR0|=(1<<CS02) |(1<<CS00); 

//Enable Overflow Interrupt Enable 
    TIMSK|=(1<<TOIE0); 

//Initialize Counter 
    TCNT0=0; 


    GICR = BIT(INT0); 
    MCUCR = BIT(ISC01) | BIT(ISC00); 

    sei(); 

    for (; ;); 



} 


ISR(TIMER0_OVF_vect) 
{ 

    if(switches == 0xff) 
    { 
    PORTB = ~led;   /* invert the output since a zero means: LED on */ 
     led <<= 1;    /* move to next LED */ 
     if (!led)    /* overflow: start with Pin B0 again */ 
     { 
      led = 1; 
     } 
    }  
    else 
    { 
    for (k = 0; k< 8;k++) 
    { 
     j = switches & (1 << k); 

     if(j == 0) 
     { 
      for(i=1;i<=(k +1);i++) 
      { 
       j = 1; 
       PORTB = ~j; 
       j = 1 << i; 

       _delay_ms(100);  //without this delay it doesnt cycle the LEDS from to whichever switch is pressed 
      } 

    } 
} 
} 

但在ISR使用延迟循环是一个不好的编程习惯。如何使用相同的计时器而不是延迟?

+0

如果您有一个计时器用于触发ISR,您为什么需要使用延迟功能?为什么每次ISR发生火灾时都不能更新LED状态? – 2011-04-29 22:21:19

+0

如果你看到我的ISR,它有if和else循环 – dora 2011-04-29 23:12:43

+0

我明白了。但为什么?正如我所说的,只需在每次ISR调用中更新LED端口状态*一次*。如果ISR定期发射,你将获得动画效果。 – 2011-04-29 23:14:14

回答

1

我认为在ISR中,您应该更新LED状态,并在主循环中设置PORTB并读取开关值。在你的代码中,它似乎在ISR中占用了太多时间。