2013-07-18 25 views
0

我正在使用中斷來重置ATTiny20。下面是相關代碼:ATTiny20在看門狗復位後陷入復位循環

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 
    ... 
} 

中斷處理函數:

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

這工作得很好 - 當按鈕被按下,系統凍結2秒鐘,然後復位......並及時陷入重置循環。一些谷歌搜索發現了罪魁禍首:在更新的芯片上,在看門狗復位後,看門狗定時器保持啓用狀態(以其最短延遲設置)。以下代碼旨在解決此問題:

// 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。由於ATTiny20上不存在MCUSR,因此將MCUSR = 0註釋掉。我試圖用SREG = 0代替它,但無濟於事。

即使有這個代碼,應該禁用看門狗定時器,問題仍然存在。設備上的指示燈閃爍表示程序在重置之前正在運行main()功能的一部分,但將wdt_disable();置於main()的頂部也沒有幫助。

有什麼關鍵的,我很想念: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; 
}