이전 포스트에서 T/C0에 대해서 소개를 하였다. 여기에서는 관련 IOCR에 대해서 자세히 알아보도록 하겠다.

TCCR0 레지스터

 T/C0가 어떤 클럭 소스을 사용할 것인지는 TCCR0(Timer/Counter Control Register 0)의 b2:0 비트의 CS02, CS01, CS00에 의해서 선택되게 된다.

[그림 1] TCCR0의 비트 구조


TCCR0의 비트 3번부터 7번까지는 예약한 비트들로서 사용되지 않으며 항상 0으로 읽혀진다. 그리고 b2, b1, b0은 다음 표와 같이 T/C0의 프리스케일링 소스를 정의한다.


[표 1] T/C0의 프리스케일 선택

CS02

CS01

CS00

설명

0

0

0

정지, 타이머/카운터0를 정지시킴

0

0

1

clk

0

1

0

clk/8

0

1

1

clk/64

1

0

0

clk/256

1

0

1

clk/1024

1

1

0

외부핀 T0 하강에지

1

1

1

외부핀 T0 상승에지

TCNT0 레지스터

 TCNT0는 클럭 소스의 카운트 값을 실시간으로 저장하는 레지스터로서 읽고 쓰기가 가능하다. 만약 TCNT0에 어떤 값이 쓰여 지면 그 쓰기 동작에 뒤이어 그 값에서부터 계수 작업이 수행되게 된다.


[그림 2] TCNT0 레지스터

이 레지스터는 초기값 $00 (0b00000000)으로 부터 최대값 $FF (0b11111111)까지 순차적으로 업카운팅(up-counting)을 하게 된다. 그리고 최대값 $FF가 되고 나서 그 다음 클럭이 들어오면 $FF + 1 = $00 가 되고 오버플로우(overflow)가 발생하게 된다. 이때 오버플로우 인터럽트가 발생하게 설정이 되었다면 인터럽트가 발생하게 될 것이다.


TIMSK (Timer/counter Interrupt MaSK) 레지스터

 TIMSK는 TC0와 TC1의 인터럽트를 사용할 수 있도록 설정하는 레지스터이다. 여기서는 TC0와 관련된 1번 비트만 확인하자.

[그림 3] TIMSK 레지스터


비트0은 TOIE0 (Timer/counter Overflow Interrupt Enable 0)라고 명명되어 있는데 T/C0에서 오버플로우가 발생했을 때 인터럽트를 발생시킬 것인지 아닌지를 설정하는 비트이다. “0”으로 설정되면 인터럽트를 발생시키지 않으며 “1”로 설정하면 글로벌 인터럽트가 인에이블이면 (즉 SREG의 I비트가 1로 되어 있으면) 인터럽트가 발생된다.

TIFR (Timer/counter Interrupt Flag Register) 레지스터

 TIFR의 구조는 TIMSK의 구조와 유사하며 다음과 같다.

[그림 4] TIFR 레지스터


이 중 TC0와 관련된 비트는 0번이며 만약 TC0에서 오버플로우가 발생하면 b1인 TOV0가 자동적으로 세트가 된다. 이 경우에 TIMSK의 b0가 (TOIE0) “1”로 설정이 되어 있다면 인터럽트가 발생되어 해당하는 ISR 함수가 호출되게 된다.


T/C0와 T/C1의 프리스케일러

 프리스케일링(prescaling)이라는 것은 입력된 클럭의 주기를 정해진 배수로 변형시키는 것이다. 다음 그림 7.2.2에서 보듯이 만약 CK/8이라면 입력 클럭 clk 의 주기가 8배로 늘어나게 됨을 알 수 있다. 만약 CK/64라면 주기가 64배로 늘어날 것이다. 이러한 기능을 수행하는 유닛을 프리스케일러(prescaler)라고 한다. (나누기로 표시되어있어서 주기가 줄어든다고 오해하면 안 된다.)


[그림 5] 프리스케일링의 개념도


T/C0와 T/C1은 같은 프리스케일러 모듈을 사용하지만 설정은 각각 다르게 할 수 있다. 이 프리스케일러는 T/C의 설정과는 무관하게 연속적으로 동작하고 하나의 프리스케일러를 T/C0과 T/C1이 공유한다. 프리스케일러를 리셋하려면 SFIOR 레지스어의 0번 비트 (PSR10)을 ‘1’로 쓰면 된다. 이후에 리셋동작이 끝나면 이 비트는 하드웨어적으로 (자동으로) ‘0’으로 클리어된다.


[그림 6] T/C0와 T/C1의 프리스케일러




Posted by 살레시오
,