AVR2012.02.04 11:24

[AVR Essay 13] 인터럽트 이야기

 

 

지금까지 기본적인 I/O에 대해서 대부분 이야기 한 것 같다.

 

이제, ATmega 8535에 있는 조금은 더 특수한 기능을 다루게 될 것이다.

 

타이머, 카운터, PWM, USART, SPI, TWI, A/D 컨버터, 아날로그 비교기가 있다.

 

이들 중 대부분은 인터럽트를 사용한다.

 

그래서 간단하게나마 인터럽트가 무엇인지 이해하고 진행해야 할 것 같다.

 

 

인터럽트는 프로그램이 실행 중에 외부의 장치 등에서 요구가 있으면

 

실행중의 프로그램을 일시 중단하고 요구에 따라 다른 처리를 수행 한다.

 

간단히 아래 그림을 보면 된다.

 

프로그램이 잘 실행되고 있다가 인터럽트가 요청되면 나중에 되돌아올 return address를 스택에 저장 한 후

 

interrupt service routine에서 인터럽트를 처리한 후 인터럽트 발생전 위치로 돌아 오는 것이다.

 

대충 이정도 개념만 알고 넘어 가자. 이론적으로 인터럽트를 풀어 나가면 할 말이 너무 많다.

 

 

ATmega 8535에는 SREG 레지스터(Status Register)가 있다.

 

여기서 Bit 7이 지금 다루고 있는 인터럽트 관련 레지스터다.

 

그것도 시스템 전체 인터럽트를 제어한다. Global Interrupt Enable이라는 의미이고

 

인터럽트를 사용하기 위해서는 우선 이를 1로 해 설정 해야 한다.

 

이 레지스터를 직접 건들여서 제어할 수도 있지만 주로 WinAVR에서는 sei();, cli(); 명령을 사용한다.

 

전체 인터럽트를 사용하기 위해서는 sei();, 전체 인터럽트를 중지 할려면 cli(); 명령을 사용하면 된다.

 

대충 set interrupt, clear interrupt 하면 명령어 외우는데는 문제 없을 것이다.

 

(사실 이 명령은 SEI, CLI로 어셈블리에 근거 한 것이다.)

 

나머지 Bit들도 상당히 중요한 것이지만 인터럽트와는 관계 없기 때문에 생략 하겠다.

 

(데이터 시트에 설명이 아주 훌륭하게 되어 있다.)

 

 

각 장치 별로 인터럽트를 사용하기 위해서는 각 장치에 해당하는 레지스터마다

 

인터럽트 사용 유무를 결정 할 수 있는 부분이 있다.

 

이들에 대해서는 해당 장치가 나올 때마다 다룰 예정이다.

 

인터럽트가 발생 했을 때 어떤 장치가 인터럽트를 발생 했는지 판단하는 인터럽트 벡터가 있다.

 

인터럽트 벡터는 인터럽트 마스크 레지스터를 통해서 각각 개별적으로 허용여부를 설정할 수 있다.

 

ATmega 8535에는 다음과 같이 인터럽트 벡터가 정의 되어 있다.

 

(AVR에서는 인터럽트가 동시에 발생하면 아래 순서대로 우선순위가 결정 된다.)

 

여기서 각각 인터럽트는 Program Address를 통해서 접근하는데,

 

역시 사람은 숫자에 약하기 때문에 WinAVR의 avr/iom8535.h 파일에 다음과 같이 #define 되어 있다.

 

 

이하 부분은 생략 했으니 직접 파일을 열어서 어떻게 되어 있는지 확인 해 보도록 해라.

 

 

인터럽트가 발생 했을 때 interrupt service routine으로 점프 하는데 여기서 할 일을 정해 주면 된다.

 

interrupt service routine은 WinAVR에서는 함수와 유사하게 작성하면 된다.

 

 

ISR(인터럽트 벡터)

{

   ...

}

 

 

예를 들어 타이머0 오버플로우 인터럽트의 interrupt service routine을 구현 할려면 다음과 같이 하면 된다.

 

 

ISR(TIMER0_OVF_vect)

{

   // 할일

}

 

 

그리고 인터럽트를 사용하기 위해서는 avr/interrupt.h를 #include 해 줘야 한다.

 

경우에 따라 interrupt service routine을 ISR 대신 SIGNAL이나 INTERRUPT로 처리하기도 하는데,

 

WinAVR에서는 앞으로 없엘 명령이기 때문에 사용하지 않는 것이 좋다.

 

자세한 내용은 avr/interrupt.h 파일을 참조 하도록 하라.

 

 

인터럽트와 대비되서 사용되는 말은 폴링(polling)이 있다.

 

인터럽트는 프로그래머가 모르는 시점에서 발생하는 것이지만

 

폴링은 프로그래머가 원하는 시점에 처리하는 것 이다.

 

텀즈에는 폴링을 다음과 같이 설명하고 있으니 참조 하도록 하라.

 

 

통신에서, "폴링"은 한 프로그램이나 장치에서 다른 프로그램이나 장치들이 어떤 상태에 있는지를

 

지속적으로 체크하는 전송제어 방식으로서, 대체로 그들이 아직도 접속되어 있는 지와 데이터 전송을 원하는지 등을 확인한다.

 

명확히 말하면, 여러 개의 장치가 동일 회선을 공유하는 멀티드롭이나 멀티포인트 통신에서,

 

제어 장치는 각 장치에 한번에 하나씩 메시지를 보내어, 전송할 데이터가 있는지(즉, 회선을 사용하기 원하는지)를 묻는다.

 

 

일단 이 정도 하면 인터럽트가 무엇인지 감을 잡았다고 믿고 싶다.

 

구체적인 예제는 앞으로 쭉~~~ 나올 것이다.

Posted by 콩알은