Anda pasti bisa. Menurut datasheet, pengawas waktu dapat diatur untuk mengatur ulang MCU atau menyebabkan interupsi ketika dipicu. Tampaknya Anda lebih tertarik pada kemungkinan interupsi.
WDT sebenarnya lebih mudah diatur daripada Timer biasa karena alasan yang sama kurang bermanfaat: lebih sedikit opsi. Ini berjalan pada clock 128kHz yang dikalibrasi secara internal, yang artinya waktunya tidak dipengaruhi oleh kecepatan clock utama MCU. Itu juga dapat terus berjalan selama mode tidur terdalam untuk menyediakan sumber bangun.
Saya akan membahas beberapa contoh lembar data serta beberapa kode yang saya gunakan (dalam C).
Termasuk File dan Definisi
Untuk memulai, Anda mungkin ingin menyertakan dua file header berikut ini agar semuanya berfungsi:
#include <avr/wdt.h> // Supplied Watch Dog Timer Macros
#include <avr/sleep.h> // Supplied AVR Sleep Macros
Juga, saya menggunakan Makro <_BV (BIT)> yang didefinisikan dalam salah satu header AVR standar sebagai berikut (yang mungkin lebih familier bagi Anda):
#define _BV(BIT) (1<<BIT)
Awal Kode
Ketika MCU pertama kali dimulai, Anda biasanya akan menginisialisasi I / O, mengatur timer, dll. Di suatu tempat di sini adalah waktu yang tepat untuk memastikan WDT tidak menyebabkan reset karena bisa melakukannya lagi, menjaga program Anda tetap di loop tidak stabil.
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
}
Pengaturan WDT
Kemudian, setelah Anda mengatur sisa chip, ulangi WDT. Menyiapkan WDT membutuhkan "urutan waktu", tetapi sangat mudah dilakukan ...
// 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
Tentu saja, interupsi Anda harus dinonaktifkan selama kode ini. Pastikan untuk mengaktifkannya kembali setelahnya!
cli(); // Disable the Interrupts
sei(); // Enable the Interrupts
WDT Interrupt Service Routine
Hal berikutnya yang perlu dikhawatirkan adalah menangani WDT ISR. Ini dilakukan sebagai berikut:
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
}
Tidur MCU
Daripada menempatkan MCU untuk tidur di dalam WDT ISR, saya sarankan hanya mengaktifkan mode tidur di akhir ISR, kemudian minta program MAIN membuat MCU tertidur. Dengan begitu, program ini benar-benar meninggalkan ISR sebelum tidur, dan akan bangun dan langsung kembali ke WDT ISR.
// 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
****************************/
}
}