CS/마이크로프로세서

[마이크로프로세서] 타이머/카운터 (1)

nowkoes 2023. 11. 15. 15:35

타이머/카운터

개요

 

 타이머/카운터(Timer/Counter)시간 관련 작업을 처리하고, 일정 시간 간격을 측정하거나, 특정 이벤트의 발생 횟수를 세는 데 사용된다. 이때 클럭의 주파수를 알면 클럭 주기를 알 수 있으므로, 타이머로 활용할 수 있다. 예를 들어, 3bit 타이머/카운터의 경우, 카운터의 상태가 111에서 000으로 변화할 때 오버플로우 인터럽트 플래그가 발생한다. 이때, MCU 내부 클럭을 사용하는 것타이머 모드, 외부 클럭 또는 외부 이벤트를 사용하는 것카운터 모드라고 한다. 

 

 이러한 타이머/카운터는 특정 작업 간의 시간 지연을 생성하고, 정확한 타이밍을 제공한다. 이전에 FND 혹은 LED를 제어할 때 주었던 delay는, 그 함수가 실행되는 시점에 모든 작업이 멈춘다. 이로 인해 앞에서 작성한 시간 지연 코드가 뒤에 있는 코드 실행에 영향을 미치거나, 인터럽트가 발생하지 않아 처리가 불편하다는 단점이 있었다. 이번 시간에는 이러한 단점들을 상쇄시킬 수 있는 타이머/카운터에 대해 알아보자.


본문

동작 원리

 우리가 사용하는 ATmega128 CPU는 8비트와 16비트 타이머/카운터를 사용한다. 하지만 동작 원리를 쉽게 이해하기 위해 3bit 타이머/카운터를 예시로 들겠다.

 

 

 일반적으로 타이머/카운터는 D-Flip Flop으로 설계된다. 데이터를 저장하고, 클럭 신호에 동기화하여 데이터를 전달하는 데 용이하기 때문이다. 타이머/카운터에서는 이러한 특성을 활용하여 Flag가 1이 되는 순간, 하드웨어적으로 인터럽트 플래그가 변화한다. 여기서 3bit 타이머/카운터를 사용한다 했으니, 비트가 111에서 00이 되는 순간 인터럽트가 발생한다. 참고로, D 플립플롭은 그 모양에 따라 트리거가 모드가 다르니, 아래 사진을 보고 가볍게 체크해 두면 좋을 것 같다.

 


ATmega128 타이머/카운터 

 ATmega128을 CPU로 채용하는 J-KIT-128-1의 경우, 8비트 타이머/카운터 2개, 16비트 타이머/카운터 2개를 사용할 수 있다. 

 

8bit 타이머/카운터 프리스케일러

 8비트 타이머/카운터는 카운트 레지스터를 갖고 있어 0부터 255까지의 값을 업/다운 계수(Count)가 가능하다. 그리고 10비트의 프리스케일러를 보유하고 있어, 다양한 클럭 소스를 선택할 수 있다. 즉, 카운트 속도를 조절하는 기능을 갖추고 있으므로, 다양한 시간 범위의 타이밍을 정할 수 있다. 이 프리 스케일러 기능이 타이머/카운터의 핵심인데, 이를 이해하기 위해 다음 자료를 보자.

 

 

 다음과 같이 FND 디스플레이에 어떠한 배열(FND에 차례대로 1, 2, 3, 4가 출력되게 하는)의 숫자를 1ms마다 출력하는 코드가 있다고 가정해 보자. 이때 이전에 작성했던 코드를 보면 알 수 있듯이, FND는 동적 구동 방식을 채용하고 있으므로 1ms의 지연을 주어서 한 번에 출력하게 구현해 놓은 것이다.

 

 여기서 1ms마다 인터럽트를 걸리게 하기 위해 클럭 주기를 구해보면, 다음과 같다.

 

 

 이때 ATmega128은 16MHz의 내부 클럭 속도를 갖고 있으므로, 클럭의 주기는 다음과 같다.

 

 

 이렇게 되면, 내부 클럭 주기 0.0625us이고, 8비트 타이머/카운트는 최대 16us까지만 카운트할 수 있기 때문에, 원하는 인터럽트 주기 1ms보다 훨씬 짧다. 이는 타이머/카운터가 1ms 동안 여러 번 오버플로우 할 것임을 의미하므로, 1ms 마다 인터럽트를 발생시키는 것이 불가능하다.

 

 

 프리스케일러(Pre-scaler)는 이러한 고속의 클럭을 사용할 때 나타나는 한계를 해결하기 위해, 클럭을 나눠 더 느린 클럭을 생성하는 장치다. 즉, 이전의 클럭 주파수 혹은 주기에 분주비를 나눠 클럭의 속도를 조절하는 것이다. 위의 그래프에서 분주비를 크게 할 때마다 클럭의 주기가 늘어지는 것을 확인할 수 있다. 이를 수식으로 나타내면 다음과 같다.

 

 

 

 만약 16Mhz를 사용하고 있고, 분주비로 2를 사용하면 16Mhz/2 = 8Mhz로 주파수가 클럭 주파수는 절반으로 줄어들고, 클럭 주기는 0.0625us * 2 = 0.125us로 늘어진다. 이렇게 10비트 프리스케일러에 적당한 분주비를 넣어서 클럭 주기를 생성하고, 이 클럭 주기를 8비트 카운트 횟수를 곱해서 원하는 시간으로 맞추는 것이 프리스케일러의 핵심이다. 

 

 

 다음은 10비트 프리스케일러의 분주비에 따른 클럭 주기와 최대 주기(클럭 주기 * 8비트)다. 이를 이용하여 타이머의 주기를 계산하려면 다음과 같은 수식을 이용하면 된다.

 

 

 여기서 TCNT는 Timer Counter의 약자로, 다음 시간에 관련 레지스터들과 함께 설명하겠다.

 

반응형