본문 바로가기

AVR/AVR 연습, Tutorial

AVR 타이머/카운터 인터럽트 (Timer/Counter interrupt) 제어 레지스터 - AVR 이론


타이머/카운터란 무엇일까요?





STEP. 1

타이머/카운터는 인터럽트와 처리가 동일한데 시간이 더해진 형태입니다.

타이머가 일정한 시간마다 신호를 주면 카운터는 그것을 세어서 8비트 AVR의 경우에 256가 넘으면 8비트로 계산 할수 있는 값이 아니므로 넘침(Overflow) 가 발생하게 됩니다.

이 때 인터럽트가 발생해서 원하는 프로그램을 처리하는 것이지요.!


STEP. 2

타이머/카운터를 이해하기 위해서는 주기와 주파수의 관계를 알아야 합니다.

먼저 주파수는 1초에 진동하는 횟수 라고 일반적으로 알고 있습니다. 

하지만 AVR 하는동안은 의미를 바꾸세요. 1초에 들어오는 신호로.!

주기는  진동한번 즉 신호한번 1Hz가 들어오는 시간을 말합니다.


만약 이런신호가 측정되었다면 신호상승에서 하강까지가 신호 1번이고, 그 신호가 1초동안 6번 측정되었습니다. 이 경우 주파수는 6Hz이고, 주기는 1/주파수 즉 1/6 인 약 0.17초가 나오게됩니다. 만약 주기를 알고있다면 1/주기 값을 하면 다시 주파수 값이 나옵니다.


타이머/카운터 인터럽트 레지스터



레지스터 설정에 앞서 먼저 가상의 하드웨어 스펙이 외부크리스탈 8Mhz 이고,

내가 원하는 출력시간은 20 밀리 초로 구현하고자 하고 설정합니다.


 TIMSK (Timer/Counter Interrupt Mask Register)


이 레지스터는 타이머/카운터0번 (8 비트)와 타이머/카운터1번 (16 비트)의 인터럽트 허용 및 동작방식을 설정하는 레지스터입니다.

TOIE0을 1로 설정하면 타이머/카운터0 오버플로우 인터럽트가 허용이되고, OCIE0A와 OCIE0B는 각각 타이머/카운터0 비교 인터럽트 허용 레지스터입니다.

타이머/카운터 오버플로우 인터럽트 사용시에는 반드시 TOIE0을 세트 시켜주어야 합니다.


 TCCR0A (Timer/Counter Control Register A)


해당 레지스터는 타이머/카운터0번의 동작방식에 대한 모든 것을 컨트롤하는 레지스터입니다.


- 일반 타이머/카운터0 옵션 -


 COM0A1

 COM0A0

동작 

 0

 0

 일반 출력모드, OCR0A 연결안함

 0

 1

비교매치시 출력을 토글 0과 1을 반복시킵니다.

 1

 0

비교매치시 출력을 0으로 클리어 시킵니다.

 1

 1

비교매치시 출력을 1로 세트 시킵니다. 


 COM0B1

 COM0B0

동작 

 0

 0

 일반 출력모드, OCR0B 연결안함

 0

 1

비교매치시 출력을 토글 0과 1을 반복시킵니다.

 1

 0

비교매치시 출력을 0으로 클리어 시킵니다.

 1

 1

비교매치시 출력을 1로 세트 시킵니다. 


오버플로우로 사용시에는 그냥 TCCR0A = 0x00 값을 주면 문제없이 동작됩니다.


- PWM 모드 사용시 타이머/카운터 옵션 -


COM0A1

COM0A0

동작

0

0

일반 출력모드, OCR0A 연결안함

0

1

WGM02=0 일반 출력모드, WGM02=1 비교매치시 토글 0과 1을 반복시킵니다.

1

0

비교매치시 0으로 클리어, TOP에서 OCR0A 1로 세트

1

1

비교매치시 1로 세트, TOP에서 OCR0A 0으로 클리어


 COM0B1

COM0B0

동작

0

0

일반 출력모드, OCR0B 연결안함

0

1

예약됨, 사용하지 않음

1

0

비교매치시 0으로 클리어, TOP에서 OCR0B 1로 세트

1

1

비교매치시 1로 세트, TOP에서 OCR0B 0으로 클리어


TOP 값은 8비트 오버플로우 값 16진수 0xFF, 10진수로 256을 의미 또는 OCR0A, B 레지스터에 직접 입력 한 값입니다.


 TCCR0B (Timer/Counter Control Register B)


타이머/카운터0 설정시에 가장 중요한 레지스터라고 할 수 있겠네요.


여기서 분주비를 잘못 설정하면 타이머/카운터의 동작시간이 완전히 맞지 않게됩니다. 먼저 가상 하드웨어가 8Mhz 크리스탈을 사용하지요. 이 주파수의 주기를 구하면 0.000000125초 (0.125 마이크로)초 마다 한 신호가 발생됩니다. 그걸 이용해서 20 밀리초의 시간을 만들고자 하는데 또 문제가 8비트 AVR은 256까지 밖에 카운팅을 하지 못하는데, 0.000000125초를 256번 다 세었더라도 0.0000032초로 (약 3.2 마이크로초) 정도 밖에 나오지 않습니다. 따라서 TCCR0B의 분주 옵션으로 한 신호(주기)의 시간을 낮추어 주어야 합니다.


 CS02

CS01 

CS00 

 분주비

타이머/카운터 인터럽트를 멈춤

클럭을 그대로 사용 

 클럭/8 프리스케일러 사용

 클럭/64 프리스케일러 사용

 클럭/256 프리스케일러 사용

클럭/1024 프리스케일러 사용 

 외부 클럭소스 (클럭 하강에지)

 외부 클럭소스 (클럭 상승에지)


