Saya mengalami masalah ketika menjalankan urutan watchdog penonaktifan pada AVR ATtiny84A sebenarnya mengatur ulang chip meskipun timer harus memiliki banyak waktu tersisa di atasnya. Ini terjadi secara tidak konsisten dan ketika menjalankan kode yang sama pada banyak bagian fisik; beberapa reset setiap kali, kadang-kadang reset beberapa, dan beberapa tidak pernah.
Untuk menunjukkan masalah, saya telah menulis sebuah program sederhana yang ...
- Mengaktifkan watchdog dengan timeout 1 detik
- Mereset pengawas
- Mengedipkan LED putih menyala selama 0,1 detik
- Mematikan LED putih selama 0,1 detik
- Menonaktifkan pengawas
Total waktu antara pengawas mengaktifkan dan menonaktifkan adalah kurang dari 0,3 detik, namun terkadang pengawas reset terjadi ketika urutan penonaktifan dijalankan.
Ini kodenya:
#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.
}
}
Pada saat startup, program memeriksa untuk melihat apakah reset sebelumnya disebabkan oleh timeout anjing pengawas, dan jika demikian itu menyalakan LED merah dan mengosongkan flag pengaturan ulang pengawas untuk menunjukkan bahwa pengaturan ulang pengawas terjadi. Saya percaya bahwa kode ini seharusnya tidak pernah dieksekusi dan LED merah tidak boleh menyala, namun sering terjadi.
Apa yang terjadi disini?