스위치를 사용한 외부 인터럽트
상승엣지(rising edge) - 버튼을 누를 때 (L->H)
하강엣지(falling edge) - 버튼에서 손을 뗄 때 (H->L)
High 0V
Low 5V
EICRA,EICRB - 외부 인터럽트 트리거 방식 설정
EICRA (0x69)
INT3 |
INT2 |
INT1 |
INT0 |
ISC31 |
ISC30 |
ISC21 |
ISC20 |
ISC11 |
ISC10 |
ISC01 |
ISC00 |
0 0 : INTn의 low 레벨에서 인터럽트
0 1 : Any edge
1 0 : INTn의 falling edge에서 인터럽트
1 1 : INTn의 rising edge에서 인터럽트
EICRB (0x6A)
INT7 |
INT6 |
INT5 |
INT4 |
ISC71 |
ISC70 |
ISC61 |
ISC60 |
ISC51 |
ISC50 |
ISC41 |
ISC40 |
0 1 : 논리값 변화에 의한 인터럽트
EIMSK (0X3D)
외부인터럽트 INT0~INT7를 개별적으로 허용하는 레지스터
(여러문을 관할하는 관문이라고 할 수 있음)
EIMSK=(1<<INT0); // INT 0 활성화
EIMSK=(1<<INT0) | (1<<INT3); // INT 0, 3 활성화
SREG (0x5F)
인터럽트를 열기위한 마지막 관문이라고도 할 수 있음.
7번째 bit를 1로 바꾸면 전역 인터럽트 활성화
Interrupt Vector Table
address의 $는 16진수(0x)를 의미
vector number와 주소, 소스, 그리고 인터럽트 정의를 볼 수 있다.
실습
SW6 을 누를때 인터럽트, LED에 불이 들어오고 나가도록 실습한다.
채터링 현상은 하드웨어적으로 개선할 수 없다면 지연을 통해 소프트웨어적으로 해결한다.
실습 예제
|
#define DDRA (*((volatile unsigned char *)0x21))
#define PORTA (*((volatile unsigned char *)0x22))
#define PINA (*((volatile unsigned char *)0x20))
#define EICRA (*((volatile unsigned char *)0x69))
#define EICRB (*((volatile unsigned char *)0x6A))
#define EIMSK (*((volatile unsigned char *)0x3D))
#define SREG (*((volatile unsigned char *)0x5F))
#define INT7 7
#define INT6 6
#define INT5 5
#define INT4 4
#define INT3 3
#define INT2 2
#define INT1 1
#define INT0 0
#define ISC7 6
#define ISC6 4
#define ISC5 2
#define ISC4 0
#define ISC3 6
#define ISC2 4
#define ISC1 2
#define ISC0 0
#define sei() __asm__ __volatile__ ("sei" ::) //sei(); 어셈블리어로 7번비트만 1로 만듬
#define sleep() __asm__ __volatile__ ( "sleep" "\n\t" :: )
void __vector_1 (void) __attribute__((signal, used, externally_visible)); //신호 사용,외부 호출
int main(void)
{
DDRA=0xFF;
PORTA=0x00;
EICRA=(3<<ISC0); // INT0 0000 0011 3 (2진수 11 = rising edge)
EIMSK=(1<<INT0); // INT0 Enable
SREG=SREG|(1<<7); // sei(); 와 같음
while(1)
{
sleep(); // cpu 부하를 줄임
}
return 0;
}
void __vector_1 (void) // $0002 INT0 외부 인터럽트 요청
{
volatile unsigned int uiCnt;
for(uiCnt = 0; 30000>uiCnt ; ++uiCnt); // 채터링 현상을 s/w적으로 개선하기 위함
PORTA=~PORTA; // ~은 NOT 연산자, 비트반전
}
|