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 오버플로어와 같은 구동을 한다.
좋은 점은 프로그램 공간이 절약된다는 점이다.
[출처] interrupt의 SIGNAL과 ISR의 차이점|작성자 리스브
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 |