आप सबसे निश्चित रूप से कर सकते हैं। डेटाशीट के अनुसार, वॉचडॉग टाइमर को MCU को रीसेट करने के लिए सेटअप किया जा सकता है या ट्रिगर होने पर एक बाधा पैदा कर सकता है। ऐसा लगता है कि आप रुकावट की संभावना में अधिक रुचि रखते हैं।
WDT वास्तव में एक सामान्य टाइमर की तुलना में सेटअप करना आसान है उसी कारण से यह कम उपयोगी है: कम विकल्प। यह आंतरिक रूप से कैलिब्रेटेड 128kHz घड़ी पर चलता है, जिसका अर्थ है कि MCU की मुख्य घड़ी की गति से इसका समय प्रभावित नहीं होता है। यह जागृत स्रोत प्रदान करने के लिए गहरी नींद मोड के दौरान भी जारी रह सकता है।
मैं डेटशीट के उदाहरणों के एक जोड़े के साथ-साथ कुछ कोड भी इस्तेमाल करूंगा जो मैंने (सी में) उपयोग किए हैं।
शामिल फ़ाइलें और परिभाषाएँ
शुरू करने के लिए, आप संभवतः काम करने के लिए निम्नलिखित दो हेडर फ़ाइलों को शामिल करना चाहेंगे:
#include <avr/wdt.h> // Supplied Watch Dog Timer Macros
#include <avr/sleep.h> // Supplied AVR Sleep Macros
इसके अलावा, मैं मैक्रो <_BV (BIT)> का उपयोग करता हूं, जिसे मानक AVR हेडर में से एक के रूप में परिभाषित किया गया है (जो आपके लिए अधिक पारिवारिक हो सकता है):
#define _BV(BIT) (1<<BIT)
कोड की शुरुआत
जब MCU पहली बार शुरू किया जाता है, तो आप आम तौर पर I / O को इनिशियलाइज़ करेंगे, टाइमर सेट करेंगे, आदि कहीं न कहीं यह सुनिश्चित करने के लिए एक अच्छा समय है कि WDT को रीसेट करने का कारण नहीं बने क्योंकि यह फिर से कर सकता है, आपके प्रोग्राम को ध्यान में रखते हुए। एक अस्थिर लूप।
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 सेटअप
फिर, आपके द्वारा बाकी चिप को सेटअप करने के बाद, WDT को फिर से करें। WDT को सेट करने के लिए "समयबद्ध अनुक्रम" की आवश्यकता होती है, लेकिन यह करना आसान है ...
// 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
बेशक, इस कोड के दौरान आपके इंटरप्ट को अक्षम किया जाना चाहिए। बाद में उन्हें फिर से सक्षम करना सुनिश्चित करें!
cli(); // Disable the Interrupts
sei(); // Enable the Interrupts
WDT इंटरप्ट सर्विस रूटीन
चिंता की अगली बात WDT ISR संभाल रही है। यह इस प्रकार किया जाता है:
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 नींद
WDT ISR के अंदर सोने के लिए MCU लगाने के बजाय, मैं बस ISR के अंत में स्लीप मोड को सक्षम करने की सलाह देता हूं, फिर MAIN प्रोग्राम को MCU को सोने के लिए रखा है। इस तरह, कार्यक्रम वास्तव में आईएसआर छोड़ने से पहले सो रहा है, और यह जाग जाएगा और सीधे डब्ल्यूडीटी आईएसआर में वापस चला जाएगा।
// 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
****************************/
}
}