Kesinlikle yapabilirsiniz. Veri sayfasına göre, gözlemci zamanlayıcısı, MCU'yu sıfırlamak veya tetiklendiğinde kesintiye neden olmak için ayarlanabilir. Kesinti olasılığıyla daha fazla ilgileniyorsunuz gibi görünüyor.
WDT'nin kurulumu normal bir Zamanlayıcıdan daha kolaydır, aynı nedenden dolayı daha az kullanışlıdır: daha az seçenek. Dahili olarak kalibre edilmiş 128kHz saatte çalışır, yani zamanlaması MCU'nun ana saat hızından etkilenmez. Ayrıca bir uyanma kaynağı sağlamak için en derin uyku modlarında çalışmaya devam edebilir.
Birkaç veri sayfası örnekleri yanı sıra (C) kullandığım bazı kod üzerinden gidecek.
Dahil Edilen Dosyalar ve Tanımlar
Başlamak için, muhtemelen işlerin çalışması için aşağıdaki iki başlık dosyasını dahil etmek isteyeceksiniz:
#include <avr/wdt.h> // Supplied Watch Dog Timer Macros
#include <avr/sleep.h> // Supplied AVR Sleep Macros
Ayrıca, aşağıdaki gibi standart AVR başlıklarından birinde tanımlanan Makro <_BV (BIT)> kullanıyorum (size daha tanıdık gelebilir):
#define _BV(BIT) (1<<BIT)
Kod Başlangıcı
MCU ilk kez başlatıldığında, tipik olarak G / Ç, ayar zamanlayıcıları vb. kararsız bir döngü.
if(MCUSR & _BV(WDRF)){ // If a reset was caused by the Watchdog Timer...
MCUSR &= ~_BV(WDRF); // Clear the WDT reset flag
WDTCSR |= (_BV(WDCE) | _BV(WDE)); // Enable the WD Change Bit
WDTCSR = 0x00; // Disable the WDT
}
WDT Kurulumu
Ardından, çipin geri kalanını ayarladıktan sonra WDT'yi tekrar yapın. WDT'yi kurmak için "zamanlanmış bir dizi" gerekir, ancak bunu yapmak gerçekten çok kolaydır ...
// Set up Watch Dog Timer for Inactivity
WDTCSR |= (_BV(WDCE) | _BV(WDE)); // Enable the WD Change Bit
WDTCSR = _BV(WDIE) | // Enable WDT Interrupt
_BV(WDP2) | _BV(WDP1); // Set Timeout to ~1 seconds
Elbette, bu kod sırasında kesintileriniz devre dışı bırakılmalıdır. Daha sonra bunları yeniden etkinleştirdiğinizden emin olun!
cli(); // Disable the Interrupts
sei(); // Enable the Interrupts
WDT Kesinti Hizmeti Rutini
Endişelenmeniz gereken bir sonraki şey WDT ISR'yi kullanmaktır. Bu şu şekilde yapılır:
ISR(WDT_vect)
{
sleep_disable(); // Disable Sleep on Wakeup
// Your code goes here...
// Whatever needs to happen every 1 second
sleep_enable(); // Enable Sleep Mode
}
MCU Uyku
MCU'yu WDT ISR'nin içine uyku moduna geçirmek yerine, ISR'nin sonunda uyku modunu etkinleştirmenizi ve ardından ANA programın MCU'yu uyku moduna geçirmesini öneririm. Bu şekilde, program aslında uyumadan önce ISR'yi terk eder ve uyanır ve doğrudan WDT ISR'ye geri döner.
// Enable Sleep Mode for Power Down
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set Sleep Mode: Power Down
sleep_enable(); // Enable Sleep Mode
sei(); // Enable Interrupts
/****************************
* Enter Main Program Loop *
****************************/
for(;;)
{
if (MCUCR & _BV(SE)){ // If Sleep is Enabled...
cli(); // Disable Interrupts
sleep_bod_disable(); // Disable BOD
sei(); // Enable Interrupts
sleep_cpu(); // Go to Sleep
/****************************
* Sleep Until WDT Times Out
* -> Go to WDT ISR
****************************/
}
}