101_인터럽트란_비상전화호출 🚨📞

도로시와 지니가 함께하는 하던 일을 잠시 멈추고 1마이크로초 만에 긴급 처리하는 CPU의 비서 시스템
- 👧 도로시: “지니야! 아두이노 코드가
delay(2000)로 쉬고 있을 때 비상 정지 버튼을 눌렀는데, 아두이노가 2초 동안 멍때리느라 버튼 신호를 완전히 무시하고 지나가 버렸어! 로봇이 벽에 부딪힐 뻔했잖아!” - 🐱 지니: “그게 바로 반복문에서 일일이 상태를 확인하는 ‘폴링(Polling)’의 치명적인 한계야! 그럴 때 아두이노가 무슨 일을 하고 있든 즉시 하던 일을 낚아채서 긴급 명령을 실행하게 만드는 마법이 바로 인터럽트(Interrupt, 가로채기) 란다!”
-
🐶 토토: “바우! 공부하다가 중요한 전화가 오면 책갈피를 꽂아두고 전화부터 받는 거다 멍!”
- 🖥️ 강의 슬라이드: slides.md
1. 도로시의 고민: 폴링(Polling)의 한계와 긴급 상황 무시

🚨 메인 루프가 바쁠 때 발생하는 이벤트 누락(Missed Event)
일반적인 아두이노 스케치는 void loop() 함수를 위에서 아래로 순차 실행합니다.
graph TD
subgraph 순차적 폴링 방식의 한계
L1["1. 센서 값 계산 (수백 ms 소요)"] --> L2["2. LCD 화면 출력 (느림)"]
L2 --> L3["3. delay(1000) 멍때리기"]
L3 --> L4["4. 디지털 핀 버튼 눌렸나 확인 (if문)"]
L4 --> L1
end
Event["사용자가 2번 단계에서 비상 버튼 클릭!"] -.->|"3번 delay 중이라 감지 못함!"| L3
- 폴링(Polling) 방식에서는 루프 도중
delay()나 복잡한 계산이 실행 중일 때 스위치를 누르면 아두이노가 그 신호를 감지하지 못하고 허공으로 날려버립니다. - 산업용 로봇이나 자율주행차에서는 범퍼 충돌 스위치나 비상 정지 버튼이 0.001초라도 씹히면 대형 사고로 이어집니다.
2. 폴링(Polling) vs 인터럽트(Interrupt) 비교

🚪 주기적으로 문을 열어보기 vs 초인종 벨소리에 즉시 반응하기
| 비교 항목 | 폴링 (Polling) | 인터럽트 (Interrupt) |
|---|---|---|
| 비유 | 손님이 왔나 1분마다 문 열어보기 | 손님이 초인종(Ding-Dong)을 누르면 즉시 문 열기 |
| CPU 자원 낭비 | 아무 일도 없는데 계속 핀 상태를 검사함 | 평소엔 메인 연산에 100% 집중 (낭비 제로) |
| 반응 속도 | 루프 한 바퀴를 다 돌 때까지 지연됨 | 신호 발생 즉시 (1마이크로초 이내) 반응! |
| 이벤트 누락 | delay() 중에 버튼을 뗐다 누르면 놓침 |
초고속 펄스도 하드웨어가 절대 놓치지 않음 |
| 주요 사용처 | 온습도 센서 주기적 측정 | 비상 정지 버튼, 엔코더 바퀴 회전수 계수 |
3. 인터럽트 동작의 3단계 흐름: 책갈피와 복귀

