400 likes | 787 Views
Interrupt. Interrupt. an asynchronous signal indicating the need for attention hardware interrupt/software interrupt call “interrupt service routine”(interrupt handler, interrupt routine) interrupt source/interrupt vector/interrupt priority. 생활 속에 인터럽트. Gom player. cell phone. 영화 감상. 1
E N D
Interrupt • an asynchronous signal indicating the need for attention • hardware interrupt/software interrupt • call “interrupt service routine”(interrupt handler, interrupt routine) • interrupt source/interrupt vector/interrupt priority
생활 속에인터럽트 Gom player cellphone 영화 감상 1 2 3 4 스팸 문자 interrupt interrupt 중요 1 2 3 4 5 영화 정지 답신 5 6 7 8 … 재생 시간
program with or without interrupt with interrupt without interrupt b = *ADC0; c = *ADC1; a = b+c; b = *ADC0; c = *ADC1; a = b+c; i=0; while(i<10){ a += b; i++; } if ( a>10 ) a = c; else a = b; i=0; while(i<10){ a += b; i++; } interrupt service routine(ISR)
interrupt is an asynchronous event b = *ADC0; b = *ADC0; c = *ADC1; a = b+c; if ( a>10 ) a = c; else a = b; if ( a>10 ) a = c; else a = b; ISR c = *ADC1; a = b+c; i=0; while(i<10){ a += b; i++; } i=0; while(i<10){ a += b; i++; } ISR
c.f.) function in program b = *ADC0; c = *ADC1; a = b+c; b = *ADC0; c = *ADC1; a = b+c; func(); i = 0; while(i<10){ a += b; i++; } void func(){ if ( a>10 ) a = c; else a = b; } i=0 while(i<10){ a += b; i++; }
Interrupt 처리 과정 • Interrupt request from an interrupt source • 예) INT0 Signal • If masked, ignore the interrupt. • Program counter(PC) is saved. • PC is changed to the program address according to the interrupt source • 예) PC <= 0x0002 • Jump to the Interrupt Service Routine (ISR) • 예) jmp EXT_INT0 (PC <= EXT_INT0) • After the end of ISR, PC is restored.
Interrupt Vector Table • memory address of an interrupt service routine
External Interrupt : INT0~INT7 • INT0~INT3 : PD0~PD3 (Port D) • INT4~INT7 : PE4~PE7 (Port E)
Global Interrupt Enable • SREG(Status Register) • I (7 bit) : Global Interrupt Enable • 전체 인터럽트를 허용하도록 설정하는 비트 • ‘1’ : interrupt enable • ‘0’ : interrupt disable • SEI : ‘1’ 로변경 (interrupt enable) • CLI : ‘0’으로 변경 (interrupt disable)
EIMSK register • External Interrupt MaSK register • External Interrupt (INT0~INT7)의 허용 여부를 제어 • ‘1’ : enable • ‘0’: disable • 예) EIMSK = 0xA4; • address : 0x59
External Interrupt Control Register (EICRA, EICRB) • Interrupt Trigger • Level trigger • low level : ‘0’ 상태이면 interrupt trigger • high level : ‘1’ 상태이면 interrupt trigger • Edge trigger • rising edge : ‘0’ -> ‘1’ 이면 interrupt trigger • fallingedge : ‘1’ -> ‘0’ 이면 interrupt trigger • EICRA, EIRCB 0x6A 0x5A
예) Enable Interrupt • INT0, rising edge • DDRD &= 0xFE; /* PD0 : interrupt source, input */ • EICRA = 0x03; • EIMSK = 0x01; • sei(); /* global interrupt enable */ • SEI instruction의 C code, mnemonic code • cli(); /* global interrupt disable */ • INT7, falling edge; • DDRE &= 0xEF; /* PE7 : interrupt source, input */ • EICRB = 0x80; • EIMSK = 0x80; • sei(); /* global interrupt enable */
Interrupt Service Routine • ISR(vector, attributes) • Format of WinAVR • C:\WinAVR-20100110\doc\avr-libc\avr-libc-user-manual.pdf 의 p.233 ~ • vector : interrupt source • p.237의 표 참조 • 예) INT0_vect : external interrupt 0 (PD0) • attributes : interrupt 속성, 생략 가능 • 예) ISR(INT0_vect) { • … • } /* external interrupt 0 (PD0)가 발생할 때 ISR */
Interrupt Vector Table Initialize • WinAVR : • ISR(vector, attributes) • ISR의 시작 번지가 자동으로 해당 vector table에 저장 • ingeneral (예) • unsigned int *ivt; • ivt = (unsigned int *)0x0002; • *ivt = int_service_routine; • /* C program에서는 함수의 이름이 주소를 나타냄 */ … • … • void int_service_routine(){ /* interrupt service routine */ • … • }
Interrupt Priority & EIFR • 인터럽트의 우선 순위 • 두 개 이상의 인터럽트가 동시에 발생될 경우 • 하위 주소의 인터럽트가 상위 주소의 인터럽트 보다 우선 순위가 높다 • 예) INT0 > INT1 > … > USART0 > … • interrupt flag register (EIFR) • External Interrupt (INT0~INT7)의 발생 여부를 나타냄
Interrupt 실습 #include <avr/io.h> #include <avr/interrupt.h> int main(){ DDRD = 0x18; EICRA = 0x02; /* falling edge */ EIMSK = 0x01; /* left S/W interrupt enable */ sei(); /* SEI instruction의 C code, mnemonic code */ while(1); return 0; }
Interrupt Service Routine ISP(INT0_vect) { PORTD |= 0x10; }
In flash program memory Reset or Restart 0x0000 : jmp 0x0054 0x0002 : jmp 0x00a0 … 0x0054 : …. … 0x00a0 : …. …. …. : reti INT0 (left S/W) main program interrupt service routine
Interrupt 실습 : LED 다시켜기, while문만 변경 #include <avr/io.h> #include <avr/interrupt.h> int main(){ … sei(); while(1) { if( (PIND & 0x01) == 1 ) PORTD &= 0xEF; } return 0; }
Interrupt 실습 : INT1 (RIGHT) #include <avr/io.h> #include <avr/interrupt.h> int main(){ DDRD = ________; EICRA = ________; EIMSK =________; sei(); while(1); return 0; }
Interrupt Service Routine ISR(INT1_vect) { PORTD |= 0x10; }
실습 : INT0, INT1 모두 사용 #include <avr/io.h> #include <avr/interrupt.h> int main(){ DDRD = ________; EICRA = ________; EIMSK =________; sei(); while(1); return 0; }
실습 : INT0, INT1 모두 사용 ISP(INT0_vect) /* Left S/W => LEDOff */ { PORTD |= 0x10; } ISR(INT1_vect) /* Right S/W => LEDOn */ { PORTD &= 0xEF; }
main switch problem : wait-polling int main() { … while (1) { cmd = rxd_char(); if( main S/W is left) { Motor Off; } else { switch(cmd){ case … unsigned char rxd_char() { unsigned char data; while( (UCSR0A & 0x80) == 0) ; data = UDR0 ; return data ; }
one possible solution : still polling int main() { … while (1) { if( (UCSR0A & 0x80) != 0 ) cmd = UDR0 ; if( main S/W is left) { Motor Off; } else { switch(cmd){ case …
solution with interrupt (I) int main() { … while (1) { cmd = rxd_char(); if( main S/W is left) { Motor Disable; } else { switch(cmd){ case … main S/W interrupt ISR(INT0_vect) { Motor Disable; }
solution with interrupt (II) int main() { … while (1) { cmd = rxd_char(); if( … ) { Left Motor Disable; } else if (… ) { RightMotor Disable; } else { switch(cmd){ case … left S/W interrupt ISR(INT0_vect) { Left Motor Disable; } right S/W interrupt ISR(INT1_vect) { Right Motor Disable; }
USART Interrupt • USART0 사용 • USCR0B Register • RXCIE0 (7 bit) = ‘1’; • USCR0B : ’18’ -> ’98’
USART0 Interrupt Service Routine ISR(USART0_RX_vect) { Cmd_U0 = UDR0; /* Cmd_U0 : global 변수 */ } … unsigned char Cmd_U0; /* global 변수 선언 위치 */ int main() { …
변수의허용 범위 • block : {}내의 선언문 및 실행문 • block 내에서 선언된 변수는 block내에서 만 유효 • Example) int a = 2; printf(“%d\n”,a); { int a = 3; printf(“%d\n”,a); } printf(“%d\n”,a);
USART0 interrupt program #include <avr/io.h> #include <avr/interrupt.h> unsigned char Cmd_U0; int main(){ /* 초기화 code, PortI/O, USART0, Interrupt Enable */ while(1){ switch(Cmd_U0) { case : … } } return 0; }
USART0 interrupt 실습 • ‘n’ : LED on, ‘f’ : LED off switch(Cmd_U0){ case ‘n’ : PORTD &= 0xEF; break; case ‘f’ : PORTD |= 0x10; break; default : }
실습 과제 • 모든 input은 interrupt로 처리 • Left S/W를 이용하여 left motor enable/disable • ‘0’ : Disable ‘1’ : Enable • Right S/W를 이용하여 right motor enable/disable • ‘0’ : Disable ‘1’ : Enable • UART 통신을 이용하여 Motor 제어 • Key map 정의 • 예) R : right forward, r : right backward