Miobot's Story

AVR 기초 강좌

4. ATmega128의 기능 및 제어 3


ATmega128's function (Timer/Counter)

2013.01.01

 1. 타이머 / 카운터


ATmega128는4개의 타이머/카운터로 구성되어있으며, 이중 타이머/카운터0은8비트 구조로서 카운터로 이용될 때 타이머카운터0의 카운터입력이 TOC1과 0으로 받아 RTC기능을 가지는 것을 제외하고는 타이머/카운터2와 기능이 같으며 타이머카운터1은16비트 구조로서 타이머/카운터3과 기능이 같다.
 
(1) 타이머/카운터란?
: 타이머/카운터를 흔히 통칭해서 부르며 같은 기능이라고 생각하고 사용하지만 세분하여 볼 때는 타이머와 카운터는 엄연히 틀린 기능을 말하는 것을 알아 두어야 한다.

타이머/카운터 = 손목시계
인간은 흔히, 시간에 묶여산다고 한다.. 손목에 찬 시계를 항상 보며, 12시에 점심 식사를 하고, 정해진 시간에 퇴근하고, 잠을 잔다. 마이크로프로세서는 더욱이 실시간 응답성을 요구하는 물건이라, 인간보다 더욱 시간 개념이 철저한다. 이러한 시간을 재고, 정해진 시간내에 작업을 수행하는 기능을 가지고 타이머 / 카운터 기능이라고 한다.
① 타이머는MCU의 내부클럭(clkI/O>분주기>clkT)을 이용하여 일정시간 간격의 펄스를 만들어 내거나 일정시간 경과 후에 인터럽트를 발생시키는 기능을 말한다.

② 카운터는 외부 핀(TOSC1, TOSC2, T1, T2, T3)을 통해서 들어오는 펄스를 계수(Edge Detector)하여Event Counter로서 동작되는 것을 말한다. (펄스=사건, 카운터값=사건의 횟수)
  

 


이렇게 타이머와 카운터는 입력 받는 소스가 틀리면서 원리적인 차이가 있지만 그 사용 목적과 결과는 같은 이유로 혼용되어 부르며 사용되고 있다.

 



 2. 타이머/카운트0, 2 제어


타이머/카운터0과2는8비트 구조로서 OVERFLOW, PWM 비슷한 기능을 가지고 제어방식도 비슷하다. 차이점이 있다면 타이머/카운터0 은32.768kHz의 크리스탈을 접속하는TOSC1 및TOSC2 단자를 가지고 있어서RTC의 기능을 갖도록 할 수 있으며 다른 타이머/카운터와는 틀리게 내부 클럭을 사용하든 외부의 클럭을 사용하든 모두 프리스케일러의 분주기능을 사용할 수 있다는 것이다.

 

 


(1) 타이머/카운터0, 2의 특징
- 8비트( 0x00 ~ 0xff ) 구조
- 10비트(0x000 ~ 0x3ff) 프리스케일러
- Overflow와Output Compare Match 인터럽트
- Output Compare Match 할 때 타이머가 클리어 된다.(CTC모드)
- 타이머/카운터0의 경우 다른 타이머/카운터와는 색다른 기능을 가진다.
> RTC기능
> 타이머와 카운터 모두 프리스케일러를 사용
> I/O 클럭과 독립된 외부32.768kHz 크리스탈에 동작가능
 
(2) 타이머/카운터0, 2의 블록도
- 내/외부 클럭 중 하나를 선택하여 기준 클럭으로 삼는다.
- 타이머/카운터0, 2은0x00~0Xff까지Count하여Overflow되면OVF 인터럽트가 걸린다.
- 타이머/카운터0, 2은0x00~0Xff까지Count하다가 지속적으로TCNT값과OCR값을 비교하여 같으면COMP 인터럽트가 걸린다.
- 타이머/카운터0, 2은 동작을 알기 위해서는 아래의 그림들을 필히 이해해야 된다.

 

 

 

※용어설명
- BOTTOM : 카운터가 가질 수 있는 최소값0x00을 나타낸다.
- MAX : 카운터가 가질 수 있는 최대값0xff를 나타낸다.
- TOP : 각 동작모드에 따라 카운터가 실제로 도달하는 최대값을 나타낸다. (CTC모드의 경우TOP=OCR)
- COUNT : TCNT0의1씩 증가 또는 감소하는 것
- DIRECTION : COUNT의 증감/ 감소 설정
- CLEAR : Clear TCNTO
- CLKTO: 타이머/카운터 클럭


(3) 타이머/카운터0 관련 레지스터
타이머/카운터0을 제어하기 위해서는 상태레지스터(SREG)와 타이머/카운터0 관련 레지스터(TIMSK, TIFR, TCCR0, TCNT0, OCR0, ASSR, SFIOR)의 사용법을 알아야 한다.
 
① TIMSK(Timer/Counter Interrupt Mask Register)
: 타이머/카운터 0~2 에서 발생하는 인터럽트를 개별적으로 허용하는 기능을 수행하는 레지스터

 

