33/82
Section 03 인터럽트 활성화와 인터럽트 서비스
루틴 연결
34/82
Section 03 인터럽트 활성화와 인터럽트 서비스 루틴 연결
장치에 대한 인터럽트 설정과 활성화• 내부 장치에 대한 특수 레지스터 존재
• 장치의 특성을 반영한 동작 설정용 또는 상태 관찰용 비트로 구성
• 인터럽트 사건의 발생 패턴을 설정해야 함
• 인터럽트 활성화 비트를 1로 셋하여, 인터럽트 발생을 허락
» 전제, 전역 인터럽트 활성화 비트가 1로 셋 되었을 때
• ATmega128 인터럽트 서비스, 개별 인터럽트 활성화 비트 및 레지스터
35/82
Section 03 인터럽트 활성화와 인터럽트 서비스
루틴 연결
36/82
Section 03 인터럽트 활성화와 인터럽트 서비스
루틴 연결
37/82
Section 03 인터럽트 활성화와 인터럽트 서비스 루틴 연결
전역 인터럽트 I-비트 활성화• 개별 인터럽트가 활성화되고, 전역 인터럽트 비트(SREG의 I-비트)가 1로 셋되어 있을 때, 인터럽트 서비스 루틴이 실행됨
• 인터럽트 사건이 발생하면, 해당 인터럽트 플래그가 1로 설정되고,
• 인터럽트 서비스 루틴이 개시되면, 그 인터럽트 플래그는 클리어됨
38/82
Section 03 인터럽트 활성화와 인터럽트 서비스 루틴 연결
인터럽트 서비스 루틴의 연결
#include <avr/interrupt.h>를 앞에 적어 인터럽트 관련 레이블과 매크로 정의
ISR( ) 함수 인수 위치에 인터럽트 서비스 루틴 명칭을 넣어 작성• ISR(INT0_vect)
• ISR(ADC_vect)
39/82
Section 03 인터럽트 활성화와 인터럽트 서비스 루틴 연결
인터럽트 대기와 실행
동시에 여러 인터럽트가 요청되었을 때는, 작은 숫자의 벡터 값의 인터럽트가 높은 우선순위를 가짐
일반적인 마이크로프로세서• 높은 우선순위의 인터럽트가 발생하면, 현재 인터럽트 서비스 루틴을 중단하고, 새로운 인터럽트 서비스 루틴을 실행
ATmega128• 우선순위가 더 높은 인터럽트가 발생하더라도, 현재 인터럽트 서비스 루틴을 중단하지는 않음
• 인터럽트 서비스 루틴이 종료되면, 대기 (pending) 인터럽트 중에서 우선순위가 높은 인터럽트 서비스 루틴을 수행
40/82
Section 03 인터럽트 활성화와 인터럽트 서비스 루틴 연결
인터럽트 서비스 프로그램 중 요청된 인터럽트 처리
• 인터럽트 1 발생, 인터럽트 1 플래그 셋
• 인터럽트 1 서비스 루틴이 실행되면서,
» SREG의 I-비트와 인터럽트 1의 플래그가 클리어됨
• 인터럽트 2 발생, 인터럽트 2 플래그 셋
• 인터럽트 1 서비스 루틴 종료까지 대기
» 인터럽트 1 서비스 루틴이 종료하면 SREG의 I-비트가 다시 1로 셋
• 인터럽트 2 서비스 루틴이 실행되면서,
» SREG의 I-비트와 인터럽트 1의 플래그가 클리어됨
• 인터럽트 2 서비스 루틴이 종료되면, SREG의 I-비트가 다시 1로 셋
41/82
Section 03 인터럽트 활성화와 인터럽트 서비스 루틴 연결
인터럽트 플래그 비트
인터럽트 플래그가 1이 되어 대기• 인터럽트 서비스 루틴 (interrupt service routine)이 실행되면, 대부분의 인터럽트 플래그 (interrupt flag)는 자동으로 클리어 (clear)됨
» 몇 가지는 수동으로 인터럽트 플래그 클리어 해 주어야 함
만일 대기 중인 인터럽트 플래그에• 소프트웨어적으로 1을 기록하면, 인터럽트 플래그는 클리어
• 대기 중인 인터럽트 해지
42/82
Section 03 인터럽트 활성화와 인터럽트 서비스 루틴 연결
개별 인터럽트 활성화 비트와 인터럽트 플래그 비트43/82
Section 03 인터럽트 활성화와 인터럽트 서비스
루틴 연결
44/82
Section 04 외부 인터럽트
외부 인터럽트 설정과 활성화
디지털 I/O 핀의 디지털 전압레벨을 외부 인터럽트로 감지
EIMSK : 외부 인터럽트 마스크 레지스터 (External Interrupt Mask Register)• 외부 인터럽트 INT0~INT7를 개별적으로 활성화시킬 수 있음
45/82
Section 04 외부 인터럽트
EICRA, EICRB : 외부 인터럽트 제어 레지스터 (External Interrupt Control Register)• 인터럽트 발생 순간을 ISCnx(n은 0~7, x는 0~1) 비트로 설정
46/82
Section 04 외부 인터럽트
외부 인터럽트와 외부 인터럽트 서비스 루틴과의 연결
외부 인터럽트 서비스 루틴을 작성하여, 주 프로그램과 인터럽트를 연결
EIFR : 외부 인터럽트 플래그 레지스터 (External Interrupt Flag Register)• 활성화된 외부 인터럽트는 전역 인터럽트가 활성화되어 있고,
• 설정된 발생 조건을 만족하면,
• 외부 인터럽트 플래그 비트를 1로 셋하고,
• 인터럽트 서비스 루틴 실행 절차가 수행
47/82
Section 04 외부 인터럽트
인터럽트 서비스 루틴 실행 절차(인터럽트 플래그 관점)❶ EICRA, EICRB 레지스터에 설정된 조건이 만족되어 인터럽트 사건 발생
❷ EIFR 레지스터의 해당 인터럽트 플래그 비트(INTF0~INT7)가 1로 셋됨 (인터럽트 사건이 발생된 시점에 다른 인터럽트 서비스 루틴이
실행 중이면, 그 인터럽트 서비스 루틴이 종료될 때까지 대기)
❸ 인터럽트 서비스 루틴으로 진입되면, 인터럽트 플래그 비트는 클리어됨
❹ (예외적) 만일 ②번 단계에서 해당 인터럽트 플래그 비트를 1로 기록하면, ③번 단계를 수행하지 않고, 인터럽트 플래그 비트는 클리어됨
48/82
Section 05 주 프로그램과 인터럽트 서비스 루틴의 요청/응답 인터페이스
인터럽트 서비스 루틴과 요청/응답 인터페이스 절차
인터럽트 서비스 루틴과 요청/응답 인터페이스❶ 주 프로그램은 인터럽트 서비스 루틴과 약속된 전역 변수에 요청을 기록
❷ 인터럽트가 발생하고 인터럽트 서비스 루틴이 실행되면, 요청 동작을 수행한 후 전역 변수에 요청에 대한 응답을 기록
❸ 주 프로그램은 응답을 확인하고, 알고리즘의 진행 단계를 조정
50/82
Section 05 주 프로그램과 인터럽트 서비스 루틴의 요청/응답 인터페이스
주 프로그램과 인터럽트 서비스 사이의 변수 공유
인터페이스 변수는 volatile 지시어를 사용하여 전역 변수로 선언• C 컴파일러는 최적화 과정으로 목적 프로그램으로 간소화
• volatile 지시어를 선언하지 않으면, 간소화에 의해 인터럽트 서비스 루틴과 상호 연관성이 끊어질 수 있음
[예제 6-1] SW0, SW1 각 스위치가 연속으로 5회 이상 눌리면 LED를 반전• 주 프로그램 요청부
» volatile로 선언된 req_INT0, req_INT1 변수로, 인터럽트 서비스 루틴과 인터페이스
» 인터럽트 서비스 루틴이 REPLY로 응답했을 때 LED 반전 LED 반전 명령 PORTA ^= 1<<PA0;
51/82
Section 05 주 프로그램과 인터럽트 서비스 루틴의 요청/응답 인터페이스
• main( ) 함수의 인터럽트 서비스 루틴과 인터페이스부
while(1){
if(req_INT0 = = REPLY){
PORTA ^= 1<<PA0; // INT0에서 응답하면 PA0 비트값 반전 req_INT0 = NOT_REQUEST; // req_INT0 요청 해지
req_INT1 = REQUEST; // req_INT1 요청 }else if(req_INT1 = = REPLY){
PORTA ^= 1<<PA0; // INT1에서 응답하면 PA0 비트값 반전 req_INT0 = REQUEST; // req_INT0 요청
req_INT1 = NOT_REQUEST; // req_INT1 요청 해지 }
}
req_INT0, req_INT1 : 전역 변수
52/82
Section 05 주 프로그램과 인터럽트 서비스 루틴의 요청/응답 인터페이스
• 인터럽트 서비스 루틴 응답부
» ISR(INT0_vect){} 사례
» req_INT0 변수에 REQUEST 요청이 있을 때 동작 - event 변수를 인터럽트가 발생할 때마다 증가 - NUM_EVENT 이상 발생되면 REPLY로 응답
volatile int req_INT0 = REQUEST, req_INT1 = NOT_REQUEST;
ISR(INT0_vect)
{ static long event = 0;
if(req_INT0 = = REQUEST){
event++;
if(event>=NUM_EVENT){
event = 0;
req_INT0 = REPLY;
} } }
53/82
Section 05 주 프로그램과 인터럽트 서비스 루틴의 요청/응답 인터페이스
요청/응답 인터페이스와 인터럽트 과부하 절감
인터럽트 발생 빈도와 주 프로그램 수행• 인터럽트 발생 빈도가 높아지면 원하는 시스템 동작이 되지 않을 수 있음
» 대기하던 인터럽트 서비스 루틴만 실행되고, 주 프로그램이 거의 수행되지 못할 수 있음
» 인터럽트 서비스 루틴에 머무르는 시간을 가능한 짧게 하고 인터럽트의 발생 빈도 를 적게 하는 것이 바람직함
» 인터럽트 서비스 루틴은 수행 시간이 짧은 장치와 관계된 조작 명령, 상태 확인 등과 관련된 간단한 동작을 수행
• 상태 결과에 따른 주된 동작은 요청/응답 인터페이스로, 주 프로그램에서 수행하는 것이 바람직함
54/82
Section 05 주 프로그램과 인터럽트 서비스 루틴의 요청/응답 인터페이스
[예제 6-2] 인터럽트 서비스 루틴의 과부하 절감을 요청/응답 인터페이스 사례• 인터럽트 감지 순간을 결정하는 비트가 (pp. 244)
ISC01 = 0, ISC00 = 0일 때, LOW 디지털 전압레벨이면 인터럽트가 계속 발생
• 강제 시간 지연 delay( ) 함수 위치에 따른 반응 관찰
1. 인터럽트 서비스 루틴 안에서 delay( ) 함수를 실행하는 경우와, 2. 주 프로그램에서 delay( ) 함수를 실행하는 경우의 차이점 확인
55/82
Section 05 주 프로그램과 인터럽트 서비스 루틴의 요청/응답 인터페이스
#include <avr/io.h>
#include <avr/interrupt.h>
// DELAY_IN_ISR
void delay(volatile long count) {
for(; count>0; count--);
} ISR(INT0_vect) {
delay(1000);
}
int main(void) {
EIMSK |= 1<<INT0; // INT0 활성화
EICRA = 0x0; // LOW일때 연속 인터럽트
PORTD |= 1<<INT0; // 내부 저항 풀업 연결 DDRA |= 1<<PA0; // PA0 출력 설정
sei(); // 전역 인터럽트 활성화
while(1){
// DELAY_IN_ISR
delay(200);
PORTA ^= 1<<PA0;
}
return 0;
}
DELAY_IN_ISR
56/82
Section 05 주 프로그램과 인터럽트 서비스 루틴의 요청/응답 인터페이스
#include <avr/io.h>
#include <avr/interrupt.h>
#define DELAY_IN_MAIN
volatile unsigned int req=1;
void delay(volatile long count) {
for(; count>0; count--);
}
ISR(INT0_vect) {
req = 0;
}
int main(void) {
EIMSK |= 1<<INT0; // INT0 활성화
EICRA = 0x0; // LOW일때 연속 인터럽트
PORTD |= 1<<INT0; // 내부 저항 풀업 연결 DDRA |= 1<<PA0; // PA0 출력 설정
sei(); // 전역 인터럽트 활성화
while(1){
#define DELAY_IN_MAIN if(!req){
delay(1000);
req = 1;
}
delay(200);
PORTA ^= 1<<PA0;
}
return 0;
}
DELAY_IN_MAIN
57/82
Section 05 주 프로그램과 인터럽트 서비스 루틴의 요청/응답 인터페이스
• #ifdef
lable_A
--- A ---#else --- B --- #endif
lable_A
라는 이름의 레이블이 정의되어 있으면, --- A --- 부분을 수행 그렇지 않으면, --- B --- 부분을 수행하라는 매크로• #define DELAY_IN_ISR로 DELAY_IN_ISR을 정의하면
ISR(INT0_vect) 인터럽트 서비스 루틴에서 delay( ) 함수 실행
• //#define DELAY_IN_ISR로 DELAY_IN_ISR을 정의해 놓지 않으면
main( ) 함수의 while( ) 반복문에서 delay( ) 함수 실행
58/82
Section 05 주 프로그램과 인터럽트 서비스 루틴의
요청/응답 인터페이스
59/82
Section 05 주 프로그램과 인터럽트 서비스 루틴의 요청/응답 인터페이스
• 결과 관찰
» 스위치를 누르지 않으면, 매우 빠르게 PA0에 연결된 LED를 반전시킴 너무 빨라 LED가 항상 켜진 것처럼 보임
» 스위치 SW0을 누르면, 지속적으로 인터럽트가 요청되어, 인터럽트 서비스 루틴이 수행
» DELAY_IN_ISR을 4번 라인 위치에 두고, 매크로 정의하여, 프로그램 컴파일/링크/다운로드 후 관찰
» DELAY_IN_ISR을 4번 라인 위치에서 삭제하여, 매크로 정의를 없앤 후, 프로그램 컴파일/링크/다운로드 후 관찰
» LED의 점멸 주기의 빠른 정도를 관찰하여, 주 프로그램의 실행 정도를 간접적으로 알 수 있음
60/82
Section 06 포토인터럽터 인터페이스
사전 지식
포토인터럽터는 포토다이오드와 포토트랜지스터를 일체형으로 만든 부품
포토인터럽터 SG-207[(주)광전자 제품]을 중심으로 주요 규격 검토• 약 940[nm]의 적외선이 포토트랜지스터의 베이스로 투과
• 베이스 단자에 전압이 생성되고, 이미터로 충분한 순방향 전류가 흐름
• 컬렉터와 이미터 사이의 스위치를 ON시킴
포토다이오드와 포토트랜지스터 간격에 적외선을 차단시켜 센서 동작61/82
Section 06 포토인터럽터 인터페이스
특성곡선• ATmega128 내부 풀업저항 20[kΩ] 이상 가정
62/82
Section 06 포토인터럽터 인터페이스
적외선 관통 포토트랜지스터에 도달되면 ON, LOW 디지털 전압레벨• 다이오드 순방향 전류 계산
• 12[mA]에 의한 적외선 관통 예측 광전류
• 트랜지스터 ON
트랜지스터의 포화동작을 만족시킴
• 입력 핀 PD0는 전압 VCE(Sat)이 되어 LOW 디지털 전압레벨
• 핀에서 인식되는 논리값은 ‘0’
적외선이 차단되면 포토트랜지스터 OFF, HIGH 디지털 전압레벨• 적외선이 차단되었을 때, 광전류 IL은 0[mA]
• 따라서, 핀에 인가되는 전압은 VCC이 되어 HIGH 디지털 전압레벨
• 핀에서 인식되는 논리값은 ‘1’
63/82
Section 06 포토인터럽터 인터페이스
실험 목적 및 동작
(1) 포토인터럽터의 회로 동작 이해
(2) 빛 차단과 투과가 포토트랜지스터의 ON/OFF로 출력에 미치는 영향
(3-1) 포토인터럽터 출력 신호가 상승하는 에지를 폴링으로 감지하는 방법 (3-2) 포토인터럽터 출력 신호가 상승하는 에지를 인터럽트로 감지하는 방법
• PD0 핀에 연결된 포토인터럽터 간격에 물체로 빛을 차단할 때, PA0에 연결된 LED를 반전하기 위한 회로
64/82
Section 06 포토인터럽터 인터페이스
• 폴링에 의한 포토인터럽터 에지 검사
// PD0가 HIGH 면 1을 취함
// PD0 상승에지 검사
for(i=0; i<100; i++) {
}
65/82
Section 06 포토인터럽터 인터페이스
• 인터럽트 방식에 의한 포토인터럽터 에지 검출
66/82