본문 바로가기
IoT/아트멜 스튜디오와 아두이노로 배우는 ATmega328 프로그래밍

오버플로 / 비교일치 인터럽트

by javapp 자바앱 2020. 6. 9.
728x90

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로 둔다.

 

16M2^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

실행 예) 

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)

       {

 

       }

}

 


 

파형 출력

 

비교일치 인터럽트 발생 -> 지정된 핀을 통해 신호 출력

 

~ 물결표시는 PWM은 출력 표시

비교 일치 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으로 자동 리셋됨 그렇기 때문에 따로 설정 안해도됨.

댓글