•Bit 1 – OCIE0(Timer/Counter0 Output Compare Match Interrupt Enable)
▪ OCIE0 = 1 : Output Compare Match Interrupt 활성화
(COMP인터럽트를 사용하려면SREG의I=1인 상태여야 한다.)

•Bit 0 – TOIE0(Timer/Counter0 Overflow Interrupt Enable)
▪ TOIE0 = 1 : Overflow Interrupt 활성화
(OVF인터럽트를 사용하려면SREG의I=1인 상태여야 한다.)


② TIFR(Timer/Counter Interrupt Flag Register)

•Bit 1 – OCF0(Output Compare Match Flag)
▪OCF0 = 1 : TCNT0 = OCR0 경우1로Set되면서 출력비교 인터럽트가 요청된다.
(이 비트는 인터럽트 처리의 시작과 함께0으로Clear된다.)

•Bit 0 – TOV0(Timer/Counter0 Overflow Flag)
▪TOV0 = 1: Overflow가 발생되면1로Set되면서 출력비교 인터럽트가 요청된다.
(이 비트는 인터럽트 처리의 시작과 함께0으로Clear된다.)


③ TCCR0(Timer/Counter Control Register 0) : 동작모드설정/ 분주비 설정 등

•Bit 7 – FOC0(Force Output Compare)
▪ 강제로OSC0 단자에 출력비교 매치 신호를 출력
 
•Bit 3,6 – WGM01, WGM00 (Waveform Generation Mode) : 파형 출력 모드

 


•Bit 5,4 – COM01, COM00(Compare Match Output Mode) : 비교매치 출력 모드


Mode

COM01

COM00

설명

PWM모드가 아닌 경우

(<st1:place w:st="on"><st1:city w:st="on">Normal</st1:city></st1:place>/ CTC)

0

0

범용 입출력포트(OC0 출력 차단)

0

1

비교매치 →OC0 Toggle 출력

1

0

비교매치 →OC0 = 0 출력

1

1

비교매치 →OC0 = 1 출력

 

Mode

COM01

COM00

설명

FAST PWM

0

0

범용 입출력포트(OC0 출력 차단)

0

1

(reserved)

1

0

비교매치 →OC0 = 0 출력

오버플로우 →OC0 = 1 출력

1

1

비교매치 →OC0 = 1 출력

오버플로우 →OC0 = 0 출력

 

Mode

COM01

COM00

설명

Phase Correct

PWM

0

0

범용 입출력포트(OC0 출력 차단)

0

1

(reserved)

1

0

상향카운터 비교매치 →OC0 = 0 출력

하향카운터 비교매치 →OC0 = 1 출력

1

1

상향카운터 비교매치 →OC0 = 1 출력

하향카운터 비교매치 →OC0 = 0 출력

 

•Bit 2,1,0 – CS02~00(Clock Select)

 



④ TCNT0(Timer/Counter Register 0)

 

• 타이머/카운터0의 8비트 카운터 값을 저장하고 있는 레지스터
• 타이머/카운터0의 자동으로 값이 갱신된다.
 
 
⑤ OCR0(Timer/Counter Output Compare Register 0)


 

• 타이머/카운터0의 카운터 값인TCNT0과 비교하여OC0 단자에 출력신호를 발생하기 위한8비트 값을 저장하고 있는 레지스터
• 사용자가 설정해야 하는 값이다.
 
  
⑥ ASSR(Asynchronous Status Register)
: 타이머/카운터0의 외부클럭에 의하여 비동기 모드로 동작하는 경우에 관련된 기능 수행


 

•Bit 3 – AS0(Asynchronous Timer/Counter0)
▪AS0 = 0  : 내부클럭(ClkI/O)   동기모드
▪AS0 = 1  : 외부클럭(TOSC1)   비동기모드
 
•Bit 2– TCN0UB(Timer/Counter0 Update Busy)
 
•Bit 1– OCR0UB(Output Compare Register0 Update Busy)
 
•Bit 0– TCR0UB(Timer/Counter Control Register0 Update Busy)
 
 
⑦ SFIOR(Special Function I/O Register)


 

•Bit 7 – TSM(Timer/Counter Synchronization Mode)
▪ 모든 타이머/카운터들을 동기화시키는 기능을 수행한다.
 
