일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- #MCU
- 인터럽트
- xilinx
- github
- petalinux
- git
- Database
- #textLCD
- Linux
- #문자열
- #CLCD
- ubuntu
- #UART
- #ComportMaster
- Interrupt
- #PuTTY
- ATMEGA128
- sqlite
- SQLite Studio
- #Atmega128
- #채터링
- zynq
- avr
- #시리얼통신
- Embedded linux
- ubutu
- Today
- Total
재잼재잼의 티스토리
10. 외부 인터럽트 본문
MCU를 사용할 때, 중요하게 사용되는 인터럽트에 관한 내용이다.
인터럽트는 쉽게 정상적인 작업을 수행하는 도중에 비정상적인 이벤트가 발생하면, 수행하던 작업을 잠시 중단하고 발생한 이벤트에대한 처리를 수행한다. 이벤트 처리가 완료되면 다시 정상적인 작업으로 복귀하여 중단된 작업을 다시 수행하는 형태로 동작한다.
이때 발생하는 비정상적인 이벤트를 "인터럽트"라고 하고, 이를 처리하기 위해 실행되는 일련의 과정을 ISR(Interrupt Service Routine)이라고 한다.
데이터 시트를 보면, ATmega128에서 발생하는 내부, 외부인터럽트에 대한 내용이다.
전부 35개의 인터럽트가 있는데, 인터럽트 벡터 번호가 낮을 수록 높은 우선순위로 동작한다.
즉, ADC를 예로 들면 ADC변환 완료 인터럽트(22)와 외부인터럽트(2)가 동시에 발생한다면, 우선순위에 따라서 외부인터럽트가 먼저 실행되는 것이다.
하지만, 이미 ADC인터럽트가 실행되는 중에는 자동적으로 SREG(상태레지스터)의 I(전역인터럽트 비트)를 0으로 Clear해서 다른 인터럽트가 발생하지 않는다.
또한, 각 인터럽트에 Program Address가 있는데, 이것은 인터럽트가 발생되었을 경우에 실행할 ISR의 주소를 의미한다.
인터럽트가 발생하면, 발생한 인터럽트를 인터럽트 벡터 테이블에서 찾는다. 이후, Program Address를 찾고, 해당 주소로 이동하여 ISR을 처리하게 된다.
ATmega128에서는 외부인터럽트 (INT0~INT7) 8개를 지원한다. 나머지는 내부적으로 발생하는 내부 인터럽트다.
ATmega128의 외부인터럽트 핀은 PD0 ~ PD3, PE4 ~ PE7 까지 8개가 있다.
외부 인터럽트는 인터럽트핀(입출력핀)에 입력되는 데이터 또는 상태의 변화에 의해 발생한다. 예를 들면 버튼을 누름으로 인해 입력값이 HIGH에서 LOW로 변하는 순간(하강엣지)과 같은 변화에의해 발생한다.
-----------------------------------------
외부인터럽트를 사용하기 위해서 필요한 레지스터를 알아보자.
1. EIMSK (External Interrupt Mask Register)
외부인터럽트 마스크 레지스터다.
8개의 비트에 INT7~INT0까지 각각 할당되어있다. 각 비트의 값에 따라 해당 인터럽트를 허용 여부를 결정할 수 있다.
2. EICRA (External Interrupt Control Register A)
외부인터럽트 제어 레지스터 A이다. INT0 ~ INT3까지의 외부 인터럽트 발생시점을 결정한다. 위에서 이야기 했지만, 외부인터럽트의 발생은 입력되는 데이터, 상태의 변화에따라 발생하기 때문에, 그 시점을 결정해주는 레지스터다.
ISCx0, ISCx1 (x : 3~0) 외부인터럽트 하나당 2개의 비트를 사용하여 표현한다.
0, 0 : INTn의 입력값이 LOW일 때, 인터럽트 발생
1, 0 : INTn의 입력값이 하강엣지 일 때, 인터럽트 발생. (HIGH에서 LOW로 변하는 순간)
1, 1 : INTn의 입력값이 상승엣지 일 때, 인터럽트 발생. (LOW에서 HIGH로 변하는 순간)
3. EICRB (External Interrupt Control Register B)
외부인터럽트 제어 레지스터 B이다. 위의 EICRA와 동일한 역할을 INT4 ~ INT7에 적용한다.
한가지 다른점이 있다면, ISCn1 : ISCn0 = 0 : 1로 인터럽트 발생시점을 결정할 수 있다.
해당 옵션은 상승엣지 또는 하강엣지 모두에 반응하여 인터럽트를 발생할 수 있고, 나머지는 동일하다.
4. EIFR (External Interrupt Flag Register)
외부 인터럽트 플래그 레지스터다. 이름에서 알 수 있듯이, 인터럽트가 발생하면 해당하는 비트가 set되는 레지스터다.ㅣ
5. SREG의 I 비트.
인터럽트에서 가장 중요한 비트. 바로 상태레지스터의 I비트다. 전역 인터럽트 발생을 허용하는 비트로, 기본값은 0이다.
말 그대로 전역인터럽트 발생을 허용하기 때문에, 내부, 외부 등 모든 인터럽트의 발생을 허용한다.
그러므로 외부인터럽트를 사용하기 위해서는 각각의 인터럽트 허용을 위해 EIMSK레지스터의 설정 또한 필요하다.
------------------------------------------------
ISR(interrupt service routine)작성.
실제로 인터럽트가 발생하면, 해당 인터럽트를 처리하기 위해서 ISR을 실행하게 된다.
#include <avr/interrupt.h>
ISR(--interrupt_vector--){
...
}
ISR은 위와 같이 정의된다. 매개변수로 인터럽트 벡터의 이름을 가진다.
ADC에서 사용했듯이,
ISR(ADC_vect){
...
}
와 같이 작성할 수 있다.
ADC_vect는 ADC변환이 완료되었을때 발생하는 내부 인터럽트(22)로써, MCU가 작업을 수행하는 도중, ADC변환이 완료되면, ADC인터럽트가 발생하게되고, ADC_vect로 이동하여 ISR을 실행한다고 볼 수 있다.
-------------------------------------------------
다음번에는 외부 인터럽트를 사용해서 코드를 작성해보도록 하자.
'MCU' 카테고리의 다른 글
9. ADC 및 Cds 사용하기 (1) | 2019.01.28 |
---|---|
8. CLCD 사용하기(2) (0) | 2019.01.23 |
7. CLCD 사용하기 (0) | 2019.01.22 |
6. UART 문자열 송/수신 (0) | 2019.01.16 |
5.UART 문자 송/수신 (0) | 2019.01.15 |