2013-07-18 1 views
0

현재 ATTiny20을 재설정하기 위해 인터럽트를 사용 중입니다. 즉시 다음 버튼은 시스템이 2 초 정지 할 때 전달됩니다 및 재설정 ... 그리고 -워치 독 재설정 후 재설정 루프에 ATTiny20 장애 발생

ISR(PCINT0_vect) 
{ 
    if (!(BUTTON_1_PORT & 1<<BUTTON_1_PIN)) // Only reset if button is pushed 
    { 
     wdt_enable(WDTO_2S); 
     while(1){}; 
    } 
} 

이 아주 잘 작동합니다

int main(void) 
{ 
    ... 

    // Set up interrupt for reset button (PCINT5) 
    SREG |= 1<<7;   // Enable global interrupts 
    GIMSK |= 1<<PCIE0;  // Enable Pin Change Interrupt 0 (enables interrupts on PCINT[7:0] 
    PCMSK0 |= 1<<PCINT5; // Enable PCINT5 (physical pin 8) interrupt 
    ... 
} 

인터럽트 처리 기능 다음은 관련 코드입니다 리셋 루프에 갇히게됩니다. 약간의 인터넷 검색이 범인을 밝혀 냈습니다. 최신 칩에서는 워치 독 타이머를 활성화 한 상태에서 (최단 지연 설정에서) 워치 독 리셋 후 사용 가능 상태로 유지됩니다. 다음 코드는이 문제를 해결하기위한 것입니다 :

// Disable watchdog on reset 
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3"))); 
void wdt_init(void) 
{ 
    // MCUSR = 0; // See below for reason for commenting this line 
    wdt_disable(); 
    return; 
} 

* N.B. MCUSR = 0은 MCUSR이 ATTiny20에 없기 때문에 주석 처리되었습니다. 나는 SREG = 0로 바꾸려고했지만 아무 소용이 없습니다.

워치 독 타이머를 비활성화해야하는이 코드를 사용해도 문제는 계속 발생합니다. 장치의 깜박이는 LED는 프로그램이 재설정되기 전에 main() 기능을 통해 실행 중임을 나타냅니다. 그러나 main()의 상단에 wdt_disable();을 넣어도 도움이되지 않았습니다.

내가 빠뜨린 중요한 부분이 있습니까? ATTiny20? 데이터 시트에 내가 놓친 것이 있습니까? 문제와 해결책은 너무도 명백해 보이지만, 나는 혼란 스럽다. Atmel Studio 6.1을 사용하고 있습니다.

+0

wdt_init이 절대적으로 호출되고 있습니까? 어떤 디버깅 기능이 있습니까? 아마도 감시견이 칩을 재설정하려고 할 때 해고되는 인터럽트가있을 것입니다 ... 아마도 거기에서 비활성화 할 수 있습니까? – gcb

+0

@gcb ATTiny20에는 불행히도 디버깅 기능이 없습니다. 나는 대답을 찾았고 그것을 아래에 추가했다. 데이터 시트에서이 라인을 알아보기 위해 밤잠을 자고 아침 커피를 마셨다 : * WDE는 RSTFLR의 WDRF에 의해 무시된다. 이것은 WDRF가 설정된 경우 WDE가 항상 설정됨을 의미합니다. WDE를 지우려면 먼저 WDRF 을 지워야합니다. 이 기능은 장애를 일으키는 조건에서 여러 번 리셋하고 오류가 발생한 후 안전한 시작을 보장합니다. * –

답변

1
// Disable watchdog on reset 
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3"))); 
void wdt_init(void) 
{ 
    // This is the flag that must be cleared on an ATTiny20 before the WDT can be disabled 
    /***************/ 
    /* RSTFLR = 0; */ 
    /***************? 

    wdt_disable(); 
    return; 
}