SIGNAL(SIG_OVERFLOW0)

ISR(SIG_OVERFLOW0)

이렇게 하면 둘다 똑같다.

 

하지만 ISR은 20071221rc1버전 부터는 옵션을 붙일 수가 있다.

여기의 옵션으로는

ISR_BLOCK,

ISR_NOBLOCK,

ISR_NAKED,

ISR_ALIASOF(target interrupt)

이렇게 4가지가 존재한다.

옵션을 붙이는 것은

ISR(SIG_OVERFLOW0, 옵션)과 같다.

 

그럼 각 기능에 대해 살펴 보자. ( disassembler창을 통해 확인 해봤다. )

ISR_BLOCK은 안 붙인것과 동일한 일을 수행한다.

  동일한 일이란

  PUSH    R1 // R1 스택에 저장
  PUSH    R0 // R0 스택에 저장
  IN      R0,0x3F // R0에 SREG 읽음
  PUSH    R0 // R0 스택에 저장 ( SREG 스택에 저장 )
  CLR     R1 // R1 지움 ( R1은 0을 유지하는것을 권장한다. AVR에서 )

  // 여기에 사용되는 레지스터 들을 PUSH 한다.
  // 실제 구문

  // 실제 구문 끝

  // 사용이 끝난 레지스터 들을 다시 POP 한다. (원래 프로그램에 영향이 없도록 PUSH와 POP을 수행함)
  POP     R0 // R0 스택에서 꺼냄 ( SREG 스택에서 꺼냄 )
  OUT     0x3F,R0 // SREG에 R0 저장
  POP     R0 // R0 스택에서 꺼냄
  POP     R1 // R1 스택에서 꺼냄

  RETI // 인터럽트 복귀

  이런 일을 하게 된다. 많다. ㅠㅠ

그럼 ISR_NOBLOCK은

  ISR_BLOCK의 처음에 SEI가 더 붙는다.

ISR_NAKED는

  PUSH

  POP

  RETI

  전혀 없는

  실제 구문만 수행한다. 그래서 ISR_NAKED를 사용하면 끝에 RETI를 꼭 붙여야 된다.

  예)

  ISR(SIG_OVERFLOW0, ISR_NAKED)

  {

    PORTD = ~PORTD;

    reti();

  }

  이것의 장점은 코드를 최소화 할 수 있다는 점이다.

마지막으로 ISR_ALIASOF(target interrupt)은

  target interrupt와 같은 일을 한다고 알려주고 끝난다.

  예)

  ISR(SIG_OVERFLOW0)

  {

    PORTD = ~PORTD;

  }

  ISR(SIG_OVERFLOW1, ISR_ALIASOF(SIG_OVERFLOW0));

  이렇게 하면 타이머1 오버플로어가 타이머0 오버플로어와 같은 구동을 한다.

  좋은 점은 프로그램 공간이 절약된다는 점이다.


'[C-04] ATmega2560' 카테고리의 다른 글

ATmega2560 Bootloader  (0) 2009.10.22
ATmega2560 TWI(I2C) Implementatioin  (0) 2009.10.22
WinAVR에서 printf 함수의 사용 방법  (0) 2009.10.18
ATmega2560 SPI Implementation  (0) 2009.10.17
ATmega2560 UART0 implementation  (0) 2009.10.17
Posted by eoseontaek