반응형

용어 정의

BOTTOM - 카운터가 0이 되었을 때를 의미.

MAX – 카운터가 0xFF(=255)에 도달했을 때를 의미

TOP 

TOP값은 0xFF(MAX) 또는 OCR0 레지스터에 저장된 값으로 지정할 수 있다.

카운터가 TOP값과 똑같거나 더 커진 경우를 의미한다.


Clear Timer on Compare Match (CTC) 모드


TCCR0 레지스터의 WGM00 비트가 0이고 WGM01 비트가 1로 설정된 경우이다.



TCNT0 레지스터는 카운터에서 값을 직접 읽거나 쓸 수 있게 해주는 레지스터이다.



OCR0 레지스터에는 카운터 값인 TCNT0 레지스터와 비교할 때 사용되어 지는 8비트 값이 포함되어 있다. OCR0 레지스터의 값과 TCNT0 레지스터의 값이 일치하면 Output Compare Interrupt가 발생하며 카운터 값이 0으로 클리어된다. 그리고 OC0 핀으로 파형이 출력된다.



OCR0 레지스터에는 카운터를 위한 TOP값을 정의한다.

카운터 값(TCNT0)은 OCR0와 일치할 때까지 계속 증가하다가 일치되는 순간 0으로 클리어된다.


카운터의 값(TCNT0)가 TOP값(OCR0)에 도달할 때마다, TIFR레지스터의 OCF0비트는 1로 설정되면서 인터럽트가 발생한다.  그리고 해당되는 인터럽트 핸들러 벡터(루틴)가 실행될 때 하드웨어에 의해서 OCF0는 0으로 클리어된다.


인터럽트 핸들러 루틴에서 TOP값(OCR0)를 변경할 수 있다. 그러나 현재 카운터값(TCNT0)보다 낮은 값을 TOP값(OCR0)으로 설정하면 compare match를 놓칠 수 있으니 주의해야 한다. 이후 카운터는 최대값인 0xFF까지 증가했다가 다시 0x00부터 시작하게 되는데 이 기간동안 compare match를 놓치게 된다는 것이다.


TIMSK레지스터의 OCIE0 비트가 1로 설정되고 Status Register의 I비트가 1로 설정되어야 타이머/카운터0 Compare Match 인터럽트가 활성화 된다.



아래처럼 회로를 구성하고 프로그램 코드를 테스트한다. 



사용중인 크리스탈의 값 F_CPU = 16Mhz이고 8비트 타이머(최대값 255)를 사용한다면 만들 수 있는 최소 딜레이값은 0.016ms이다. 계산과정은 다음과 같다.


주기 = 1/주파수 = 1/16000000 Hz = 0.0000000625 s = 0.0000625 ms


타이머 카운터 = 필요한 딜레이 시간 / 클록 시간 주기 – 1

255 = X / 0.0000625 ms – 1

X = 256 * 0.0000625 ms = 0.016 ms



1 ms를 만들고 싶다면... 위에서 계산한 순서대로 계산해보면 된다.


F_CPU 그대로 사용한다면

16MHz => 0.0000625 ms

1ms/0.0000625ms –1 = 15999=> 8비트 표현 범위를 넘어섬..


프리스케일러로 8을 사용한다면

16MHz / 8 = 16000000/8 = 2000000Hz => 0.0000005 s = 0.0005ms

1ms/0.0005ms –1 = 1999 => 8비트 표현 범위를 넘어섬..


프리스케일러 64를 사용한다면

16Mhz / 64 = 16000000/64 = 250000Hz => 0.000004 s = 0.004ms

1ms/0.004ms –1 = 249 => 8비트 카운터로 사용가능


프리스케일러 256을 사용한다면

16Mhz / 256 = 16000000/256 = 62500Hz => 0.000016 s = 0.016ms

1ms/0.016ms-1=61.5 => 소수점이 있음


프리스케일러 1024를 사용한다면...

16Mhz / 1024 = 16000000/1024 = 15625Hz => 0.000064 s = 0.064ms

1ms/0.064ms-1=14.625 => 소수점이 있음..



위 계산 결과를 이용하여 1ms마다 타이머 Compare Match 인터럽트가 발생하게 해놓았다.
프리스케일러로 64를 사용하며 OCR0의 값은 249가 된다.

이를 바탕으로 1초마다 LED가 깜빡이게 했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
 * 8bit_timer_example2_ctc.c
 *
 * Created: 2016-06-17 
 * Author : webnautes
 */ 
 
#define F_CPU 16000000UL
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
 
volatile uint16_t total_count;
 
 
ISR(TIMER0_COMP_vect)
{
    //카운터 초기화
    total_count++;
}
 
int main(void)
{
    DDRB |= (1<<DDB3); //LED용
 
    //프리스케일러로 64를 선택
    TCCR0 |= (1<<CS02);
 
    //CTC 모드 
    TCCR0 |= (1<<WGM01);
 
    //카운터 초기화
    TCNT0 = 0;
 
    //TOP 정의
    OCR0 = 249;
 
 
    //타이머/카운터0 Compare Match 인터럽트 활성화
    TIMSK |= (1<<OCIE0);
 
    //전역 인터럽트 활성화
    sei();
 
    total_count = 0;
 
 
    /* Replace with your application code */
    while (1
    {
        if ( total_count == 1000 ) //1초마다 LED 켜짐
        {
            total_count = 0;
            PORTB |= (1<<PB3);
            _delay_ms(10);
        }
        else PORTB &= (~(1<<PB3));
 
            
    }
}
 
 
 
 
cs


문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts