당신은 가장 확실하게 할 수 있습니다. 데이터 시트에 따르면 워치 독 타이머는 MCU를 재설정하거나 트리거 될 때 인터럽트를 발생 시키도록 설정 될 수 있습니다. 인터럽트 가능성에 더 관심이있는 것 같습니다.
WDT는 실제로 일반 타이머보다 설정이 더 쉬운 이유는 덜 유용합니다. 적은 옵션입니다. 내부적으로 보정 된 128kHz 클록에서 실행되므로 타이밍은 MCU의 주요 클록 속도에 영향을받지 않습니다. 웨이크 업 소스를 제공하기 위해 가장 깊은 수면 모드 동안 계속 실행할 수도 있습니다.
몇 가지 데이터 시트 예제와 C에서 사용한 일부 코드를 살펴 보겠습니다.
포함 된 파일 및 정의
시작하려면 아마도 다음 두 가지 헤더 파일을 포함시켜 작업 할 수 있습니다.
#include <avr/wdt.h> // Supplied Watch Dog Timer Macros
#include <avr/sleep.h> // Supplied AVR Sleep Macros
또한 표준 AVR 헤더 중 하나에 정의 된 매크로 <_BV (BIT)>를 다음과 같이 사용합니다 (더 친숙 할 수 있음).
#define _BV(BIT) (1<<BIT)
코드의 시작
MCU가 처음 시작되면 일반적으로 I / O를 초기화하고 타이머를 설정하는 등의 작업을 수행해야합니다. 여기서 WDT가 다시 수행 할 수 있기 때문에 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 슬립
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
****************************/
}
}