임베디드 마이크로프로세서 프로그래밍 실전 제작 : 네 로 테 크 강의 : 김 종 형
Embedded AVR Programming
ATMEGA128 타이머/카운터0
1. 2. 3.
20062006-0404-03
-2-
타이머/카운터의 개요 타이머/카운터 0 타이머/카운터 0 실습
Embedded AVR Programming
1-1 타이머/카운터의 개요 ⊙ ATmega128은 4개의 타이머/카운터를 구성 - 타이머/카운터0, 2 는 8비트 구조이며 타이머/카운터1, 3은 16비트 구조 ⊙ 타이머/카운터0는 32.768kHz를 사용하는 TOSC1, TOSC2단자를 가지며 RTC의 기능 가짐 ⊙ 타이머/카운터0는 내부클럭 혹은 외부클럭을 사용시 프리스케일러의 적용 ⊙ 타이머/카운터1~3은 내부 클럭을 사용하는 타이머에 대해서 프리스케일러가 동작 ⊙ 모두 인터럽트 및 PWM 출력 기능을 가짐 - 오버플로우 인터럽트(overflow interrupt) : 카운터의 값이 오버플로우되는 경우 발생 - 출력비교 인터럽트(output compare match interrupt) : 카운터 값이 출력비교 레지스터의 값과 같게 되는 순간에 발생 - 입력캡쳐 인터럽트(input capture interrupt) - PWM : 출력비교 기능을 이용하여 출력비교 신호에 주기와 듀티비를 가변할 수 있는 출력 신호를 발생(OC0, OC1A/OC1B/OC1C, OC2, OC3A/OC3B/OC3C)
20062006-0404-03
-3-
Embedded AVR Programming
1-2 타이머/카운터 0 ⊙ 0에서 255까지 셀 수 있는 8비트 타이머/카운터 ⊙ 타이머로 사용될 때는 내부 클럭을 분주하여 이용 ⊙ 외부에 32.768kHz 클럭을 TOSC1, TOSC2단자에 연결하여 RTC를 구현 ⊙ 8비트 PWM 신호를 만들어서 포트로 출력
20062006-0404-03
-4-
Embedded AVR Programming
1-2 타이머/카운터 0 ⊙ 타이머/카운터0 제어 레지스터(TCCR0) : 타이머/카운터0의 동작 모드를 설정하고 프리스케일러의 분주비를 설정 BIT
7
6
5
4
3
2
1
0
$33($53)
FOC0
WGM00
COM01
COM00
WGM01
CS02
CS01
CS00
Value
0
0
0
0
0
0
0
0
- FOC0(Force Output Compare) : 1로 설정시 강제로 즉시 OC0 단자에 출력비교가 매치 된 것과 같은 출력을 내보냄, 출력신호의 동작은 COM01~00 비트에 의해 결정 - CS02 ~ CS00 : PRESCALER 설정
20062006-0404-03
클럭 소스의 기능
CS02
CS01
CS00
0
0
0
클럭 입력을 차단(타이머/카운터0의 기능이 정지됨)
0
0
1
clkTOS / 1
0
1
0
clkTOS / 8
0
1
1
clkTOS / 32
1
0
0
clkTOS / 64
1
0
1
clkTOS / 128
1
1
0
clkTOS / 256
1
1
1
clkTOS / 1024 -5-
Embedded AVR Programming
1-2 타이머/카운터 0 ⊙ 타이머/카운터0 제어 레지스터(TCCR0) - WGM00 ~ WGM01 : Waveform Generation Mode로써 카운터의 동작순서를 설정하여 어떤 파형을 발생하는지를 결정 1) Normal Mode : 타이머 카운터가 255까지 세고 난 뒤 인터럽트를 발생 2) CTC(Clear Timer on Compare match) Mode : 최대로 세는 수를 변화시킴 즉, 255까지 다 세지 않고 100까지만 세고 인터럽트를 발생시키게 한다든가 하는 것 3) Fast PWM Mode : 255까지 다 세기 전에 인터럽트를 발생시키게 할 수 있음 즉, 255다 세기 전에 한번 255다 센 후에 한번..이렇게 인터럽트가 두 번 발생 가능 4) PCPWM(Phase Correct Pulse Width Modulation) Mode : PWM 과 유사하나 255~0으로 숫자가 줄어들면서 셈
20062006-0404-03
모드
WGM01 (옛 CTC0)
WGM00 (옛 PWM0)
동작모드
TOP
OCR0 레지스터 의 업데이트 시점
TOV0 플래그의 셋트 시점
0
0
0
Normal
0xFF
설정 즉시
MAX
1
0
1
Phase Correct PWM
0xFF
TOP
BOTTOM
2
1
0
CTC
OCR0
설정 즉시
MAX
3
1
1
Past PWM
0xFF
TOP
MAX
-6-
Embedded AVR Programming
1-2 타이머/카운터 0 ⊙ 타이머/카운터0 제어 레지스터(TCCR0) - COM01 ~ 00 : Compare Match Output Mode로서 OC0 단자에 출력 비교 매치
20062006-0404-03
-7-
Embedded AVR Programming
1-2 타이머/카운터 0 ⊙ 타이머/카운터0 레지스터 (TCNT0) : 타이머/카운터0의 8비트 카운터값을 저장 BIT
7
6
5
4
$32($52) Value
3
2
1
0
0
0
0
TCNT0[7..0] 0
0
0
0
0
⊙ 타이머/카운터0 출력비교 레지스터(OCR0) : TCNT0 값과 비교하여 OC0 단자에 출력신호를 발생하기 위한 8비트 값을 저장 BIT
7
6
5
4
$31($51) Value
3
2
1
0
0
0
0
OCR0[7..0] 0
0
0
0
0
⊙ 비동기 상태 레지스터 (ASSR) : 타이머/카운터0 이 외부 클럭에 의하여 비동기 모드로 동작하는 경우 관련된 기능을 수행 BIT
7
6
5
4
3
2
1
0
$30($50)
-
-
-
-
AS0
TCN0UB
OCR0UB
TCR0UB
Value
0
0
0
0
0
0
0
0
AS = 0 , 동기모드 (내부클럭 사용) AS = 1, 비동기모드 (외부클럭 사용) 20062006-0404-03
-8-
Embedded AVR Programming
1-2 타이머/카운터 0 ⊙ 특수 기능 I/O 레지스터 (SFIOR) : 타이머/카운터들을 동기화 하는데 관련된 기능 BIT
7
6
5
4
3
2
1
0
$32($52)
TSM
-
-
-
ACME
PUD
PSR0
PSR321
Value
0
0
0
0
0
0
0
0
TSM : 모든 타이머/카운터들을 동기화시키는 기능수행 ⊙ 타이머/카운터 인터럽트 마스크 레지스터 (TIMSK) BIT
7
6
5
4
3
2
1
0
$37($57)
OCIE2
TOIE2
TICIE1
OCIE1A
OCIE1B
TOIE1
OCIE0
TOIE0
Value
0
0
0
0
0
0
0
0
OCIE0 : Timer/Counter0 Output Compare Match Interrupt Enable 로서 이 값이 1로 설정되고 상태 레지스터 SREG 에서 I=1로 설정시 작동되며 이때 TIFR의 OCF0 비트가 1로 되면 이 인터럽트가 처리 TOIE0 : Timer/Counter0 Overflow Interrupt Enable로 이 값이 1로 셋 되고 SREG I =1 일 때, TIFR의 TOV0비트가 1로 되면 이 인터럽트가 처리
20062006-0404-03
-9-
Embedded AVR Programming
1-2 타이머/카운터 0 ⊙ 타이머/카운터 인터럽트 플래그 레지스터 (TIFR) BIT
7
6
5
4
3
2
1
0
$36($56)
OCF2
TOV2
ICF1
OCF1A
OCF1B
TOV1
OCF0
TOV0
Value
0
0
0
0
0
0
0
0
⊙ 인터럽트 주기 공식 Interrupt Cycle = (Prescale Ratio/Clock) * (256-TCLK0) 인터럽트 주기 = (프리스케일러비/클럭)*(256-TCLK0레지스터값) 예)프리스케일러비 256, 클럭 16MHz, TCLK0는 56 (256/16*10^6)*(256-56) = 3.2ms
20062006-0404-03
-1010-
Embedded AVR Programming
1-3 Timer0 오버플로워 인터럽트 실습 1 ☞ 포트 B의 4번핀에 LED를 연결하여 토글 형식의 신호를 출력하는 프로그램 #include <mega128.h> #include <delay.h> // timer 0 overflow ISR interrupt [TIM0_OVF] void timer0_ovf_isr(void) { TCNT0 = 0x00; // reset TCNT0 PORTB.4 = ~PORTB.4; } void main(void) { DDRB = 0x10;
// 포트 B를 출력으로 설정
TCNT0 = 0x00; // reset TCNT0 TCCR0 = 0x07; // count with cpu clock/1024 // 실습) TCCR0를 변화하면서 발생하는 주기를 측정한다. TIMSK = 0x01; // enable TCNT0 overflow #asm("sei"); while (1) { }; }
20062006-0404-03
-1111-
Embedded AVR Programming
1-7 Timer0 오버플로워 인터럽트 실습 2 ☞ 포트 B의 4번핀에 LED를 연결하여 500ms마다 토글 형식의 신호를 출력하는 프로그램 #include <mega128.h> #include <delay.h>
void main(void) { DDRB = 0x10;
// 포트 B를 출력으로 설정
unsigned int timecount = 0; // global time counter // timer 0 overflow ISR interrupt [TIM0_OVF] void timer0_ovf_isr(void) { TCNT0 = 6; // reload for 1ms ticks if(++timecount == 500) { PORTB.4 = ~PORTB.4; // toggle PORTB.4 //PORTB = PORTB ^ 0x10; // toggle PORTB.4 timecount = 0; // clear for next 500ms } }
20062006-0404-03
TCNT0 = 0x00; // reset TCNT0 TCCR0 = 0x04; // count with cpu clock/64 (64/16MHz=4ms) TIMSK = 0x01; // enable TCNT0 overflow #asm("sei"); while (1) ; // do nothing }
-1212-