3. --33--20062006--0404--0303
Embedded AVR ProgrammingEmbedded 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)
5. --55--20062006--0404--0303
Embedded AVR ProgrammingEmbedded AVR Programming
1-2 타이머/카운터 0
⊙ 타이머/카운터0 제어 레지스터(TCCR0)
: 타이머/카운터0의 동작 모드를 설정하고 프리스케일러의 분주비를 설정
- FOC0(Force Output Compare) : 1로 설정시 강제로 즉시 OC0 단자에 출력비교가
매치 된 것과 같은 출력을 내보냄, 출력신호의 동작은 COM01~00 비트에 의해 결정
- CS02 ~ CS00 : PRESCALER 설정
Value
$33($53)
BIT
00000000
CS00CS01CS02WGM01COM00COM01WGM00FOC0
01234567
clkTOS / 32110
clkTOS / 64001
clkTOS / 128101
clkTOS / 256011
clkTOS / 1100
clkTOS / 8010
1
0
CS02
clkTOS / 102411
클럭 입력을 차단(타이머/카운터0의 기능이 정지됨)00
클럭 소스의 기능CS00CS01
6. --66--20062006--0404--0303
Embedded AVR ProgrammingEmbedded 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으로 숫자가 줄어들면서 셈
BOTTOMTOP0xFFPhase Correct PWM101
MAX설정 즉시OCR0CTC012
3
0
모드
MAXTOP0xFFPast PWM11
MAX설정 즉시0xFFNormal00
TOV0 플래그의
셋트 시점
OCR0 레지스터
의 업데이트 시점
TOP동작모드
WGM00
(옛 PWM0)
WGM01
(옛 CTC0)
8. --88--20062006--0404--0303
Embedded AVR ProgrammingEmbedded AVR Programming
1-2 타이머/카운터 0
⊙ 타이머/카운터0 레지스터 (TCNT0)
: 타이머/카운터0의 8비트 카운터값을 저장
⊙ 타이머/카운터0 출력비교 레지스터(OCR0)
: TCNT0 값과 비교하여 OC0 단자에 출력신호를 발생하기 위한 8비트 값을 저장
⊙ 비동기 상태 레지스터 (ASSR) : 타이머/카운터0 이 외부 클럭에 의하여 비동기 모드로
동작하는 경우 관련된 기능을 수행
AS = 0 , 동기모드 (내부클럭 사용)
AS = 1, 비동기모드 (외부클럭 사용)
Value
$32($52)
BIT
00000000
TCNT0[7..0]
01234567
Value
$31($51)
BIT
00000000
OCR0[7..0]
01234567
TCR0UBOCR0UBTCN0UBAS0---
Value
$30($50)
BIT
00000000
-
01234567
9. --99--20062006--0404--0303
Embedded AVR ProgrammingEmbedded AVR Programming
1-2 타이머/카운터 0
⊙ 특수 기능 I/O 레지스터 (SFIOR) : 타이머/카운터들을 동기화 하는데 관련된 기능
TSM : 모든 타이머/카운터들을 동기화시키는 기능수행
⊙ 타이머/카운터 인터럽트 마스크 레지스터 (TIMSK)
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로 되면 이 인터럽트가 처리
PSR321PSR0PUDACME---
Value
$32($52)
BIT
00000000
TSM
01234567
Value
$37($57)
BIT
00000000
TOIE0OCIE0TOIE1OCIE1BOCIE1ATICIE1TOIE2OCIE2
01234567
10. --1010--20062006--0404--0303
Embedded AVR ProgrammingEmbedded AVR Programming
1-2 타이머/카운터 0
⊙ 타이머/카운터 인터럽트 플래그 레지스터 (TIFR)
⊙ 인터럽트 주기 공식
Interrupt Cycle = (Prescale Ratio/Clock) * (256-TCLK0)
인터럽트 주기 = (프리스케일러비/클럭)*(256-TCLK0레지스터값)
예)프리스케일러비 256, 클럭 16MHz, TCLK0는 56
(256/16*10^6)*(256-56) = 3.2ms
Value
$36($56)
BIT
00000000
TOV0OCF0TOV1OCF1BOCF1AICF1TOV2OCF2
01234567
11. --1111--20062006--0404--0303
Embedded AVR ProgrammingEmbedded 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)
{ };
}
12. --1212--20062006--0404--0303
Embedded AVR ProgrammingEmbedded AVR Programming
1-7 Timer0 오버플로워 인터럽트 실습 2
☞ 포트 B의 4번핀에 LED를 연결하여 500ms마다 토글 형식의 신호를 출력하는 프로그램
void main(void)
{
DDRB = 0x10; // 포트 B를 출력으로 설정
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
}
#include <mega128.h>
#include <delay.h>
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
}
}