레이블이 카운터인 게시물을 표시합니다. 모든 게시물 표시
레이블이 카운터인 게시물을 표시합니다. 모든 게시물 표시

2015년 6월 23일 화요일

ATmega8(A) T/C2의 PWM 모드

 PWM이라는 것은 구형파의 듀티비(duty ratio)를 조절하는 것을 의미한다. 듀티비란 구형파의 주기와 ‘1’이 되는 구간의 시간비율을 의미한다. 다음 [그림 1]에서 T는 주기, t1은 한주기에서 ‘1’이 되는 시간을 표기하는데 듀티비는 t1/T 로 정의된다.

[그림 1] PWM과 듀티비

ATmega8(A)의 T/C2는 두가지 PWM발생 모드를 가지고 있는데 하나는 고속PWM모드이고 다른 하나는 위상교정PWM 모드이다. 이 두 가지에 대해서 각각 알아보겠다.

고속 PWM 모드

 고속 PWM모드는 TCNT2레지스터가 노멀모드에서와 같은 동작을 한다. 즉, 0x00에서 0xFF까지 1씩 증가하다가 그 다음 사이클에서 다시 0x00으로 클리어된 후 다시 1씩 증가한다. 이 때 ① TOV2 플래그가 세트되며 ②비교매치시 OC2 플래그도 세트된다. OC2 핀은 COM21:0 비트들의 설정에 따라서 동작이 결정되는데 ①의 경우에 세트되고 ②의 경우에 리셋 되거나 혹은 반대의 동작을 취할 수 있다.([표 1] 참조) 데이터쉬트에서 [그림 1]에 고속 PWM모드의 타이밍 다이어그램을 발췌하였다.

[그림 2] 고속 PWM 모드에서의 타이밍 다이어그램

[표 1] 고속 PWM 모드일 때 비교 출력핀(OC2핀) 동작
COM21
COM20
OC2핀의 동작
0
0
포트핀(PB3)으로 동작
0
1
-
1
0
TCNT2=0x00일때 OC2핀 셋,
비교매치시 OC2핀 리셋
1
1
TCNT2=0x00일때 OC2핀 리셋,
비교매치시 OC2핀 셋

OC2핀으로 발생하는 PWM파형의 주기는 다음 식과 같이 계산할 수 있다.
여기서 N 은 분주수를 나타내며 1, 8, 32, 64, 128, 256, 1024 중 하나이고, fTC2는 T/C2에 인가되는 클럭 주파수이다.

 한 가지 유용한 사실은 오버플로우 인터럽트와 비교매치 인터럽트를 이용하면 임의의 포트핀에 PWM파형을 발생시킬 수 있다는 점이다. 즉 해당하는 ISR() 함수 내부에서 원하는 포트핀을 셋시키거나 리셋시켜서 OC2핀 뿐만 아니라 임의의 포트핀에 PWM파형을 발생시킬 수 있다.

위상 교정 PWM 모드

 위상교정PWM 모드가 고속PWM 모드와 다른 점은 TCNT2레지스터가 0에서 0xFF값에 도달한 후(업-카운팅) 0x00으로 클리어되는 것이 아니고 1씩 감소하여 다시 0x00이 된다(다운-카운팅)는 점이다. 이때 비교매치는 두 가지 경우인데 업 카운팅의 경우와 다운 카운팅의 경우이다. PWM파형은 업-카운팅에서 비교매치가 일어난 경우 OC2핀을 ‘1’로, 다운-카운팅에서 비교매치가 일어난 경우 OC2핀을 ‘0’으로 설정하여 PWM파형을 발생시킨다. (혹은 그 반대의 모양으로 발생시킬 수 있다.)

[그림 3] 위상 교정 PWM 모드의 타이밍 다이어그램

OC2핀으로 발생하는 PWM파형의 주파수는 고속 PWM의 경우보다 두 배 줄어들며 다음 식과 같이 계산할 수 있다.
여기서 N은 분주수를 나타내며 1, 8, 32, 64, 128, 256, 1024 중 하나이다.

[표 2] 위상 교정 PWM 모드일 때 비교 출력핀(OC2핀) 동작
COM21
COM20
OC2핀의 동작
0
0
포트핀(PB3)으로 동작
0
1
reserved
1
0
업카운팅에서 비교매치시 OC2핀 리셋
다운카운팅에서 비교매치시 OC2핀 셋
1
1
업카운팅에서 비교매치시 OC2핀 셋
다운카운팅에서 비교매치시 OC2핀 리셋

고속 PWM모드에서와 마찬가지로 두 개의 인터럽트를 이용하면 위상교정 PWM파형도 임의의 포트핀으로 내보낼 수 있다. 단, 이번에는 앞의 경우와 달리 비교매치 인터럽트가 업-카운팅에서 발생했는지 다운-카운팅에서 발생했는지를 판별해야 할 것이다. 이것을 위해서 [그림 3]을 살펴보면 오버플로우 인터럽트는 다운-카운팅에서 0x00에 도달한 경우에 발생하는 것을 알 수 있다. 따라서, 오버플로우 인터럽트가 발생한 이후 첫 번째 비교매치 인터럽트는 업-카운팅에서, 두 번째 비교매치 인터럽트는 다운-카운팅에서 발생한 것으로 판정해야 하므로 조건 검사를 하는 코드가 앞의 경우에 비해서 더 추가가 되어야 할 것이다.

