2007. 2. 27. 17:41

ATmega128은 다음과 같은 4개의 범용 타이머/카운터가 있다.
Timer/Counter0(8비트), Timer/Counter1(16비트), Timer/Counter2(8비트), Timer/Counter3(16비트)가 있다.


타이머/카운터의 제어에 필요한 레지스터는
- 타이머/카운터 제어 레지스터(TCCRn),
- 타이머/카운터 레지스터(TCNTn),
- 출력 비교 레지스터(OCRn)가 있으며,

인터럽트 관련하여
-타이머/카운터 인터럽트 플래그 레지스터(TIFR),
-타이머/카운터 인터럽트 마스크 레지스터(TIMSK)가 있다.

타이머를 사용하기 위해서는 타이머에서 사용하는 클럭에 대해서 설정을 해야 하는데 이는 프리스케일러(Prescaler) 값으로 조절할 수 있다.
프리스케일러 값은 각 타이머의 컨트롤 레지스터(TCCRn)에서 설정할 수가 있다.

타이머 인터럽트는 각 타이머 관련 컨트롤 레지스터에서 적절한 프리스케일러 값을 설정한 후 , 각 타이머 레지스터(TCNTn)에 얼마마다 한번씩 인터럽트를 걸게 할 것인지와 관련된 값을 써주면 된다.

그리고 인터럽트를 사용해야 하므로 타이머 인터럽트 관련 레지스터들을 설정해야 한다. 타이머 인터럽트에서는 TIMSK 레지스터만 설정하면 된다.


프로그램 예제
1msec마다 발생하는 타이머 오버플로 인터럽트를 이용하여, 변수값이 1씩 증가하도록 설정하여 포트 A로 카운트된 값을 출력하는 프로그램

#include <iom128.h>
#include <ina90.h>
#include <sig-avr.h>
#include <interrupt.h>

#define   SYSTEM_CLOCK  16000000   // CLOCK (X-tal frequency)

volatile int Count = 0;

SIGNAL(SIG_OVERFLOW0)
{
     outp(0x83, TCNT0);
     outp(Count, PORTA);
     Count++;
     if (Count > 255)Count= 0;
}

void Port_Init(void)

     outp(0xFF, DDRA);    //Port_A setting up output
}

void Timer_Init(void)
{                // Timer0 setting, 1ms 
                 // system_clk/Presclae = divide_clk
                 // 1/divide_clk = divide_time
                 // 1ms/divide_time = n
                 // 256 - n = TCNT0

     outp(0x05, TCCR0);      // Clock Source = System clock/128
     outp(0x83, TCNT0);
     outp(0x01, TIMSK);      // Timer 0 overflow enable
}

int main(void)
{
     outp(0x00, MCUCR);    // External Memory Disable
     Port_Init();
     Timer_Init();
     sei();
     while(1)
        {
         }
     return 0;
}

Posted by Paul Hwang