แน่นอนที่สุดคุณสามารถ ตามแผ่นข้อมูลตัวจับเวลาจ้องจับผิดสามารถตั้งค่าเพื่อรีเซ็ต MCU หรือทำให้เกิดการขัดจังหวะเมื่อมันทริกเกอร์ ดูเหมือนว่าคุณมีความสนใจในความเป็นไปได้ที่จะขัดจังหวะ
จริง ๆ แล้ว WDT นั้นติดตั้งง่ายกว่าตัวตั้งเวลาปกติด้วยเหตุผลเดียวกันกับที่มีประโยชน์น้อยกว่า: ตัวเลือกที่น้อยลง มันทำงานบนนาฬิกา 128kHz สอบเทียบภายในซึ่งหมายความว่าเวลาจะไม่ได้รับผลกระทบจากความเร็วสัญญาณนาฬิกาหลักของ MCU นอกจากนี้ยังสามารถทำงานต่อได้ในโหมดสลีปที่ลึกที่สุดเพื่อให้แหล่งสัญญาณปลุก
ฉันจะดูตัวอย่างแผ่นข้อมูลสองสามรายการรวมถึงรหัสบางส่วนที่ฉันใช้ (ใน C)
ไฟล์และคำจำกัดความที่รวมอยู่
ในการเริ่มต้นคุณอาจต้องการรวมไฟล์ส่วนหัวสองไฟล์ต่อไปนี้เพื่อให้สามารถใช้งานได้:
#include <avr/wdt.h> // Supplied Watch Dog Timer Macros
#include <avr/sleep.h> // Supplied AVR Sleep Macros
นอกจากนี้ฉันใช้ Macro <_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 Interrupt Service Routine
สิ่งต่อไปที่คุณต้องกังวลคือการจัดการ 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 สลีป
แทนที่จะให้ MCU เข้าสู่โหมดสลีปภายใน WDT ISR ฉันขอแนะนำให้เปิดใช้งานโหมดสลีปที่ส่วนท้ายของ ISR จากนั้นให้โปรแกรม MAIN ทำให้ MCU เข้าสู่โหมดสลีป ด้วยวิธีนี้โปรแกรมจะออกจาก ISR ก่อนที่จะเข้าสู่โหมดสลีปและมันจะตื่นขึ้นมาและกลับไปที่ 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
****************************/
}
}