Miobot's Story

AVR 기초 강좌

4. ATmega128의 기능 및 제어 2


ATmega128's function (Interrupt)

2012.12.31

 1. 인터럽트(Interrupt)


ATmega128에는 리셋을 포함하여 모두 35종의 리셋 및 인터럽트 벡터를 가지고 있다. 이러한 인터럽트 구성은 외/내부 장치의 서비스 요청에 MCU가 가장 빠르게 대응할 수 있는 방법이기 때문에 사용자가 원하는 작업을 수행하는 중요한 수단이 된다.

(1) 인터럽트(Interrupt)란?
: CPU 외부의 하드웨어적인 요구에 의해서 정상적인 프로그램의 실행 순서를 변경하여 보다 시급한 작업을 먼저 수행한 후에 다시 원래의 프로그램으로 복귀하는 작업을 말한다.

인터럽트는 짱구다?

 



 



(2) 인터럽트의 종류
: ATmega128의 경우에는 35종의 리셋 및 인터럽트 벡터를 가지고 있는데 아래 그림과 같이 구성되어 있다.

 


▪ 리셋 및 인터럽트 벡터를 분류해보자.
RESET          1개
Ext.INT          8개
TIMER 0        2개
TIMER 1        5개
TIMER 2        2개
TIMER 3        5개
USART0        3개
USART1        3개
ADC             1개
기타             5개
  
▪ 인터럽트우선순위?
인터럽트의 요청이 중복될 수도 있는 경우를 대비하여 각 인터럽트 사이에는 하드웨어적으로 우선순위를 정해두었다. 이에 따라 인터럽트 발생이 동시에 될 경우 우선순위가 높은 인터럽트가 먼저 실행되게 된다.
 
(3) 인터럽트의 제어방법
: 위의 여러 인터럽트를 사용하기 위해서는 SREG 레지스터의 I비트를 Set시켜 모든 인터럽트를 허용 해야 하며 사용할 인터럽트의 개별적인 Enable 비트를 Set시켜야만 한다. 그 사용법에 대해서는 외부인터럽트제어 부분에서 예를 들어 설명하니 참고하기 바란다.


 2. 외부 인터럽트 제어


ATmega128에서 외부 인터럽트가 8개 지원되는데 이는 8개의 외부핀(INT 7~0)을 통해서 입력되는 신호에 의하여 발생하는 인터럽트를 말한다.
 
(1) 외부 인터럽트란?
: 위에서 인터럽트의 종류는 35가지 임을 알았다. 외부인터럽트는 이중 8개에 속하는 것으로서 내부적인 처리 및 연산에 의한 다른 인터럽트와는 달리 아닌 외부핀 INT0~INT7에 직접 입력되는 신호(High & Low)값을 입력 값으로 받아 인터럽트가 걸려 정해놓은 인터럽트 루틴을 실행하는 것을 말한다.

외부 인터럽트 = 달팽이 눈?
달팽이의 눈처럼 생긴 촉수는 외부와의 접촉의 순간, 잎사귀를 먹고 있던 도중이던, 이동 중 이던간에 무조건적으로 달팽이 관속으로 숨어 버린다. 이처럼, 외부인터럽트는 당팽이의 눈(촉수)와 같은 역할을 하여, 외부에서 신호가 들어오면 현재 진행중인 프로그램을 잠시 멈추고, 정해져 있는 일을 수행하게 된다. 

(2) 외부 인터럽트(INT 7~0)의 특징
- 외부 인터럽트는 INT 7~0 핀의 트리거 동작으로 인터럽트가 발생된다.
- LOW / 상승엣지 / 하강엣지 의 방식으로 트리거 신호를 선택할 수 있다.
- 외부 인터럽트는 INT 7~0 핀의 입/출력 방향에 관계없이 인터럽트가 발생된다.
(소프트웨어적으로 데이터를 출력하여 인터럽트를 요구 할 수도 있다.)
- INT 7~4 : I/O클럭이 있어야만 사용가능
- INT 3~0 : 비동기적 검출이 가능하다.( 슬립모드를 깨울 때 이용되기도 한다.)

 
(3) 외부 인터럽트 관련 레지스터
: 외부 인터럽트를 제어하기 위해서는 상태레지스터(SREG)와 외부 인터럽트 관련 레지스터(EIMSK, EICRA, EICRB, EIFR)의 사용법을 알아야 한다.
 
① SREG(Status Register)

 

▪ MCU의 현 상태 및 최근 수치 명령 실행에 대한 결과를 포함한다.
▪ 상태레지스터는 모든 ALU 연산을 수행 후 갱신된다.
▪ Bit7. I (Global Interrupt Enable) : 모든 인터럽트 활성화 비트


② EIMSK(External Interrupt Mask Register)

▪ Bit 7..0 – INT 7~0 Q 비트를 SET(1) 시키면 해당 외부 인터럽트 핀이 활성화 된다.
▪ 단, SREG의 I비트가 1로 SET된 상태여야 한다.


