8비트 타이머/카운터 2개 |0 ~ 255
16비트 타이머/카운터 1개 |0 ~ 65535
분주비 = 클록을 나누는 값
- 오버플로 인터럽트 : TCNTn 레지스터에 오버플로가 발생
- 비교일치 인터럽트 : TCNTn 레지스터의 값이 미리 설정된 값과 동일
오버플로 인터럽트
#define F_CPU 16000000L
#include <util/delay.h>
#include <avr/io.h>
#include <avr/sfr_defs.h>
#include <avr/interrupt.h>
#include "UART.h"
int count = 0;
int state = 0;
ISR(TIMER0_OVF_vect) //오버플로 인터럽트 벡터
{
count++;
if(count == 32){ //오버플로 32 회 발생
count = 0;
state = !state;
if(state) PORTB = 0xFF;
else PORTB = 0x00;
}
}
int main(void)
{
DDRB = 0x20;
PORTB = 0X00;
TCCR0B |= (1 << CS02) | (1 << CS00); //분주비를 1024로 설정
TIMSK0 |= (1 << TOIE0);
sei();
while(1){}
}
타이머 카운터 레지스터에 1로 둔다.
16M을 2^20으로 봐서
8비트 타이머는 0~255 = 256 = 2^8
16M 클록 사용하면 256/16M
count = 32 = 2^5
= ( 2^8 * 2^10 ) / 2^4 * 2^20(16M) = > 오버플로 32회 발생하는데 0.5초
TCNT0 : 현재까지의 카운트 값 저장
분주비 설정 TCCR0B
–16MHz 클록, 1024 분주비를 사용하는 경우 16M/1024 = 16KHz 펄스가 타이머/카운터에 공급
–256개 클록 생성을 위해서는 256/16K = 1/64초 소요
–32회 오버플로가 발생하면 0.5초 경과
실행 예)
TCCR0B |= (1 << CS02) | (1 << CS00);
인터럽트 활성화 레지스터 TIMSK0
실행 예)
TIMSK0 |= (1 << TOIE0); //오버플로 인터럽트
TIMSK1 |= (1 << OCIE1A);
OCR0x 레지스터 (Output Compare Register)
비교일치 발생 후 TCNT0 레지스터는 자동으로 0으로 초기화되지 않음
실행예 ) OCR0A = 128; //비교일치 기준값
비교일치 인터럽트1
#define F_CPU 16000000L
#include <util/delay.h>
#include <avr/io.h>
#include <avr/sfr_defs.h>
#include <avr/interrupt.h>
#include "UART.h"
volatile int count = 0; //비교일치 발생한 횟수
int state = 0; //LED 점멸 상태
ISR(TIMER0_COMPA_vect)
{
count++;
TCNT0 = 0; //비교일치 카운트 실행되면 TCNT0 = 0 을 반드시 해야된다.
}
int main(void)
{
DDRB = 0x20; //출력 핀으로
PORTB = 0x00;
TCCR0B |= (1 << CS02) | (1 << CS00); //분주비를 1024로 설정
OCR0A = 128; // 비교일치 기준 값 256의 반
TIMSK0 |= (1 << 0CIE0A); // 비교일치 인터럽트 허용
sei();
while(1)
{
if(count ==64){ //비교일치 64회 발생 = 0.5초 경과
count = 0;
state = !state;
if(state) PORTB = 0xFF;
else PORTB = 0x00;
}
}
}
–TCNT1 레지스터는 2개의 8비트 레지스터를 조합한 16비트 가상 레지스터
–OCR1x 레지스터는 16비트 가상 레지스터
-16비트 타이머/카운터가 긴 시간 측정 가능
비교일치 인터럽트2
#define F_CPU 16000000L
#include <util/delay.h>
#include <avr/io.h>
#include <avr/sfr_defs.h>
#include <avr/interrupt.h>
#include "UART.h"
int state = 0; //LED 점멸 상태
ISR(TIMER1_COMPA_vect) //16비트
{
TCNT1 = 0; //비교일치 카운트 실행되면 TCNT1 = 0 을 반드시 해야된다.
state = !state;
if(state) PORTB = 0xFF;
else PORTB = 0x00;
}
int main(void)
{
DDRB = 0x20; //출력 핀으로
PORTB = 0x00;
TCCR1B |= (1 << CS12) | (1 << CS10); //분주비를 1024로 설정
OCR1A = 0x2000; // 비교일치 기준 값 256의 반
TIMSK1 |= (1 << 0CIE1A); // 비교일치 인터럽트 허용
sei();
while(1)
{
}
}
파형 출력
비교일치 인터럽트 발생 -> 지정된 핀을 통해 신호 출력
비교 일치 A,B
TCCR1A 레지스터 (Timer/Counter Control Register)
파형생성 비교일치 인터럽트
int main(void)
{
TCCR1B |= (1 << CS12) | (1 << CS10); //분주비 1024로 설정
OCR1A = 0x2000; //비교일치 기준 값
//비교일치 인터럽트 발생시 OC1A 핀의 출력 반전
TCCR1A |= (1 << COM1A0);
TCCR1B |= (1 << WGM12); //CTC 모드 선택
DDRB |= (1 << PINB1); //OC1A 핀을 출력으로 설정
while(1){}
}
CTC (Clear Timer on Compare Match) 모드에서는
비교일치 인터럽트 발생시
TCNT 레지스터가 0으로 자동 리셋됨 그렇기 때문에 따로 설정 안해도됨.
'IoT > 아트멜 스튜디오와 아두이노로 배우는 ATmega328 프로그래밍' 카테고리의 다른 글
ATmega328 프로그래밍 LCD 출력 성공! (0) | 2020.06.25 |
---|---|
ATmega328 조도센서, 온도센서, 초음파센서 (0) | 2020.06.11 |
ATmega328 가변저항 / 난수 생성 (0) | 2020.06.08 |
인터럽트 (0) | 2020.05.30 |
LED & button (0) | 2020.05.24 |
댓글