본문 바로가기
대한상공회의소 스마트팩토리 교육/IoT 디바이스 개발

[IoT 디바이스 개발] AVR(ATmega128A)«수업-24» :워치도그 타이머(Watchdog Timer, WDT)

by 나는영하 2022. 3. 7.

※ 주의사항 

본 블로그는 수업 내용을 바탕으로 제가 이해한 부분을 정리한 블로그입니다.
본 내용을 참고로만 보시고, 틀린 부분이 있다면 지적 부탁드립니다!

감사합니다😁

 

안녕하세요!!

오늘은 아래와 같은 내용을 확인해보겠습니다.

 

워치도그 타이머

Watchdog Timer


1. 워치도그 타이머

※ 워치도그 = 경비견을 가리키는 단어

1-1. 워치도그 타이머란?

워치도그 타이머 블록다이어그램

1) 시스템의 오작동을 감시하기 위한 목적으로 사용

- 시스템이 정상적인 동작을 수행하지 못하는 경우 시스템을 리셋 시킨다.

2) 워치도그 타이머의 경우 시스템 클록과는 별개로 내부 오실레이터에 의해 1Mhz로 동작한다.

- 분주비(PRESCALER) 설정을 통해 워치도그 타이머의 동작 주파수를 결정할 수 있다.

3) 워치도그 타이머가 만료 되면 워치도그 리셋이 수행되며, 따라서 워치도그 리셋 이전에 워치도그 타이머를 리셋해 주어야 한다.

- 워치도그 리셋 : 워치도그 타이머의 측정 시간이 지나서 본 마이크로컨트롤러가 리셋되는 작업

- 워치도그 타이머 리셋 : 워치도그 타이머가 일정 시간이 지나기 전에 워치도그 타이머의 리셋 하는 작업

(두개 종류의 리셋의 의미를 구분해서 사용하고 본문의 내용을 이해하도록 하자!)

 

1-2. 워치도그 타이머 관련 레지스터

1) WDTCR 레지스터

WDTCR 레지스터

(1) WDCE 비트(Watchdog Change Enable) :

- WDE와 WDP 비트의 값을 변경하기 위해서는 WDCE 비트를 먼저 세트한 후 변경해야한다.

- WDCE 비트가 세트된 이후에는 4클록 이후 자동으로 클리어 된다.

- 워치도그 타이머의 만료 시간 변경이나 비활성화를 위해서는 반드시 정해진 순서와 타이밍을 지켜야 한다.

 

(2) WDE 비트(Watchdog Enable) :

- 워치도그 타이머 만료에 의한 시스템 리셋을 허용한다.

- 안전 수준 2에서는 WDE 비트와 무관하게 워치드고 타이머가 항상 동작한다.

(안전 수준 2에서는 워치도그 타이머 비활성화 불가)

 

(3) WDP2 ~ WDP0 비트(Watchdoh Timer Prescaler) :

- 워치도그 타이머의 분주비를 설정한다.

 

※ 워치도그 타이머의 분주비에 따른 만료시간

WDP2 WDP1 WDP0 VCC = 3V에서의 만료시간 VCC = 5V에서의 만료 시간
0 0 0 14.8ms 14.0ms
0 0 1 29.6ms 28.1ms
0 1 0 59.1ms 56.2ms
0 1 1 0.12s 0.11s
1 0 0 0.24s 0.22s
1 0 1 0.47s 0.45s
1 1 0 0.95s 0.9s
1 1 1 1.9s 1.8s

 

2) MCUCSR 레지스터

MCUCSR 레지스터

(1) WDRF 비트(Watchdog Systme Reset Flag) : 

- 워치도 타이머에 의한 리셋이 발생한 경우 1로 세트된다.

- 파워ON 리셋이 발생하거나 해당 비트에 논리 0의 값을 기록하면 클리어 된다.

※ 나머지 비트는 워치도그 타이머와 관계없는 비트로써 설명은 생략😁

 

1-3. 워치도그 타이머 라이브러리

1) Time Sequence 사용 방법은 간단하지 않아 라이브러리를 사용하는것이 일반적 

2) 헤더 파일 : #include <wdt.h>

3) 3개의 매크로 함수

- wdt_reset : 워치도그 타이머 리셋

- wdt_disable : 워치도그 타이머 비활성화

- wdt_enable(value) : 워치도그 타이머 활성화

※ vlaue 값에 따른 워치도그 타이머 만료 시간 상수

상수 WDP[2:0] VCC = 5V에서의 만료 시간
WDTO_15MS 000 14.0ms
WDTO_30MS 001 28.1ms
WDTO_60MS 010 56.2ms
WDTO_120MS 011 0.11s
WDTO_250MS 100 0.22s
WDTO_500MS 101 0.45s
WDTO_1S 110 0.9s
WDTO_2S 111 1.8s

※ 마이크로컨트롤러에 공급되는 전압에 따라 실제 만료시간을 달라집니다!! 따라서 워치도그 타이머의 리셋 주기는 생각보다 많이 짧게 해주는것이 좋을 듯 싶습니다. 😁

 


 

2. 워치도그 타이머 관련 실습

2-1. 결과 사진

워치도그 타이머 리셋 미실시(좌) / 워치도그 타이머 리셋 실시(우)

- 메인문의 초기화 부분에 들어가 있는 "Initialization..."이 약 2초 마다 반복되는 것으로 보아 왼쪽은 워치도그 타이머의 만료 시간에 따른 마이크로컨트롤러가 리셋 되는것을 알 수 있다.

- 오른쪽은 16비트 타이머의 오버플로 인터럽트의 ISR에 워치도그 타이머 리셋 명령어를 넣어서 만료 시간 이전에 리셋을 수행하여 마이크로 컨트롤러가 리셋되는것을 방지하게 된다. (카운트 값은 주기적으로 증가 하게 된다.) 

 

2-2. 코드

#define F_CPU 16000000L
#include <avr/io.h>
#include <stdio.h>
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include "UART0.h"

FILE OUTPUT\
= FDEV_SETUP_STREAM(UART0_transmit, NULL, _FDEV_SETUP_WRITE);
FILE INPUT\
= FDEV_SETUP_STREAM(NULL, UART0_receive, _FDEV_SETUP_READ);

ISR(TIMER1_OVF_vect){
	wdt_reset();
	TCNT1 = 50000;
}

void Timer1_Init(){
	TCCR1B |= ((1<<CS12)|(1<<CS10));//1024분주 설정
	TIMSK |= (1<<TOIE1); //1번타이머 오버플로 인터럽트 활성
}

int main(void)
{
	TCNT1 = 50000;
	wdt_enable(WDTO_2S);
	
	stdout = &OUTPUT;
	stdin = &INPUT;
		
	UART0_init();
	Timer1_Init();	
    sei(); //전역 인터럽트 활성화 
	
	printf("*** Initialization...\r\n");
	
	uint16_t count = 0;
    while (1) 
    {
		count++;
		printf("count : %d\r\n", count);
		_delay_ms(1000);
    }
	return 0;
}

- 16비트 타이머의 오버플로 ISR 안에 wdt_reset()명령어를 넣음으로써 약 1초 마다 워치도그 타이머 리셋이 수행된다. (TCNT1의 시작 값은 50000으로 오버플로 발생 시간은 (1/15625) * 15536 = 0.994304s에 해당된다.)

 

댓글