2011-04-29 3 views
0

LED 옆에있는 스위치를 읽고 LED가 0에서 어느 스위치로든 번갈아 가며 을 누르기를 원합니다. 아무 것도 누르지 않으면 아무 것도 지연되지 않습니다. 이렇게 타이머 0을 사용했습니다. 내가 근무하기 때문에 atmega8515. 나는 INT0를 사용했다.에 LED를 넣으십시오. 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 상태를 업데이트 할 수없는 이유는 무엇입니까? –

+0

내 ISR이 표시되면 if 및 else 루프가 – dora

+0

으로 표시됩니다. 하지만 왜? 내가 말했듯이, 각 ISR 콜에서 LED 포트 상태 *를 한 번 업데이트하면됩니다. 일정한 간격으로 ISR이 발생하면 애니메이션 효과를 얻게됩니다. –

답변

1

ISR에서는 LED 상태를 업데이트해야하고 메인 루프에서는 PORTB를 설정하고 스위치 값을 읽을 수 있다고 생각합니다. 귀하의 코드에서는 ISR에서 많은 시간을 차지하고있는 것 같습니다.

관련 문제