•Bit 1 – PSR0(Prescaler Reset Timer/Counter0
▪ 타이머/카운터0의 프리스케일러를 리셋 시키며 동작 후에 자동적으로 클리어 된다.
 
  
(4) 타이머/카운터0 의 동작

① Normal Mode
▪ 일반적인 타이머 오버플로우 인터럽트가 필요할 때 사용
▪ 상향카운터
▪ 0x00 ~ 0xFF 계수동작 반복
▪ 카운트 도중Clear 없음
▪ 오버플로우(OVF) 인터럽트(MAX=0xFF값일 때 발생)
▪ 비교매치(COMP) 인터럽트(파형을 예상하지 못하기 때문에 추천하지 않음)
 
② CTC Mode(Compare Timer on Compare Match Mode)
▪ 주파수 분주 기능으로 주로 사용
▪ 상향카운터
▪ 0x00 ~ OCR0 계수 동작 반복
▪ OCR0값과TCNT0값이 같으면 카운트 도중Clear
▪ 오버플로우(OVF) 인터럽트
▪ (MAX=OCR0값일 때 발생, COMP인터럽트와 동일하게 작동되기 때문에 추천하지 않음)
▪ 비교매치(COMP) 인터럽트

 


③ FAST PWM
▪ 높은 주파수PWM 파형발생이 필요할 때 사용
▪ 상향카운터(Single-Slope Operation)
▪ 0x00 ~ 0xFF 계수 동작 반복
▪ TCNT0과OCR0의Compare Match되면OC0에LOW출력(COM0 1:0 = 2)
▪ 0xFF →0x00 오버플로우 되면OC0에HIGH출력(COM0 1:0 = 2)


 


④ Phase Correct PWM
▪ 높은 분해능의PWM출력 파형을 발생하는데 사용
▪ 상향카운터0x00 →0xFF
▪ 하향카운터0xFF →0x00
▪ 0x00 ~ 0xFF ~ 0x00 계수 동작 반복
▪ 상향카운터 비교매치 →OC0 = 0 출력(COM0 1:0 = 2)
▪ 하향카운터 비교매치 →OC0 = 1 출력(COM0 1:0 = 2)

 



 3. 타이머/카운트0 제어 실습



[Example 01]
: 아래의 내용은 타이머/카운터0을 이용하여LED가1초마다 ON/OFF 시키는 프로그램이다.

#include "iom128.h"
 
#define sbi(PORTX , BitX)   PORTX |=  (1 << BitX)   // 비트SET 명령정의
#define cbi(PORTX , BitX)   PORTX &= ~(1 << BitX)   // 비트CLEAR 명령정의
 
unsigned char count= 0;
 
#pragma vector=TIMER0_OVF_vect          // 타이머0 Overflow 인터럽트처리루틴
__interrupt void OVF_Interrupt(void)    // 8ms마다인터럽트루틴실행
{
    count++;

    if(count==125)          // 8ms*125=1sec
    {
        if(PINA==0x00)
        {
            PORTA= (0xFF);  // 1111 1111 (LED 전등)
        }             
        else if(PINA==0xFF)
        {
            PORTA= (0x00);  // 0000 0000 (LED 전멸)
        }             
        count = 0;
    }
    TCNT0= 131;             // 125 = 255-TCNT0+1
}
 
void Main_Init(void);
 
int main(void)
{
    Main_Init();
    while(1);
}
void Main_Init(void)
{
    cbi(SREG,7);        // 모든인터럽트비활성화
    PORTA   = 0xFF;     // 포트A 값초기화
    DDRA    = 0xFF;     // 포트A 출력으로설정
    TCCR0   = 0x07;     // 1024분주설정(clkt=16000000/1024=15625Hz)
    TCNT0   = 131;      // 1/clkt0 = 64us, 64us*125=8ms
    TIMSK   = 0x01;     // overflow 인터럽트인에이블
    sbi(SREG,7);        // 모든인터럽트활성화
}


[Example 02]
: 아래의 내용은 타이머/카운터 0을 이용하여 OC0핀에 PWM을 0/25/50/75/100% 듀티비를 나타내는 프로그램이다.

#include "iom128.h"
 
#define sbi(PORTX , BitX)   PORTX |=  (1 << BitX)   // 비트 SET 명령 정의
#define cbi(PORTX , BitX)   PORTX &= ~(1 << BitX)   // 비트 CLEAR 명령 정의
 
void Main_Init(void);           // 초기화 함수 선언
void delay(long time);          // 딜레이 함수 선언
 
int main(void)
{      
    Main_Init();
    while(1)
    {
        OCR0=0;        delay(10000000); // 0%듀티비
        OCR0=64;       delay(10000000); // 25%듀티비
        OCR0=128;      delay(10000000); // 50%듀티비
        OCR0=191;      delay(10000000); // 75%듀티비
        OCR0=255;      delay(10000000); // 100%듀티비
    }
}
void Main_Init(void)
{
    cbi(SREG,7);        // 모든 인터럽트 비활성화
    PORTA   = 0xFF;     // 포트A 값 초기화
    DDRA    = 0xFF;     // 포트A 출력으로 설정
    PORTB   = 0xFF;     // 포트B 값 초기화
    DDRB    = 0xFF;     // 포트B 출력으로 설정
    TCCR0   = 0x67;     // 1024분주설정(clkt=16000000/1024=15625Hz )
                        // Phase Correct PWM모드, COM0100=10설정
    TCNT0   = 0x00;     // 1/clkt0 = 64us, 64us*256=16.384ms
    OCR0    = 0x00;     // 0%듀티비
    TIMSK   = 0x02;     // COMP 인터럽트 인에이블
    sbi(SREG,7);        // 모든 인터럽트 인에이블
}
 
void delay(long time)   // 딜레이 함수 정의
{
    while(time--);
}



 [ 참고자료 ]


[1] Atmel Corporation, ATmega128(L) Datasheet, http://www.atmel.com/devices/ATMEGA128.aspx?tab=documents


End.

written by Yoonseok Pyo
http://robotpilot.net/
http://cafe.naver.com/openrt


Posted by Miobot