[카운트다운 타이머] 올해는 얼마나 남았을까?

 

문득 올해는 과연 얼마나 남았을까 궁금할 때가 있다.

개발 자체는 몇 년 전에 했었지만, 이번에 블로그에 다시 올려본다.

남은 초와 시간, 그리고 %로 올해가 얼마나 남았는지 확인해보자.

참고로 이 포스팅을 올렸을때는 이미 2019년은 50%도 남지 않았다...

 

 

##타이머

ATMega 128에서는 4개의 타이머가 존재한다.

각 타이머는 0, 1, 2, 3과 같은 번호를 가지고 있으며, 이 번호는 나중에 레지스터를 할당할 때 사용된다. (ex, TCCR0)

이 중 0, 2번 타이머는 8비트 타이머이고 ATMega 128기준 7372800Hz를 갖는다.

그리고 나머지 1, 3번 타이머는 16비트 타이머이다.


타이머는 보통 세개~네개 정도의 레지스터만 선언해주면 사용이 가능하다. (interrupt 헤더파일은 선언해 주어야 한다.)


TCNTn(Timer/CouNTer register)

 이름에서 보이듯이 직접 타이머를 카운트하는 레지스터이다. 0~255의 값을 가질 수 있으며 만약 이 값을 우리가 임의대로 수정하면, 이후 타이머는 수정된 값 이후부터 더하고, 초기화 되어도 수정된 값으로 초기화가 된다.


OCRn (Timer/Counter Output Compare register n)

 아래에서 설명할 CTC모드와 고속 PWM 모드에서 사용되는 레지스터. 0~255사이의 값을 가지며 타이머의 속도를 조절할 수 있는 역할을 한다.


TCCRn(Timer/Counter Control Register n)

 사실상 타이머를 사용하는데 가장 중요한 레지스터이다.

 구조는 8비트로 | FOCn | WGMn1 | WGMn0 | COMn1 | COMn0 | CSn2 | CSn1 | CSn0 | 이며,

 FOCn(Force Output Compare n)과 COMn0, COMn1(Compare match Output Mode n)은 고급 제어에서 이용되며, 가장 단순하게 타이머 용도로만 사용할 정도면 WGM과 CS만 이해하여도 크게 문제가 없다.

 따라서 이번 포스팅에서는 WGM과 CS에 대해서만 설명한다.

 1) WGMn1 WGMn0 (Waveform Generation Mode n)

WGM의 경우 CS와 다르게 그 위치가 8비트 상에서 연속되어 있지 않으므로, 정확한 위치 확인이 필요하다.

아래 진리표의 경우 WGMn1 WGMn0 순으로 작성된 것으로, 실제 레지스터에 적용시에는 그 구조를 파악하여 정확히 써주어야 한다.

0 0 : 일반 (0~255->0~255) => TCNT레지스터의 값이 0부터 255까지 차례로 증가한 뒤 TOV라는 레지스터로 값이 다 찼다는 결과를 주고 다시 0으로         초기화 된 뒤 255까지 다시 올라가는 방식이다.

0 1 : 위상정정 PWM(Pulse Width Modulation) (0~255~0~255) => TCNT레지스터의 값이 0부터 255까지 차례로 증가한 뒤 일반 모드와는 다르게         바로 0으로 초기화 되는 것이 아니라, 0까지 값을 하나씩 줄여가는 방식이다. 0으로 줄은 상태에서 TOV값이 리턴된다. 물론 0이 되면 다시 값이         1씩 증가한다.

1 0 : CTC(Compare Timer on Compare match) (0~OCRn->0~OCRn) => 다른 방식들과는 다르게 0부터 OCRn 레지스터에 저장된 값까지만 증가하고,         OCRn(Timer/Counter Output Compare register n)레지스터 값과 TCNT레지스터의 값이 동일해지면 TOV를 반환하고 0으로 다시 초기화 된다.

1 1 : 고속 PWM (0~255->0~255) => TCNT레지스터의 값이 0부터 255까지 차례로 증가한 뒤 TOV라는 레지스터로 값이 다 찼다는 결과를 주고 다시         0으로 초기화 된 뒤 255까지 다시 올라가는 방식이다. 일반 모드와 다르게 고속 PWM은 0부터 255까지 증가하지만 OCRn값이 있다면, 그         시기에 즉시 OCn(Output Compare n)값을 리턴한다.

 2) CSn2 CSn1 CSn0 (Clock Select)

프리스케일러(free scaler)라고도 불리며, 분주기라고도 불린다. 이 세 비트의 상태에 따라서 한 클럭마다 신호를 발생할 것인지, 아니면 그것보다 낮은 클럭으로 신호를 발생할 것인지 선택이 가능하다.

0 0 0 : 정지

0 0 1 : 7372800(클럭상태)

0 1 0 : 7372800/8 = 921600(921600클럭으로 돌아가는 것과 같은 상태)

0 1 1 : 7372800/32

1 0 0 : /64

1 0 1 : /128

1 1 0 : /256

1 1 1 : /1024 => 약 71ms로 동작


TIMSK(Timer/Counter Interrupt MaSK register)

 TIMSK = 0x01;로 선언하면 overflow 인터럽트를 Enable한다.


TIFR(Timer/Counter Interrupt Flag Register)

 TOV 발생 시에 기록하는 레지스터.

 TIFR = 0xFF;로 선언하면 첫 인터럽트 시작이 0이 된다.


Sei(); <= 인터럽트 인에이블 함수


SIGNAL(SIG_OVERFLOW0) <= 타임 인터럽트 서비스 루틴


SIGNAL(SIG_OUTPUT_COMPARE0) <= OCR모드일 때 인터럽트 서비스 루틴



* 타이머 조작

1) TCNT를 직접 설정하는 방법 : 한번 설정 시 TCNT부터 255까지 증가

2) 프리스케일러 조작

3) CTC모드로 조작 : OCRn 설정시 0부터 OCRn까지 증가

+ Recent posts