Atmega128에서 지원하는 외부인터럽트중 RESET 다음으로 가장 우선순위가 높은 인터럽트가 있다.
바로 외부인터럽트이다. 그 순위로는 INT0 ~ INT7까지이다.
RESET보다는 우선순위가 낮지만, 그 외 타이머 인터럽트보다는 높다.
더 자세한 인터럽트 순위에 관해 궁금하다면 아래 참고.
https://ansan-survivor.tistory.com/1221
이제 이 외부인터럽트에 스위치를 달아서 동작을 시켜본다.
사용할 PCB는 직접제작한 아래 PCB이다. (Atmega128과 최소한의 동작기능만 장착)
https://ansan-survivor.tistory.com/1144
먼저 외부인터럽트를 사용하기전에 아래 항목의 레지스터를 알아야 한다.
- SREG
- EMISK
- EICRA
- EICRB
< SREG 레지스터 >
- 외부인터럽트가 발생하려면 무조건 7번 비트가 1으로 Set되어야 한다.
- 그래서 보통 코드 마지막에 SREG |= 0x80; 으로 자주 사용
< EMISK 레지스터 >
- INT0 부터 INT7 까지 사용할 외부인터럽트를 Set하면 된다.
- 여기 예제에서는 INT7 과 INT6을 사용함으로 1100 0000 (=0xC0) 으로 Set하면 됨.
< EICRA, EICRB 레지스터 >
- 외부인터럽트 INT0 ~ INT3 을 사용할 때 트리거방식 설정
- 외부인터럽트 INT4 ~ INT7 을 사용할 때 트리거방식 설정
- 2개 비트 마다 각각 INTn의 기능 설정
- EICRA는 INT0 ~ INT3 의 동작 방식을 정할 수 있음
- EICRB는 INT7 ~ INT4 의 동작 방식을 정할 수 있음
* PE0 출력포트 설정, LED장착 (저항 생략)
* PE6, PE7 스위치 입력포트 설정, 내부 Pull-up 모드 설정 (DDRn을 입력 설정 후 PORTn을 Set하면 내부 Pullup 사용)
예제 코드)
PE6과 PE7의 외부 인터럽트가 들어오면 (스위치의 하강 엣찌) LED가 토글
EICRB = 0xA0; 넣은 이유, INT6과 INT7을 하강엣지로 사용
#include <avr/io.h>
#include <avr/interrupt.h>
// 외부인터럽스6 (INT6레지스터) 서비스 루틴
// 인터럽트가 들어오면 동작
ISR(INT6_vect)
{
PORTE &= 0xFE; // 0b11111110 PE0번 비트가 클리어되고 (clear = 0)
}
// 외부인터럽스7 (INT7레지스터) 서비스 루틴
ISR(INT7_vect)
{
PORTE |= 0x01; // 0b00000001 PE0번 비트가 셋됨(set = 1)
}
int main(void)
{
// 0x00111111 으로 PE6, PE7을 입력세팅, 나머지 PE0 ~ PE5 출력 세팅
DDRE = 0x3F;
// PE6, PE7을 Pull-up으로 하기위해 AND마스크 (DDRn을 입력설정 후 PORTn을 Set하면 내부 Pullup 사용)
PORTE &= 0xC0;
// 사용할 외부인터럽트 bit를 Set해줌. INT6, INT7 사용하므로 0b11000000 으로 세팅
EIMSK = 0xC0; // INT6, 7 Interrupt Enable
// 인터럽트 동작 방식 설정
EICRA = 0x00;
EICRB = 0xA0; // INT6, 7 Falling Edge에 동작 [1010 0000]
// 인터럽트 발생시 필요, 7번 bit를 Set해주어야 함
SREG |= 0x80; // Global Interrupt Enable
while(1){
}
return 0;
}