타이머 (Timer)
타이머 (Timer) / 카운터 (Counter)는 마이크로컨트롤러 응용에서 중요한 자원이다.
타이머는 말 그대로 시간을 재는 기구이다. delay 함수를 사용하여 1/100초 단위의 시간을 잴 수 있다. 반면, 타이머는 좀 더 정확하게 시간을 재기 위하여 마이크로컨트롤러가 사용하는 클락 (JKIT-128-1의 경우 16Mhz)을 기반으로 그 클락 펄스의 개수를 세는 것이라 할 수 있다.
카운터 (counter)는 우리말로 계수기라고 하는데, 한 마디로 개수를 세는 것을 말한다. 어떤 이벤트의 개수, 입장객 수, 걸음 수 등등 마이크로컨트롤러에서 보면 외부에서 어떤 사건 (이벤트)이 발생하는 것의 개수를 세는 형태로 사용된다.
ATmega128의 내부에는 4개의 타이머가 있는데 이들 중 Timer/Counter0, Timer/Counter2는 8비트이고, Timer/Counter1, Timer/Counter3는 16비트이다. 기능은 모두 비슷하므로 Timer/Counter0만 이해하면 다른 것은 똑같이 적용하여 사용할 수 있다.
TCNT0는 Timer/Counter0의 실제 카운터 값을 저장하는 레지스터로써 외부 클락이 한 번 입력될 때마다 자신이 가지고 있는 값을 1씩 증가시켜, 0 ➡ 1 ➡ 2 ➡ 3 ➡ 4 ➡ … ➡ 254 (0xfe) ➡ 255 (0xff) ➡ 0의 패턴으로 동작한다. 읽고 쓰기가 가능하므로 어떤 특정 값을 써 놓으면 그 값부터 1씩 증가하게 된다. 그런데, 256 (0xff) ➡ 0(0x00)으로 변화할 때에는 숫자가 더 이상 커질 수 없으므로 오버플로우 (overflow)가 생성된다. 이때, 내부적으로 미리 선언해 놓은 경우는 오버플로우 인터럽트가 발생하여 이 시점에 인터럽트 서비스 루틴이 실행되도록 할 수 있다.
8비트 카운터이므로 0에서 시작하여 255까지 256개의 숫자를 표현할 수 있고, 최대 숫자인 255를 지나면 더 이상 표현할 수 없으니까 오버플로우를 발생시키고 다시 0으로 돌아가는 방식이다.
Timer/Counter0 제어
Timer/Counter0 관련한 동작을 제어하기 위한 레지스터로는 TCCR0 (Timer Counter Control Register 0)가 있다.
1) WGM1-0 (Waveform Generation Mode) 00 = Normal (일반 카운터 모드) 2) COM1-0 (Compare Output Mode) 00 = Normal (일반 카운터 모드) 3) CS2-0 (Clock Select) 001 = 1분주, 010 = 8분주, 011 = 32분주, 100 = 64분주, 101 = 128분주, 110 = 256분주, 111 = 1024분주 |
이 중 CS2-0은 프리스케일러 (pre-scaler)를 선택하는 항목이다. 이것은 고속의 클락을 사용하여 타이머를 동작시킬 때 조금 긴 주기의 시간을 측정하기 위하여 클럭을 분주하는 방법이다. 8분주 프리스케일러를 선택한 경우에는 8번의 클락이 발생하여야 CNTR0에 1번의 클록이 전달되게 된다. 큰 프리스케일러 값을 선택하게 된다면 좀 더 긴 시간동안 동작하는 타이머를 만들 수 있다. ATmega128은 최대 1024분주까지가 가능하다. 1분주를 선택하면 원래의 클락이 그대로 들어간다.
TCNT0 값이 255 (0xff) ➡ 0 (0xff)로 변하게 될 때 오버플로우가 발생하는데, 이때 인터럽트도 함께 발생하게 하려면 TIMSK (Timer Counter Interrupt Mask Register)의 해당 비트인 TOIE0 (Timer0 Overflow Interrupt Enable)를 ‘1’로 설정해야 한다.
타이머로 원하는 시간을 세팅
예를 들어, 100us마다 반복적으로 인터럽트가 걸리도록 하는 방법은 다음과 같다.
1) 프리스케일러의 값을 정하여 타이머의 기본 주기를 계산한다. 예를 들어, 클락이 16MHz이고 프리스케일러이 32면, 타이머 클락의 주기는 (1/(16*1000000)) *32 = 2 (us) 2) 필요한 지연 시간을 타이머의 기본 주기로 나누어 클락 사이클을 계산한다. 100us의 지연 시간을 얻으려면 100/2 = 50 (클락)이 필요하다. 3) 256-클락 사이클 값을 TCNT0에 저장하고 오버플로우 인터럽트를 Enable 상태로 만든다. 위에서 256-50=206 값을 TCNT0에 저장하면, 이때부터 50클락 후 (100us 지난 후) 오버플로우 인터럽트가 발생하게 된다. 4) 엄밀하게 따지면 TCNT0에 값을 쓰거나 인터럽트가 발생하기 때문에 이것을 처리하는 시간이 소요되므로 정확하게 시간을 맞출 수는 없지만 이러한 시간은 ns (nano sec) 단위이므로 무시한다. |
'Embedded System > AVR' 카테고리의 다른 글
[AVR] CTC 비교매치 모드 인터럽트 (0) | 2022.06.09 |
---|---|
[AVR] JMOD-128-1 (0) | 2022.06.09 |
[AVR] MAX7219로 알파벳 표시 (0) | 2022.06.02 |
[AVR] Timing Diagram (0) | 2022.05.25 |
[AVR] MAX7219 (0) | 2022.05.25 |