여기에서는 이전 포스트에서 소개했던 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;//0b00000100TIMSK=0xC0;//0b11000000TCNT2=0x00;OCR2=00;sei();// global interrupt enableLED(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에 인가되는 클럭의 주파수이다.
'하드웨어 > ATmega8(A)' 카테고리의 다른 글
ATmega8(A) 아날로드-디지털 변환기(ADC) 개요 (0) | 2015.06.29 |
---|---|
ATmega8(A) T/C2의 PWM 모드 (0) | 2015.06.23 |
ATmega8(A) T/C2의 레지스터와 프리스케일러 (0) | 2015.06.23 |
ATmega8(A) T/C2의 기능 개요 (0) | 2015.06.23 |
ATmega8(A) T/C0의 레지스터와 프리스케일러 (0) | 2015.06.23 |