여기에서는 이전 포스트에서 소개했던 T/C2의 정상 모드와 CTC 모드에 대해서 자세히 살펴보도록 하겠다.

정상(Normal) 모드

 정상 모드는 TCNT2레지스터가 OCR2레지스터의 값에 영향을 받지 않고 $00부터 $FF까지 1씩 증가하는 동작을 반복하며 중간에 이 값이 클리어되지 않는 가장 단순한 기능의 모드이다. TCNT2레지스터가 $00값이 되는 동시에 TOV2 (overflow flag)가 ‘1’이 되고 만약 오버플로 인터럽트가 활성화되어 있다면 ISR이 호출된 후 TOV2는 자동으로 ‘0’으로 클리어된다. 또한 TCNT2값이 OCR2값과 일치되는 순간 TOCI2가 ‘1’이 되고 만약 OCIE2 비트가 ‘1’로 설정되었다면 비교 매치 인터럽트가 발생된다.


 따라서 이 모드는 일정한 시간 주기로 인터럽트를 발생하는 용도로 사용되나 그 주기를 정밀하게 결정하지는 못하는 단점이 있다. 또한 normal 모드에서도 COM21:0비트를 설정하여 OCR2의 비교매치를 사용할 수는 있으나 데이터쉬트에 의하면 normal모드에서 OC2핀을 활성화시키는 것은 권장되지 않는다.


 이제 노멀모드의 두 개의 인터럽트를 이용해서 LED의 밝기를 조절하는 예제를 작성해 보자. 다음 프로그램을 실행시켜보면 LED전체가 점점 밝아졌다가 꺼진후 다시 점점 밝아지는 동작을 반복한다.


#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "am8USBasp.h"
ISR(TIMER2_OVF_vect) {
   TurnLEDOn;
}
ISR(TIMER2_COMP_vect) {
   TurnOffAll;
}
int main(void){
   uint uiA;
   InitAM8();
   ASSR=0x00;
   TCCR2=0x04;//0b00000100
   TIMSK=0xC0;//0b11000000
   TCNT2=0x00;
   OCR2=00;
   sei();// global interrupt enable
   LED(0xFF);
   while(1) {
       for(uiA=0;uiA<256;uiA+=5) {
           OCR2 = (uchar)uiA;
           _delay_ms(100);
       }
   }
}


이 예제에서 보면 오버플로 인터럽트에서는 LED를 모두 켜고 비교매치 인터럽트에서는 LED를 모두 끄게 되어 있다. 이러한 동작이 1초에 약 977번 일어나기 때문에 눈으로 보기에는 깜빡이는 것이 아니라 밝기가 다르게 보이는 것이다. OCR2의 값이 클수록 LED가 켜져 있는 구간이 길어지므로 OCR2값이 0에 가까우면 거의 꺼진 것 같이 보이고 커질수록 더 밝아보이게 된다. 이러한 동작을 펄스폭 변조(PWM) 제어라고 하는데 디지털 회로에서 그 응용폭이 넓기 때문에 AVR에는 PWM을 발생시키는 별도의 기능이 마련되어 있으며 7.3.3절에서 자세히 설명하도록 하겠다.


CTC (Clear Timer on Compare match) 모드

 정상 모드에 비해서 CTC 모드는 조건 TCNT2 == OCR2 이 만족되는 그 다음 순간에 TCNT2레지스터가 $00으로 초기화 된다는 점이 다르다. non-PWM모드 (노멀 모드와 CTC 모드)에서 COM21:0비트의 설정에 따라 OC2핀이 어떻게 동작하는 지는 다음 표에 정리하였다. 두 개의 COM21, COM20 비트 중 하나라도 0이 아니면 ATmega8(A)의 17번 핀은 PB3로 동작하는 것이 아니라 OC2핀으로 동작한다.


[표 1] non-PWM 모드일 때 비교 출력 모드

COM21

COM20

OC2핀의 동작

0

0

포트핀(PB3)으로 동작

0

1

비교매치 시 OC2 토글(toggle)

1

0

비교매치 시 OC2 클리어(‘0’)

1

1

비교매치 시 OC2 세트(‘1’)


[그림 1] CTC모드의 타이밍 다이어그램


또한 TIMSK레지스터의 OCIE2 비트를 ‘1’로 설정하여 TCNT2가 OCR2값과 같을 때 인터럽트(비교매치 인터럽트)를 발생하게 설정할 수도 있다. 그리고 노멀모드와 마찬가지로 TOV2 플래그는 TCNT2레지스터가 OCR2레지스터 값에 도달하여 0x00으로 클리어되는 순간 ‘1’로 세트되지만 이 모드에서는 오버플로우 인터럽트가 별로 의미가 없다. 왜냐하면 같은 시점에서 OCI2 인터럽트가 발생하기 때문이다.

CTC모드의 가장 큰 장점은 사용자가 원하는 정밀한 주기의 인터럽트를 발생할 수 있다는 점, 그리고 [그림 1]에서 보듯이 COM21:0=01로 설정하면 원하는 주기를 가지는 구형파를 생성하여 OC2핀으로 내보낼 수 있다는 점이다. 이 경우에는 반드시 DDRB3를 ‘1’로 하여 출력모드로 설정해두어야만 한다. 이 경우 주파수의 계산식은 다음과 같다.

여기서 N은 분주수(1, 8, 32, 64, 128, 256, 1024 중 하나)이고 fdk 는 T/C2에 인가되는 클럭의 주파수이다.



Posted by 살레시오
,