ATmega8(A) T/C2의 정상 모드와 CTC 모드

 여기에서는 이전 포스트에서 소개했던 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에 인가되는 클럭의 주파수이다.


ATmega8(A) T/C2의 레지스터와 프리스케일러

 이전 포스트에 이어서 T/C2에 관련된 레지스터들에 대해서 알아보자. T/C2와 관련된 레지스터들은 다음과 같다.

[표 1] T/C2와 관련된 레지스터들
레지스터
용도
TCNT2
클럭의 계수값을 실시간으로 저장하는 레지스터
OCR2
(Overflow Compare Register) 이  레지스터의 값이 오버플로가 발생하는  값으로 설정된다.
TCCR2
T/C2의 전체적인 동작을 설정하고 제어하는 레지스터
TIMSK
T/C2의 인터럽트를 사용할 수 있도록 설정
TIFR
T/C2의 인터럽트가 발생했는지를 표시하는 레지스터
ASSR
어떤 클럭 소스를 이용할 것인가를 설정


ASSR 레지스터

 ASSR2 레지스터를 이용하여 어떤 클럭 소스를 이용할 것인가를 설정할 수 있다.

[그림 1] ASSR 레지스터의 구조

이 ASSR레지스터의 b3는 AS2인데 이 비트가 ‘0’이면 시스템 클럭을, ‘1’이면 TOSC1, TOSC2핀으로 인가되는 외부 클럭을 T/C2의 클럭소스로 선택한다.

TCCR2 레지스터

 TCCR2 레지스트는 T/C2의 전체적인 동작을 설정하고 제어하는 레지스터이다.

[그림 2] TCCR 레지스터

FOC2는 b7인데 이 비트는 항상 ‘0’으로만 읽혀지며 PWM모드가 아닐 때만 ‘1’을 쓸 때 강제로 비교매치가 수행된다. (Force Output Compare) 이 경우 OC2핀의 출력은 COM21:0비트의 설정에 따라 변하게 된다.
그리고 b6과 b3 두 개의 비트는 WGM21:0로 표기하면 T/C2의 동작 모드를 설정하는데 사용되며  다음 표에 각각의 모드를 수록하였다.

[표 2] Waveform Generation Mode (WGM) 비트 설정
No
WGM21:0
모드
TOP
OCR2갱신
TOV2 세트
0
00
Normal
$FF
즉시
MAX
1
01
Phase Correct PWM
$FF
TOP
BOTTOM
2
10
CTC
OCR2
즉시
MAX
3
11
Fast PWM
$FF
BOTTOM
MAX

COM21:0 비트는 OC2핀의 출력을 제어하며 이 두 비트 중 하나라도 ‘1’로 세트되어 있다면 17번 핀은 포트핀(PB3)으로 동작하지 않고 OC2핀으로 동작하게 된다. 단 OC2핀으로 사용하기 위한서는 DDRB3는 반드시 출력(‘1’)으로 설정해야 된다는 것을 주의해야 한다. 또한 COM21:0 설정에 따른 동작은 어떤 모드로 동작하느냐에 따라서 값은 값이라도 다르다는 것에도 유의해야 한다.

 CS22:0 비트는 입력 클럭의 분주비를 설정하는 비트들이다.

[표 3] T/C2 프리스케일 선택
CS22
CS21
CS20
설명
clkT2S =16MHz일 때 TOI 발생 주파수
0
0
0
클럭 소스 없음
(T/C2 비동작)
발생 안 함
0
0
1
clkT2S
62,500 Hz
0
1
0
clkT2S /8
7,812 Hz
0
1
1
clkT2S /32
1,953 Hz
1
0
0
clkT2S /64
977 Hz
1
0
1
clkT2S /128
488 Hz
1
1
0
clkT2S /256
244 Hz
1
1
1
clkT2S /1024
61 Hz

TIMSK 레지스터

 T/C0에서도 소개한 바 있는 TIMSK 레지스터는 T/C2의 인터럽트를 사용할 수 있도록 설정하는 비트들을 가지고 있다. 여기서는 T/C2와 관련된 b6, b7 비트들을 확인하자.

[그림 3] TIMSK 레지스터

이 중 b6은 TOIE2 (Timer/counter Overflow Interrupt Enable 2)라고 명명되어 있다. TOIE2는 T/C2에서 오버플로우가 발생했을 때 인터럽트를 발생시킬 것인지 아닌지를 설정하는 비트인데 “0”으로 설정되면 인터럽트를 발생시키지 않는다. 만약 TOIE2가 “1”로 설정되어있고 글로벌 인터럽트가 인에이블이면 (즉 SREG의 I비트가 1로 되어 있으면) 인터럽트가 발생된다. b7은 비교매치 시에 인터럽트를 발생시킬 것인지 아닌지를 설정하는 비트이고 ‘1’로 설정되면 비교매치 인터럽트가 발생한다.