타이머에 충분한 시간이 남아 있어도 AVR ATtiny84A 에서 디스 에이치 워치 독 시퀀스를 실행하는 것이 실제로 칩을 재설정하는 문제가 있습니다. 이것은 일관되지 않고 많은 물리적 부분에서 동일한 코드를 실행할 때 발생합니다. 일부는 매번 재설정되고 일부는 때때로 재설정되며 일부는 재설정되지 않습니다.
문제를 설명하기 위해 간단한 프로그램을 작성했습니다 ...
- 1 초 타임 아웃으로 워치 독을 활성화합니다
- 워치 독을 재설정합니다
- 0.1 초 동안 흰색 LED를 깜빡입니다.
- 0.1 초 동안 흰색 LED가 깜박임
- 워치 독을 비활성화합니다
워치 독 활성화와 비활성화 사이의 총 시간은 0.3 초 미만이지만 비활성화 시퀀스가 실행될 때 워치 독 재설정이 발생하는 경우가 있습니다.
코드는 다음과 같습니다.
#define F_CPU 1000000 // Name used by delay.h. We are running 1Mhz (default fuses)
#include <avr/io.h>
#include <util/delay.h>
#include <avr/wdt.h>
// White LED connected to pin 8 - PA5
#define WHITE_LED_PORT PORTA
#define WHITE_LED_DDR DDRA
#define WHITE_LED_BIT 5
// Red LED connected to pin 7 - PA6
#define RED_LED_PORT PORTA
#define RED_LED_DDR DDRA
#define RED_LED_BIT 6
int main(void)
{
// Set LED pins to output mode
RED_LED_DDR |= _BV(RED_LED_BIT);
WHITE_LED_DDR |= _BV(WHITE_LED_BIT);
// Are we coming out of a watchdog reset?
// WDRF: Watchdog Reset Flag
// This bit is set if a watchdog reset occurs. The bit is reset by a Power-on Reset, or by writing a
// logic zero to the flag
if (MCUSR & _BV(WDRF) ) {
// We should never get here!
// Light the RED led to show it happened
RED_LED_PORT |= _BV(RED_LED_BIT);
MCUCR = 0; // Clear the flag for next time
}
while(1)
{
// Enable a 1 second watchdog
wdt_enable( WDTO_1S );
wdt_reset(); // Not necessary since the enable macro does it, but just to be 100% sure
// Flash white LED for 0.1 second just so we know it is running
WHITE_LED_PORT |= _BV(WHITE_LED_BIT);
_delay_ms(100);
WHITE_LED_PORT &= ~_BV(WHITE_LED_BIT);
_delay_ms(100);
// Ok, when we get here, it has only been about 0.2 seconds since we reset the watchdog.
wdt_disable(); // Turn off the watchdog with plenty of time to spare.
}
}
프로그램은 시작시 워치 독 시간 초과로 인해 이전 재설정이 발생했는지 확인하고,이 경우 빨간색 LED가 켜지고 워치 독 재설정 플래그가 지워져 워치 독 재설정이 발생했음을 나타냅니다. 나는이 코드를 실행해서는 안되며 빨간색 LED가 켜지지 않아야한다고 생각하지만 종종 발생합니다.
무슨 일이야?