③ EICRA(External Interrupt Control Register A)

▪ 외부 인터럽트의 트리거 방식을 LOW / 상승엣지 / 하강엣지 중에 선택하는 레지스터

ISCn1

ISCn0

설명

0

0

INTn Low 신호시에 일반적인 인터럽트 요청을 한다.

0

1

(reserved)

1

0

INTn의 하강엣지 신호시에 일반 비동기적인 인터럽트를 요청한다

1

1

INTn의 상승엣지 신호시에 일반 비동기적인 인터럽트를 요청한다

 


④ EICRB(External Interrupt Control Register B)

 

▪ 외부 인터럽트의 트리거 방식을 LOW / 상승엣지 / 하강엣지 중에 선택하는 레지스터

ISCn1

ISCn0

설명

0

0

INTn의 Low 신호시에 일반적인 인터럽트 요청을 한다.

0

1

어떠한 신호의 변화에서든 일반적인 인터럽트 요청을 한다.

1

0

INTn의 두 샘플 신호간의 하강엣지 신호시에 일반적인 인터럽트를 요청한다

1

1

INTn의 두 샘플 신호간의 상승엣지 신호시에 일반적인 인터럽트를 요청한다

 


⑤ EIFR(External Interrupt Flag Register)

▪ Bit 7..0 – 외/내부로부터 INT7:0 핀에 인터럽트가 요청되면 해당 비트가 Set(1) 된다. 그 후에 인터럽트 루틴이 실행될 때 해당 비트가 Clear(0)된다.


(4) 외부 인터럽트 동작
①    인터럽트가 활성화(SREG.7 / EIMSK 해당 비트 활성화) 되어 있는 상태에서
②    외부INT의 동작 엣지나 논리신호에 의해 인터럽트가 요청되면
③    제일 우선 INTFn=1 상태로 플래그가 Set되고
④    실행 중이던 메인 프로그램의 프로그램카운터 값을 스택에 저장하게 된다.
⑤    그 후 해당 인터럽트 벡터로 점프하게 되며
⑥    지정된 인터럽트 루틴을 실행하는 동시에 INTFn=0 상태로 플래그가 Clear된다.
⑦    해당 인터럽트의 루틴이 처리된다.
⑧    해당 인터럽트의 루틴이 끝나게 되면 RETI 명령을 받는다.
⑨    스택으로부터 저장된 프로그램카운터 값을 로드 한다.
⑩    동작 중이던 프로그램 위치로 복귀하여 실행 중이던 부분부터 메인 프로그램이 재작동된다.
 
위의 내용은 외부인터럽트의 처리과정을 자세히 서술하여 설명한 것입니다. 이게 무슨 말인지 받아 들이기 어려운 것은 우선 모르는 용어가 많이 나왔을 것이며, 벡터 주소 값에 대한 이해가 부족한 탓이죠. 처음에는 어려울 수도 있으니 이해가 안 된다면 우선 넘어가고 후에 자세히 읽어 본다면 인터럽트의 이해가 쉬워 질 것입니다.
 
 


 3. 외부 인터럽트 실습




[Example 01]
: 아래의 소스는 아래의 그림과 같이 간단한 스위치회로를 구성하여 스위치를 눌렀을 때 외부인터럽트가 걸려 메인프로그램(LED ALL OFF)에서 인터럽트루틴(LED ALL ON)이 실행되기 위한 프로그램이다.

 


#include "iom128.h"
 
#define sbi(PORTX , BitX)   PORTX |=  (1 << BitX)   // 비트 SET 명령 정의
#define cbi(PORTX , BitX)   PORTX &= ~(1 << BitX)   // 비트 CLEAR 명령 정의
 
void delay(long time);                  // 딜레이 함수 선언
 
#pragma vector=INT0_vect                
__interrupt void INT0_Interrupt( void ) // INT0 인터럽트 처리 루틴(ISR)
{  
    PORTA = 0xFF;       // 1111 1111 (LED 전등)
    delay(1000000);     // 시간 지연 함수
}
void main(void)
{
    sbi(SREG,7);        // SREG I비트 SET
    sbi(EIMSK,INT0);    // EIMSK INT0비트 SET

    DDRA = 0xFF;        // PORTA 출력포트로 설정
    DDRD = 0x00;        // PORTD 입력포트로 설정
                        // PORTD는 출력으로 설정해도 무방하다.
    while(1)
    {
        PORTA= 0x00;    // 0000 0000 (LED 전멸)
    }      
}
 
void delay(long time)   // 딜레이 함수 정의
{
    while(time--);
}



 [ 참고자료 ]


[1] Atmel Corporation, ATmega128(L) Datasheet, http://www.atmel.com/devices/ATMEGA128.aspx?tab=documents


End.

written by Yoonseok Pyo
http://robotpilot.net/
http://cafe.naver.com/openrt


Posted by Miobot