AVR ATtiny84A'da devre dışı bırakılan bir bekçi uygulaması dizisinin yürütülmesi , zamanlayıcının üzerinde bolca zaman kalmasına rağmen çipi sıfırlıyor. Bu tutarsızca ve aynı kodu birçok fiziksel parçada çalıştırırken olur; bazıları her zaman sıfırlanır, bazıları bazen sıfırlanır, bazıları ise hiçbir zaman sıfırlanmaz.
Sorunu göstermek için, basit bir program yazdım ki ...
- Watchdog'u 1 saniye zaman aşımı ile etkinleştirir
- Bekçi köpeği sıfırlar
- Beyaz LED'i 0,1 saniye boyunca yanıp söner
- Beyaz LED'i 0,1 saniye süreyle yanıp söndü
- Bekçi köpeğini devre dışı bırakır
Bekçi uygulaması etkinleştirme ve devre dışı bırakma arasındaki toplam süre 0,3 saniyeden azdır, ancak bazen devre dışı bırakma sırası yürütüldüğünde bir bekçi uygulaması sıfırlaması gerçekleşir.
İşte kod:
#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.
}
}
Başlangıçta, program önceki sıfırlamanın bir bekçi uygulaması zaman aşımından kaynaklanıp kaynaklanmadığını kontrol eder ve eğer öyleyse kırmızı LED'i yanar ve bir bekçi uygulaması sıfırlamanın gerçekleştiğini belirtmek için bekçi uygulaması sıfırlama bayrağını temizler. Bu kodun asla yürütülmemesi gerektiğine ve kırmızı LED'in hiçbir zaman yanmaması gerektiğine inanıyorum, ancak çoğu zaman böyle oluyor.
Burada neler oluyor?