용어 정의
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 => 소수점이 있음..
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 |
'AVR > Atmega128 강좌' 카테고리의 다른 글
Atmega128 기초 - 8비트 타이머/카운터 Phase Correct PWM 모드 (0) | 2016.06.21 |
---|---|
Atmega128 기초 - 8비트 타이머/카운터 Fast PWM 모드 (7) | 2016.06.21 |
Atmega128 기초 - 8비트 타이머/카운터 일반모드 (2) | 2016.06.17 |
Atmega128 기초 - 외부 인터럽트 (0) | 2016.06.16 |
ATmega128 기초 - 입출력 포트 (2) | 2016.06.15 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!