Chapter. 5 인터럽트 HBE-MCU-Multi AVR Jaeheung, Lee
목차 1. 폴링과인터럽트그리고인터럽트서비스루틴 2. ATMega128 인터럽트 3. 인터럽트로 LED 점멸시키기 4. 인터럽트로스톱워치만들기
인터럽트 1. 폴링과인터럽트그리고인터럽트서비스루틴 2. ATMega128 인터럽트 3. 인터럽트로 LED 점멸시키기 4. 인터럽트로스톱워치만들기
인터럽트 인터럽트 (Interrupt) 방해하다 훼방놓다 어떤작업을진행하고있다가갑자기다른일이발생하여먼저처리해야하는상황을인터럽트발생이라함. 현재수행중인일을잠시중단하고급한일을처리한후원래의일을다시이어서수행 이때, 그급한일을해결하는것이인터럽트서비스루틴임 발생시기를예측할수없는경우에더효율적
인터럽트 인터럽트와인터럽트서비스루틴 인터럽트가발생하면프로세서는현재수행중인프로그램을멈추고 상태레지스터와 PC(Program Counter) 등을스택에잠시저장한후인터럽트서비스루틴으로점프한다. 인터럽트서비스루틴을실행한후에는이전의프로그램으로복귀하여정상적인절차를실행한다. 원 래 하 던작업 인터럽트발생 중단 복귀 인터럽트가발생하면실행할내용 ( 인터럽트서비스루틴 )
폴링과인터럽트 마이크로컨트롤러의외부상황입력방법 폴링 (polling) : 사용자가명령어를사용하여입력핀의값을계속읽어서변화를알아내는방식 인터럽트 (interrupt) : MCU 자체가하드웨어적으로그변화를체크하여변화시에만일정한동작을하는방식
인터럽트 인터럽트의구성요소 발생원 : 누가인터럽트를요청했는가? 우선순위 : 2개이상의요청시누구를먼저서비스할까? ( 중요도 : Priority) 인터럽트벡터 : 서비스루틴의시작번지는어디인가?
인터럽트 인터럽트의종류 발생원인에따른인터럽트분류 n 내부인터럽트 n 외부인터럽트 차단가능성에의한인터럽트분류 n 차단 ( 마스크 ) 불가능 (Non maskable, NMI ) 인터럽트 n 차단 ( 마스크 ) 가능 (Maskable) 인터럽트 인터럽트조사방식에따른분류 n 조사형인터럽트 (Polled Interrrupt) n 벡터형인터럽트 (Vectored Interrupt)
ATMega128 인터럽트 ATMega128 인터럽트 차단가능한외부인터럽트 리셋포함총 35개의인터럽트벡터를가짐 n 리셋 1개 n 외부핀을통한외부인터럽트 8개 n 타이머관련 14개 n 타이머 0(2 개 ), 타이머 1(5 개 ), 타이머 2(2 개 ), 타이머 3(5 개 ), n UART 관련 6 개 n USART0(3 개 ), USART1(3 개 ), n 기타 6 개
ATMega128 인터럽트 ATMega128 인터럽트 모든인터럽트는전역인터럽트인에이블비트인 SREG 의 I 비트와각각의개별적인인터럽트플래그비트가할당되어있다. 인터럽트들과개개의리셋벡터는각각개별적인프로그램벡터를프로그램메모리공간내에가진다. 모든인터럽트들은개별적인인터럽트허용비트를할당받는다. 특정인터럽트를가능하게하려면특정인터럽트가능비트와상태레지스터 (SREG) 에있는전체인터럽트허용비트 (I 비트 ) 가모두 1 로세트되어있어야한다.
ATMega128 인터럽트 상태레지스터 (SREG:Status REGister) ALU 의연산후상태와결과를표시하는레지스터 7 6 5 4 3 2 1 0 I T H S V N Z C 비트 I T H S V N Z C 설명 Global Interrupt Enable Bit Copy Storage Half Carry Flag Sign Bit 2's Complement Overflow Flag Negative Flag Zero Flag Carry Flag
ATMega128 인터럽트 인터럽트마스크레지스터 (EIMSK : External Interrupt MaSK register) 외부인터럽트의개별적인허용제어레지스터 INTn 이 1 로세트되면외부인터럽트인에이블 7 6 5 4 3 2 1 0 INT7 INT6 INT5 INT4 INT3 INT2 INT1 INT0 비트 INT7~0 설명 Int7~0 Interrupt Enable
ATMega128 인터럽트 ATMega128 인터럽트우선순위 프로그램메모리공간에서최하위주소는리셋과인터럽트벡터로정의되어있다. 리스트는서로다른인터럽트들의우선순위를결정한다. 최하위주소에있는벡터는최상위주소에있는벡터에비해우선순위가높다. n RESET : 최우선순위 n INT0(External Interrupt Request 0) : 2 순위 MCU 제어레지스터 (MCUCR: MCU Control Register) 의 IVSEL(Int errupt Vector SELect) 비트를세팅함으로써인터럽트벡터의배치를변경할수있다.
ATMega128 인터럽트 외부인터럽트의트리거 인터럽트를발생시키기위한 방아쇠 인터럽트발생의유무를판단하는근거가됨. 트리거방법 n n Edge Trigger : 입력신호가변경되는순간을인터럽트트리거로사용하는경우 n n 하강에지 (Falling Edge) 트리거 : 1 에서 0 로변경되는시점을사용 상승에지 (Rising Edge) 트리거 : 0 에서 1 로변경되는시점을사용 n ATMega128 에서에지트리거는 50ns 이상의펄스폭을가져야한다. Level Trigger : 입력신호가일정시간동안원하는레벨을유지되면트리거하는경우 n 평상시 High(1) 로있다가 Low(0) 로변화되어일정시간유지되면트리거하게됨. n 레벨트리거인터럽트신호는워치독오실레이터에의해 2 번샘플링되며이기간이상의펄스폭을주어야한다.
ATMega128 인터럽트 EICRA(External Interrupt Control Register A) 외부인터럽트 0~3 의트리거설정에사용 7 6 5 4 3 2 1 0 ISC31 ISC30 ISC21 ISC20 ISC11 ISC10 ISC01 ISC00 ISCn1 ISCn0 설명 0 0 INT의 Low level에서인터럽트를발생한다. 0 1 예약 1 0 INT의하강에지에서인터럽트를발생한다. 1 1 INT의상승에지에서인터럽트를발생한다.
ATMega128 인터럽트트리거 EICRB(External Interrupt Control Register B) 외부인터럽트 4~7 의트리거설정에사용 7 6 5 4 3 2 1 0 ISC71 ISC70 ISC61 ISC60 ISC51 ISC50 ISC41 ISC40 ISCn1 ISCn0 설명 0 0 INTn1의 Low level에서인터럽트를발생한다. 0 1 INTn 핀에논리적인변화가발생할경우 1 0 INT의하강에지에서인터럽트를발생한다. 1 1 INT의상승에지에서인터럽트를발생한다.
ATMega128 인터럽트트리거 EICRB(External Interrupt Control Register B) 외부인터럽트 4~7 의트리거설정에사용 7 6 5 4 3 2 1 0 ISC71 ISC70 ISC61 ISC60 ISC51 ISC50 ISC41 ISC40 ISCn1 ISCn0 설명 0 0 INTn1의 Low level에서인터럽트를발생한다. 0 1 INTn 핀에논리적인변화가발생할경우 1 0 INT의하강에지에서인터럽트를발생한다. 1 1 INT의상승에지에서인터럽트를발생한다.
ATMega128 인터럽트동작 EIFR(Interrupt Flag Register) 외부인터럽트발생여부를알려주는레지스터 외부인터럽트가에지트리거에의해요청된경우허용여부에상관없이 1 로세트 7 6 5 4 3 2 1 0 INTF7 INTF6 INTF5 INTF4 INTF3 INTF2 INTF1 INTF0 비트 설명 INTF7~0 IntF7~0 Interrupt Flag
ATMega128 인터럽트 ATMega128 인터럽트프로그램 인터럽트프로그램의틀 #include <io.h> #include <interrupt.h> /* 인터럽트관련시스템헤더파일 */ SIGNAL(SIG_INTERRUPT0) /* Int0에대한 Interrupt Service Routine 선언 */ { /* 인터럽트가발생되었을때실행할명령어세트를선언 */ } int main(void) { DDRD = 0xFE; /* 인터럽트입력으로 D 포트를사용 */ EIMSK = 0x01; /* external interrupt 0 을 Enable*/ sei(); /* 전체인터럽트 Enable */ for (;;) { /* main loop 명령어세트 */ }
실습 5 : 인터럽트로 LED 점멸 실습개요 ATmega128 마이크로컨트롤러의인터럽트기능을이용하여 LED 를점멸시키는실습 일정시간마다 LED 가순차적으로켜지도록하고, 버튼스위치를누르면 LED 가멈추었다가다시누르면동작하도록한다. 버튼스위치가눌려지면인터럽트가발생하도록해야한다. 입력포트 1 개 ( 인터럽트가가능한포트 ), 출력포트 1 개사용 실습목표 인터럽트발생원리이해 인터럽트제어방법의습득 ( 관련레지스터이해 ) 입출력포트에관한이해 ( 특히인터럽트관련포트 )
실습 5 : 인터럽트로 LED 점멸 사용모듈 : MCU 모듈, LED 모듈, Switch 모듈 MCU 모듈포트 E MCU 모듈포트 D MCU 모듈 LED 모듈 LED 모듈 Signal Switch 모듈버튼스위치 Signal Switch 모듈
실습 5 : 인터럽트로 LED 점멸 모듈결선방법 MCU 모듈포트 E 의 PE0 ~PE7 을 LED 모듈의 LED 0 ~ 7 까지연결 MCU 모듈포트 D 의 PD0 를 2 핀케이블로 Switch 모듈의 BT0 에연결
실습 5 : 인터럽트로 LED 점멸 구동프로그램 : 사전지식 인터럽트를위한입력포트선택 n 포트 D의 0번비트는 Int0로서, 인터럽트로사용할수있는포트임. 외부인터럽트 Enable n 상태레지스터 (SREG) 의전체인터럽트허용비트 (I 비트 ) 를 1 로세팅 n Int0의인터럽트마스크레지스터의 0번비트를 1로세팅. 인터럽트트리거방법정의 n 상승에지에서트리거하도록 EICRA 레지스터를세팅. 전체인터럽트 Enable n sei(); Main 루틴기술 인터럽트서비스루틴의선언 n SIGNAL( 인터럽트소스명 ); 방식을사용
실습 5 : 인터럽트로 LED 점멸 구동프로그램 : 소스분석 Interrupt_led.c 1) 2) 3) #include<avr/io.h> #include<avr/interrupt.h> #include<util/delay.h> unsigned char Time_STOP = 0; SIGNAL(SIG_INTERRUPT0); /* 인터럽트서비스루틴선언 */ int main(){ unsigned char LED_Data = 0x01; DDRD = 0xFE; /* 포트 D의 0 번째레지스터를사용하여입력 (0xFE는 1~7비트까지의레지스터를의미 ) */ DDRE = 0xFF; /* 포트 E의 0~7번째까지의모든레지스터를출력으로사용 */
실습 5 : 인터럽트로 LED 점멸 4) 5) EICRA = 0x0F; EICRB = 0x00; EIMSK = 0x01; EIFR = 0x01; sei(); while(1){ /* 0~3비트까지 1 로두어인터럽트0에서상승에지를발생한다. (EICRA: Interrupt sense control 및 MCU의일반적인기능을설정하는데사용 ) */ /* 0비트가 1 로셋되고, SREG 레지스터의 I비트가 1 로설정되어있으면외부인터럽트는 enable된다. (EIMSK: INT0~INT7의개별인터럽트를설정 ) */ /* 0비트가 1 로셋되고, SREG 레지스터의 I비트와 EIMSK 레지스터의 INT7~INT0비트가 1 로설정되어있으면, MCU는해당하는인터럽트벡터로점프한다. (EIFR: EIMSK 레지스터에서설정한개별인터럽트의상태를나타냄 ) */
실습 5 : 인터럽트로 LED 점멸 6) 7) PORTE = LED_Data; /* 포트E를 LED_Data로두고, LED_Data를하나씩쉬프트시킨다. */ if(time_stop == 0) { if(led_data == 0x80) LED_Data = 0x01; else LED_Data <<= 1; } _delay_ms(100); } return 0; } SIGNAL(SIG_INTERRUPT0){ // Stop/Resume 처리 cli(); if(time_stop == 0) Time_STOP = 1; else Time_STOP = 0; sei(); } 인터럽트서비스루틴
실습 5 : 인터럽트로 LED 점멸 실행결과
실습 6 : 인터럽트를이용한스톱워치 실습개요 스위치모듈과 Array-FND 모듈에연결하여스톱워치를제작 일정시간마다클럭에의해 FND 에숫자와문자가디스플레이되도록하고, 스위치를누르면 FND 디스플레이가초기화되도록하며, 또한다른버튼을누르면잠시멈추었다가다시이어서동작을하도록한다. 포트 D 의 0 번비트와 1 번비트를 Int0 와 Int1 의인터럽트로사용 n Int0 에의해서스톱워치의 Stop/Resume 기능을구현. n Int1 을이용하여스톱워치의리셋기능을구현. 스톱워치의표시는 Array FND 를사용한다. 실습목표 인터럽트활용방법의습득 ( 관련레지스터이해 ) Array FND 동작원리이해
실습 6 : 인터럽트를이용한스톱워치 7-Segment FND Array 스톱워치등 7-segment FND 를여러개 Array 로묶어서사용 7-Segment 의출력은공통으로연결하고, 출력할위치를지정하는 c om1 ~ com4 의값을제어하여원하는숫자나문자를표시
실습 6 : 인터럽트를이용한스톱워치 7-Segment FND Array 구동원리 4 개의 7-Segment 에 1234 의숫자를표시하기위한방법 데이터 : 00000110 Com 1~4 : 0111 데이터 : 01011011 Com 1~4 : 1011 데이터 : 01100110 Com 1~4 : 1110 데이터 : 01001111 Com 1~4 : 1101 H G F E D C B A 0 1 0 0 1 1 1 1 Com1 Com2 Com3 Com4 1 1 0 1
실습 6 : 인터럽트를이용한스톱워치 사용모듈 : MCU 모듈, ArrayFND 모듈, Switch 모듈 MCU 모듈포트 G MCU 모듈포트 E MCU 모듈포트 D MCU 모듈 ArrayFND 모듈 ArrayFND 모듈 Signal Switch 모듈버튼스위치 Signal Switch 모듈
실습 6 : 인터럽트를이용한스톱워치 Array-FND 모듈의회로도
실습 6 : 인터럽트를이용한스톱워치 모듈결선방법 MCU 모듈포트 G 의 PG0~PG3 는 Array FND 모듈의 C0~C3 포트에연결 MCU 모듈포트 D 의 PD0 와 PD1 을 Switch 모듈의 BT0 및 BT1 에연결 MCU 모듈포트 E 의 PE0~PE7 를 Array FND 모듈의 A~H 까지연결.
실습 6 : 인터럽트를이용한스톱워치 구동프로그램 : 사전지식 인터럽트를이용하여스톱워치와비슷한기능을하도록만든것이다 FND Array 는 A~H 까지의각 7-Segment 의 LED 를켜기위한신호를사용 n n 위치선택신호 (C3~C0) 잔상효과를위해약간의시간지연이필요 C3~C0 는 MCU G 포트의 PG3~PG0 에연결되어있고, A~H 포트는 MC U E 포트의 PE7~PE0 연결 입출력포트 D 의 0 번비트는 Int0 로서, 1 번비트는 Int1 으로사용 스톱워치와유사하게기능을하도록만들어진것으로실제로정확한시간을잴수있는완전한스톱워치가아님 n n 매인함수의 While-Loop 를한바퀴돌아온시간을 10ms 으로간주 상대적인시간
실습 6 : 인터럽트를이용한스톱워치 구동프로그램 : 소스분석 Interrupt_stopwatch.c 1) #include<avr/io.h> #include<avr/interrupt.h> #include<util/delay.h> unsigned char time_10ms=0,time_100ms=0,time_1s=0,time_10s=0; char Time_STOP = 0; 2) SIGNAL(SIG_INTERRUPT0); SIGNAL(SIG_INTERRUPT1); int main(){ unsigned char FND_DATA_TBL[] = {0x3F, 0X06, 0X5B, 0X4F, 0X66, 0X6D, 0X7 C, 0X07, 0X7F, 0X67, 0X77, 0X7C, 0X39, 0X5E, 0X79, 0X71, 0X08, 0X80}; 3) DDRD = 0xFC; /* 포트 D 의 0,1 번째레지스터를사용하여입력 (0xFC 는 2~7 DDRG = 0x0F; DDRE = 0xFF; 비트까지의레지스터를의미 ) */ // 포트 G 의 0~3 번째까지의레지스터를출력으로사용 // 포트 E 의 0~7 번째까지의모든레지스터를출력으로사용
실습 6 : 인터럽트를이용한스톱워치 4) EICRA = 0x0F; /* 0~3비트까지 1 로두어인터럽트0과 1에서상승에지를발생한다. (EICRA: Interrupt sense control 및 MCU의일반적인기능을설정하는데사용 ) */ EICRB = 0x00; EIMSK = 0x03; /* 0~1비트까지 1 로셋되고, SREG 레지스터의 I 비트가 1 로설정되어있으면외부인터럽트는 enable된다. */ // (EIMSK: INT0~INT7의개별인터럽트를설정 ) EIFR = 0x03; /* 0~1비트까지 1 로셋되고, SREG 레지스터의 I비트와 EIMSK 레지스터의 INT7~INT0비트가 1 로설정되어 있으면, MCU는해당하는인터럽트벡터로점프한다. /* (EIFR: EIMSK 레지스터에서설정한개별인터럽트의 상태를나타냄 ) */ 5) sei(); while(1){
실습 6 : 인터럽트를이용한스톱워치 6) PORTG = 0x07; // C3을선택한다 PORTE = FND_DATA_TBL[time_10ms]; /* FND_DATA_TBL배열에서 time_10ms 만큼의 FND데이터 를출력한다. */ _delay_ms(2); // 잔상을남게하기위한딜레이 PORTG = 0x0B; //C2를선택 PORTE = FND_DATA_TBL[time_100ms]; _delay_ms(2); PORTG = 0x0D; //C1을선택 PORTE = FND_DATA_TBL[time_1s] 0x80; _delay_ms(3); PORTG = 0x0E; //C0을선택 PORTE = FND_DATA_TBL[time_10s]; _delay_ms(3); if(time_stop == 1) continue; // 인터럽트에의한 Stop/Resume 처리 /* 여기까기사용된딜레이함수가약 10ms이므로 time_10ms는 10ms마다증가된다. */
실습 6 : 인터럽트를이용한스톱워치 6) time_10ms++; if(time_10ms == 10){ time_10ms = 0; time_100ms++ ; } if(time_100ms == 10){ time_100ms = 0; time_1s++ ; } if(time_1s == 10){ time_1s = 0; time_10s++ ; } if(time_10s == 10){ time_10s = 0; } } return 0; }
실습 6 : 인터럽트를이용한스톱워치 7) SIGNAL(SIG_INTERRUPT0){ // Stop/Resume 처리 cli(); if(time_stop == 0) Time_STOP = 1; else Time_STOP = 0; sei(); } 인터럽트서비스루틴 0 : 스톱워치의 Stop/Resume 처리 8) SIGNAL(SIG_INTERRUPT1){ // 리셋 cli(); time_10ms = 0; time_100ms = 0; time_1s = 0; time_10s = 0; sei(); } 인터럽트서비스루틴 1 : 스톱워치의 Reset 처리
실습 6 : 인터럽트를이용한스톱워치 실행결과