2011-04-29 70 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中佔用了太多時間。