728x90

외부 인터럽트 벡터

- 인터럽트 벡터 테이블에서 상위에 위치

 

ATmega128에서 외부 인터럽트 핀 결정

- GPIO 핀 -> 범용 입출력 핀

- ATmega128의 53개의 핀만으로 다양한 기능을 동작하기엔 부족 -> 한 핀이 다른 기능도 사용 가능

 

 

 

외부 인터럽트 핀

- PD0 ~ PD3까지가 INT0 ~ INT3

- PE4 ~ PE7 까지가 INT4 ~INT7

- 해당 GPIO핀들을 외부 인터럽트 핀으로 사용가능

 

 

외부 인터럽트 회로

- 인터럽트 설정을 해야 외부 인터럽트 사용 가능

외부 인터럽트 사용 회로

 

외부 인터럽트 벡터 매크로

- 외부 인터럽트 0과 외부 인터럽트 3을 사용 시 벡터 매크로 설정

- 스위치 첫번째와 네번째를 외부 인터럽트 핀으로 사용

#include <avr/interrupt.h>

ISR(INT0_vect)
{

}

ISR(INT3_vect)
{

}

 

 

SREG Register

- 인터럽트 사용시 내부에 인터럽트 관련 설정을 했을때만 동작

-> 아무때나 인터럽트 발생 방지 

-> 레지스터 설정을 해야함 ->SREG 레지스터

- Status Register : 상태 레지스터

- 인터럽트를 사용하기 위해서 SREG 레지스터의 7번 비트에 1을 써야함(글로벌 인터럽트)

Status Register

 

글로벌 인터럽트 설정

- SREG 레지스터 7번 비트에 1을 저장

- 상태 레지스터는 다른 역활도 수행하므로 잘못 변경되지 않도록 주의

SREG |= (1<<SREG_I)
// SREG |= (1<<7);
// SREG = SERG | (1<<7);

 

SEI와 CLI 명령어

- sei() : Global Interrupt Enable -> 전체 인터럽트 활성

- cli() : Global Intterupt Disable -> 전체 인터럽트 비활성

sei();
// SREG |= (1 << SREG_I)와 같다.

cli();
// SREG |= (0 <<SREG_I)와 같다.

 

EIMSK Register

- External Interrupt MaSK Resgister

- 외부 인터럽트를 개별적으로 허용하는데 사용

- 사용하려는 외부 인터럽트를 high를 주면 된다.

ex) INT0 ~ INT3 을 1로 주면 외부 인터럽트 0 ~ 3 사용 가능

EIMSK Register

EIMSK Register 사용 예시

EIMSK = (1 << INT3);// 1 << 3 = 0b0000 1000;
EIMSK = (1 << INT0) | (1 << INT2); // 0b000 0101

 

EICRA/EICRB Register

- External Interrupt Control Register A/B

- EICRA : 외부 인트럽트 INT0 ~ INT3 감지 방법 결정

- EICRB : 외부 인터럽트 INT4 ~ INT7 감지 방법 결정

EICRA Register
ERCIB Register

EICRA Register

- ISC(숫자)1/0 과 같은 이름 규칙을 가짐

-> ISC01, ISC00 : 외부 인터럽트 0번 설정

-> ISC11, ISC10 : 외부 인터럽트 1번 실징

아래의 테이블 참고

ex 1) ISC01 = 1, ISC00 = 0 일 시

 -> 외부 인터럽트 0번에 폴링 에지 때 인터럽트 발생

ex 2) ISC71 = 1, ISC70 = 1 인 경우

 -> 외부 인터럽트 7번이 라이징 에지 때 인터럽트 발생

=> 스위치가 눌릴때 인터럽트? 눌리고 땔때 인터럽트?

- 스위치 여러개 사용 시 각각에 대해 별도로 코딩해야함

EICRA 레지스터 동작 설명

 

EICRA 코드 구현

EICRA |= (0<<ISC21) | (0<<ISC20); //INT2핀에 Low 신호 입력 순간 인터럽트 발생

EICRA = (1<<ISC21) | (1<<ISC20) | (1<<ISC11) | (0<<ISC10);
// INT2 핀 라이징 에지 시 인터럽트 발생 + INT1핀 폴링 에지시 인터럽트 발생

 

 

 

1. 외부 인터럽트 0 로우 레벨 시 LED on/Off

#include <avr/io.h>
#include <avr/intterupt.h>
#include <util/delay.h>

ISR (INT0_vect)
{
	PORTC = 0x00;
    _delay_ms(50);
    PORTC = 0xFF;
    _delay_ms(50);
}

int main(void)
{
	DDRC = 0xFF; // 출력 모드
    PORTC = 0xFF; // 하이레벨
    DDRD = 0x00; //입력 모드
    PORTD = 0xFF; // 내부 풀업 사용
    
    EICRA = (0 << ISC01) | (0 << ISC00);
    //Low가 들어오는 순간 인터럽트 발생 -> 내부 풀업으로 기본 상태 1 -> 스위치 클릭시 0-> INT0 발생
    EIMSK = (1 << INT0); //INT0 허용
    sei();//글로벌 인터럽트 인에이블
    while(1);
}

회로 설정

D1 VDD n1 ;LED D1이 VDD와 n1 node사이에 연결1
R1 n1 PC0 330 ; 저항 R1을 n1 node와 PC0 사이에 연결

D2 VDD n2
R2 n2 PC1 330

D3 VDD n3
R3 n3 PC2 330

D4 VDD n4
R4 n4 PC3 330

D5 VDD n5
R5 n5 PC4 330

D6 VDD n6
R6 n6 PC5 330

D7 VDD n7
R7 n7 PC6 330

D8 VDD n8
R8 n8 PC7 330

K0 PD0 VSS  LATCHEd ;K0 스위치는 래치타입 

- 래치 스위치를 사용하여 한번 누르면 눌린 상태가 유지됨

-> 눌린 상태서 HIGH, 다시 누르면 LOW로 변함

 

300x250

+ Recent posts