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。
wdt_init絕對會被調用嗎?你有什麼調試功能?當看門狗即將重置芯片時,也許有一箇中斷被觸發......也許在那裏你可以禁用它? – gcb
@gcb遺憾的是ATTiny20沒有調試功能。我確實找到了答案,並在下面添加了它。只需在睡眠中喝上一杯咖啡即可注意到數據表中的這一行:* WDE在RSTFLR中被WDRF覆蓋。這意味着當WDRF被設置時WDE總是被設置。要清除WDE,必須先清除WDRF 。此功能可確保在導致故障的情況下進行多次重置,並在 故障後安全啓動。* –