📖 Context Save ➡️ ISR 실행 ➡️ Resume의 매끄러운 사이클
하드웨어 인터럽트 신호가 들어왔을 때 ATmega328P 마이크로컨트롤러 내부에서는 다음과 같은 기계적 전환이 발생합니다.
sequenceDiagram
autonumber
participant Main as 메인 프로그램 (void loop)
participant Stack as 스택 메모리 (Stack)
participant HW as 하드웨어 핀 (D2 / D3)
participant ISR as 인터럽트 서비스 루틴 (ISR)
Main->>Main: 모터 구동 및 화면 출력 연산 중...
HW->>Main: 비상 버튼 펄스 발생 (FALLING edge)!
Main->>Stack: 1. 현재 실행 주소(PC)와 레지스터 상태 저장 (책갈피 꽂기)
Main->>ISR: 2. 우선순위 점프! 긴급 ISR 함수로 이동
ISR->>ISR: 모터 즉시 정지 플래그 설정 및 상태 변경
ISR->>Main: 3. 복귀 신호 (RETI)
Stack->>Main: 책갈피 주소를 복원하여 하던 작업 계속 진행
- 책갈피 꽂기 (Context Save):
- CPU가 실행 중이던 프로그램 카운터(PC)와 상태 레지스터(SREG) 값을 스택(Stack) 메모리에 안전하게 백업합니다.
- 비상 출동! ISR (Interrupt Service Routine):
- 미리 등록해 둔 전용 인터럽트 처리 함수(
emergencyStop())로 즉시 건너뛰어 초고속으로 처리합니다.
- 미리 등록해 둔 전용 인터럽트 처리 함수(
- 제자리로 복귀 (Resume):
- ISR 함수가 끝나면 스택에서 책갈피를 꺼내와, 인터럽트가 걸렸던 바로 그 다음 줄부터 아무 일도 없었다는 듯 메인 코드를 이어갑니다.
4. 인터럽트의 2가지 주요 분류

🌐 외부 하드웨어 핀 인터럽트 vs 내부 시스템 인터럽트
- 1. 외부 인터럽트 (External Hardware Interrupt):
- 물리적인 전선 핀에 걸리는 전압이 HIGH에서 LOW로 떨어지거나(FALLING) 전압이 바뀔 때 발동합니다.
- 아두이노 우노(UNO)는 디지털 2번 핀(INT0) 과 디지털 3번 핀(INT1) 단 2개만 지원합니다!
- 2. 내부 인터럽트 (Internal Software / Timer Interrupt):
- 칩 내부의 하드웨어 타이머 카운터가 오버플로우되거나, UART 시리얼 수신 버퍼에 새 글자가 도착했을 때 자동으로 발동합니다.
5. ISR(인터럽트 함수) 작성 시 3대 절대 규칙
- 짧고 굵게 끝내라 (Short & Fast):
- ISR 내부에서는 화면에 글자를 출력(
Serial.println)하거나 오래 기다리는delay()함수를 절대 사용하면 안 됩니다 (delay()는 타이머 인터럽트를 쓰므로 ISR 안에서 영원히 멈춥니다).
- ISR 내부에서는 화면에 글자를 출력(
volatile키워드 필수:- ISR 내부에서 값을 바꾸고 메인
loop()에서도 읽는 전역 변수는 반드시 앞에volatile int count = 0;처럼volatile을 붙여 컴파일러 최적화에 의한 변수 캐싱 오류를 방지해야 합니다.
- ISR 내부에서 값을 바꾸고 메인
- 플래그(Flag) 전달 기법:
- ISR 안에서는
isStopped = true;처럼 깃발(플래그)만 꽂아두고, 실제 무거운 작업은loop()함수가 처리하도록 설계하는 것이 정석입니다.
- ISR 안에서는
🌟 도로시와 지니의 핵심 요약 노트!

- 👧 도로시: “인터럽트는 아두이노가
delay()로 아무리 깊은 잠에 빠져 있어도 1마이크로초 만에 즉시 깨워주는 초인종 비상벨이구나!” - 🐱 지니: “맞아! ISR 함수는 번개처럼 짧게 실행되어야 하며, 공유 변수에는
volatile을 선언한다는 규칙을 꼭 기억하렴.” - 🐶 토토: “바우! 이제 아두이노 2번 핀에 버튼을 달고 외부 인터럽트(
attachInterrupt) 코드를 직접 만들어보자 멍!”
서브목차