인터럽트 EICRA(External Interrupt Control Register A), EICRB(External Interrupt Control Register B) 설명


 ISC71

ISC70 

ISC61 

ISC60 

ISC51 

ISC50 

ISC41 

ISC40 

 Bit 7

Bit 6 

Bit 5 

Bit 4 

Bit 3

Bit 2 

Bit 1 

Bit 0 

Bit 0 과 1, Bit 2 와 3, Bit 4 와 5, Bit 6 과 7은 위 그림의 표처럼 한 쌍이다.

EICRA, EICRB는 각각 두 개 씩 묶어서 INT0(ISC00, ISC01) : INT7(ISC70, ISC71)까지를 의미한다.

이들의 값에 따라 어떤 식으로 작동이 되느냐는 밑의 표에 나와있다.    



 ISCn1

ISCn0 

Description 

 0

 Low이면 인터럽트를 요청.

 0

 어떤 변화가 있으면(positive || negative) 인터럽트를 요청.

 1

 falling edge이면 인터럽트를 요청.

 1

 rising edge이면 인터럽트를 요청.

* ISCn1의 n은 INTn의 n을 의미한다.



인터럽트 EIMSK - External Interrupt Mask Register 설명



Bits 7:0은 INT7 : INT0을 의미한다. 이들 중 하나가 무조건 1이어야 하고, 

SREG 레지스터의 Bit 7 I도 1이 되어야 인터럽트가 구동된다.

INT7 : INT0가 방이라 치고 SREG 레지스터의 Bit 7이 대문이라 치면, 

대문을 잠그면(0) 밖에 나갈 수 없다. 그래서 둘 다 1이어야 인터럽트 요청가능.



INT.h부터 살펴보자

#define cli() __asm__ __volatile__ ("cli" ::)

SREG 인터럽트 비활성화 시키는 어셈블리어

#define sei() __asm__ __volatile__ ("sei" ::)

SREG 인터럽트 활성화 시키는 어셈블리어 sei(set enable interrupt)

자동으로 1을 넣는다.

#define sleep() __asm__ __volatile__ ( "sleep" "\n\t" :: )

SREG 인터럽트 슬립 시키는 어셈블리어

c로만은 cpu를 못 건드는 부분을 어셈블리어로 건들인다.

통틀어 inline assembly라고 부른다. 컴파일이 바뀌면 사용할 수 없다. 

void __vector_8(void) __attribute__((signal, used, externally_visible));

gcc컴파일러만 쓰는 문법 이 함수의 속성을 적어줌.

리눅스에서는 시그널....인터럽트이다. 외부에서 이 함수를 호출할 수 있다.

data sheet 59page 벡터 넘버를 보면 실제 코딩할 때는 번호가 0부터 시작이다.

void INT7_Init(void);



다음 INT.c를 보면,

void __vector_8 (void) 

{

LCD_Str("Interrupt1");

상승엣지일 때 위의 것이 적힘.

USART_Str("Interrupt2");

}

void INT7_Init(void)

{

cli();

이 함수를 실행전에 다른장치의 인터럽트를 먼저 꺼둠.

EICRB = (1<<ISC71)|(1<<ISC70);

상승 엣지일 때 인터럽트 요청.

EIMSK = EIMSK|(1<<INT7);

SREG는 직접 건들여서 세팅하거나,

sei();

SREG = SREG|(1<<I)과 같은 의미.

}



마지막으로 main.c

int main(void)

{

LCD_Init();        LCD초기화

INT7_Init();        INT7초기화

while(1)

{

sleep();

일 안시키면 재운다.

}

return 0;

}



실행결과


ATMega 128A에 연결.

푸쉬스위치에 연결

실행 결과


최종 소스는 

20140509.zip