용어 정의
BOTTOM - 카운터가 0이 되었을 때를 의미.
MAX – 카운터가 0xFF(=255)에 도달했을 때를 의미
TOP
TOP값은 0xFF(MAX) 또는 OCR0 레지스터에 저장된 값으로 지정할 수 있다.
카운터가 TOP값과 똑같거나 더 커진 경우를 의미한다.
일반 모드
TCCR0 레지스터의 WGM00 비트와 WGM01 비트가 0으로 설정된 경우이다.
TCNT0 레지스터는 카운터에서 값을 직접 읽거나 쓸 수 있게 해주는 레지스터이다.
일반 모드에서 카운팅은 항상 증가하는 방향으로 이루어 진다.
8비트로 표현할 수 있는 최대값인 0xFF(=255)를 초과하면 다시 bottom(=0)부터 카운팅을 시작한다. TCNT0가 0이 되는 순간 TIFR 레지스터의 TOV0 비트가 1로 설정된다.
타이머/카운터 오버플로우 인터럽트와 같이 사용되면, TIFR 레지스터의 TOV0 플래그 비트는 자동으로 0으로 클리어된다.
TIMSK 레지스터의 TOIE0 비트가 1로 설정되고 Status 레지스터의 I비트가 1로 설정되었을 때 타이머/카운터0 오버플로우 인터럽트가 활성화된다.
프리스케일러 선택은 TCCR0레지스터의 CS02, CS01, CS00 비트에 의해서 결정된다.
아래처럼 회로를 구성하고 프로그램 코드를 테스트한다.
사용중인 크리스탈의 값 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마다 오버플로우 인터럽트가 발생하도록 설정해놓았다.
프르스케일러로 64를 사용하게 되며 TCNT0의 시작값은 256-249인 7이 된다.
249는 위에서 계산한 결과 값이다.
따라서 total_overflow_count값이 1000이 될때마다 1초가 되므로
LED는 1초가 될 때마다 켜지게 된다..
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 | /* * 8bit_timer_example.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_overflow_count; ISR(TIMER0_OVF_vect) { total_overflow_count++; TCNT0 = 7; } int main(void) { DDRB |= (1<<DDB3); //LED용 //프리스케일러로 64를 선택 TCCR0 |= (1<<CS02); //카운터 초기화 256-249 TCNT0 = 7; //타이머/카운터 오버플로우 인터럽트 활성화 TIMSK |= (1<<TOIE0); //전역 인터럽트 활성화 sei(); total_overflow_count = 0; /* Replace with your application code */ while (1) { if ( total_overflow_count == 1000 ) //1초마다 LED 켜짐 { total_overflow_count = 0; PORTB |= (1<<PB3); _delay_ms(10); } else PORTB &= (~(1<<PB3)); } } | cs |
'AVR > Atmega128 강좌' 카테고리의 다른 글
Atmega128 기초 - 8비트 타이머/카운터 Fast PWM 모드 (7) | 2016.06.21 |
---|---|
Atmega128 기초 - 8비트 타이머/카운터 CTC 모드 (0) | 2016.06.18 |
Atmega128 기초 - 외부 인터럽트 (0) | 2016.06.16 |
ATmega128 기초 - 입출력 포트 (2) | 2016.06.15 |
USB To TTL 컨버터 모듈 사용기 ( Atmega328p 자작 보드에 연결 ) (2) | 2015.12.07 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!