따라서 프리스케일러 설정마다 계산해줍니다.

클럭을 그대로 사용시에는 0.000000125초 (0.125 마이크초)

클럭/8 계산시에는 클럭*8 사용시에는 0.000001 (1 마이크로 초)

클럭/64 사용시에는 0.000008 (8 마이크로 초)

클럭/256 사용시에는 0.000032 (32 마이크로 초)

클럭/1024 사용시에는  0.000128 (128 마이크로 초) 로 계산 됩니다.

이 때 TCNT값 255 안에서 이 값들과 곱했을 때 20 ms(밀리초)를 만들 수 있는 값은 어떤

옵션일까요? 또 계산 해봅니다.

20ms 는 0.02초 입니다. 이 값을 위에서 구해진 값으로 나눕니다.

클럭을 그대로 사용시에는 160000번을 TCNT0이 카운트 해야 해서 안되겠군요.!

클럭/8 사용시에는 20000번을 TCNT0에서 카운트로 역시 256 안에 들어오지않습니다.

클럭/64 사용시에는 2500번을 TCNT0에서 카운트 하므로 사용이 불가능 하군요.

클럭 256 사용시에는 625번을 TCNT0에서 카운트 해야하므로 사용이 안됩니다..

클럭/1024 사용시에는 156.25번을 TCNT0에서 카운트 해야합니다. 소수가 나와서 오차가 생기지만, 8비트 값 256 안에 들어오므로 사용이 가능합니다. 따라서 TCCR0B레지스터 설정을 클럭 1024로 설정해두고, TCNT0의 초기값을 256에서 156을 뺀 100으로 해두면 156을 카운트한 후에 오버플로우 인터럽트가 발생됩니다.


- FOC0A, FOC0B에 대해서 -

큰 용도가 있어보이는 레지스터는 아니며, WGM옵션 아래 표 옵션 중에 PWM 모드가 아닐 시에만 사용이 가능하고, 오버플로우 모드나, CTC모드일 때 이 비트를 1로 설정하면 AVR에서는 TCNT0과 OCRx값이 비교매치 된것으로 판단 OCRx핀에 출력을 합니다.

>> 사용해보지 않아서 정확한 용도가 확실치 않습니다.<<


- TCCR0A, TCCR0B 공동사용 설정 부분 -


모드

WGM02

WGM01

WGM00

타이머/카운터 옵션

TOP값 

업데이트 OCRx

OVF 발생

0

0

0

0

일반모드 (=오버플로우 모드)

0xFF

즉시

MAX

1

0

0

1

PWM, 위상 보정

0xFF

TOP

BOTTOM

2

0

1

0

비교매치 CTC

OCR0x

즉시

MAX

3

0

1

1

Fast PWM

0xFF

 TOP

MAX

4

1

0

0

예약됨 사용하지 않음

-

-

-

5

1

0

1

PWM, 위상보정

OCR0x

TOP

BOTTOM

6

1

1

0

예약됨 사용하지 않음

-

-

-

7

1

1

1

Fast PWM

OCR0x

TOP

TOP


BOTTOM = 0x00, TOP=OCR0x 또는 0xFF, MAX=0xFF 를 의미합니다.


 TCNT0 (Timer/Counter register)


이 레지스터는 한 주기당 들어오는 신호를 세어주는 레지스터입니다.

이 값이 256이 넘으면 Overflow 처리 값 넘침으로 인터럽트 처리를 하게 됩니다.
또 비교매치 인터럽트 시에는 이 값과 OCR0A혹은 OCR0B의 입력값과 비교해서

같으면 인터럽트가 발생하는데에도 사용됩니다.


 TIFR (Timer/Counter Interrupt Flag Register)

해당 레지스터는 오버플로우 인터럽트나 비교매치 인터럽트가 발생했을 때 신호가 발생했다고

알려주는 레지스터로 TOV0은 오버플로우 레지스터 발생이 되면 해당 비트가 1로 셋팅되고,

OCF0A와 OCF0B는 각각 OCR0A와 OCR0B와 TCNT0값을 비교해서 같으면 1로 셋팅됩니다.

외부 인터럽트와는 다르게 인터럽트 프로그램을 실행하고 나면 자동으로 클리어 0으로 

입력됩니다.


 OCR0A (Output Compare register A)

TCCR0A에서 오버플로우 인터럽트나, 일반 비교매치인터럽트를 사용하지 않고, 타이머/카운터의 부가 기능인 PWM, Fast PWM, Phase Corrent 또는 단순 비교매치를 토글이나, 세트, 클리어로 고정 시켰을 경우 OCR0A에 입력한 값과 한 주기마다 카운트를 해주는 TCNT0의 값을 비교한다음 같으면 OCR0A핀에 출력이 이루어 지는 구조로 출력은 PWM출력 혹은 사용자가 설정한 OCR0A 값에 따라 결정된 주기에 맞게 토글출력, 혹은 세트, 클리어로 출력이 됩니다.


 OCR0B (Output Compare register B)

TCCR0A에서 오버플로우 인터럽트나, 일반 비교매치인터럽트를 사용하지 않고, 타이머/카운터의 부가 기능인 PWM, Fast PWM, Phase Corrent 또는 단순 비교매치를 토글이나, 세트, 클리어로 고정 시켰을 경우 OCR0B에 입력한 값과 한 주기마다 카운트를 해주는 TCNT0의 값을 비교한다음 같으면 OCR0B핀에 출력이 이루어 지는 구조로 출력은 PWM출력 혹은 사용자가 설정한 OCR0B 값에 따라 결정된 주기에 맞게 토글출력, 혹은 세트, 클리어로 출력이 됩니다.

OCR0A와 같습니다만 TINY2313에는 비교매치핀이 두개 있기 때문에 레지스터도 2개입니다.