Interrupt Interrupt an asynchronous signal indicating the need






































- Slides: 38
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 incoming Lab.
program with or without interrupt b = *ADC 0; c = *ADC 1; a = b+c; i=0; while(i<10){ a += b; i++; } with interrupt b = *ADC 0; c = *ADC 1; a = b+c; if ( a>10 ) a = c; else a = b; i=0; while(i<10){ a += b; i++; } interrupt service routine(ISR) incoming Lab.
interrupt is an asynchronous event b = *ADC 0; c = *ADC 1; a = b+c; if ( a>10 ) a = c; else a = b; i=0; while(i<10){ a += b; i++; } ISR c = *ADC 1; a = b+c; i=0; while(i<10){ a += b; i++; } ISR incoming Lab.
c. f. ) function in program b = *ADC 0; c = *ADC 1; a = b+c; func(); i = 0; while(i<10){ a += b; i++; } b = *ADC 0; c = *ADC 1; a = b+c; void func(){ if ( a>10 ) a = c; else a = b; } i=0 while(i<10){ a += b; i++; } incoming Lab.
ATmega 128 interrupt Source (I) 35 개 incoming Lab.
ATmega 128 interrupt Source (II) incoming Lab.
Interrupt 처리 과정 Interrupt request from an interrupt source 예) INT 0 Signal If masked, ignore the interrupt. Program counter(PC) is saved. PC is changed to the program address according to the interrupt source 예) PC <= 0 x 0002 Jump to the Interrupt Service Routine (ISR) 예) jmp EXT_INT 0 (PC <= EXT_INT 0) After the end of ISR, PC is restored. incoming Lab.
Interrupt Vector Table memory address of an interrupt service routine incoming Lab.
External Interrupt : INT 0~INT 7 INT 0~INT 3 : PD 0~PD 3 (Port D) INT 4~INT 7 : PE 4~PE 7 (Port E) incoming Lab.
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) incoming Lab.
EIMSK register External Interrupt Ma. SK register External Interrupt (INT 0~INT 7)의 허용 여부를 제어 ‘ 1’ : enable ‘ 0’: disable 예) EIMSK = 0 x. A 4; address : 0 x 59 incoming Lab.
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 Ø falling edge : ‘ 1’ -> ‘ 0’ 이면 interrupt trigger EICRA, EIRCB 0 x 6 A 0 x 5 A incoming Lab.
EICRA, EICRB incoming Lab.
예) Enable Interrupt INT 0, rising edge DDRD &= 0 x. FE; /* PD 0 : interrupt source, input */ EICRA = 0 x 03; EIMSK = 0 x 01; sei(); /* global interrupt enable */ Ø SEI instruction의 C code, mnemonic code Ø cli(); /* global interrupt disable */ INT 7, falling edge; DDRE &= 0 x. EF; /* PE 7 : interrupt source, input */ EICRB = 0 x 80; EIMSK = 0 x 80; sei(); /* global interrupt enable */ incoming Lab.
Interrupt Service Routine ISR(vector, attributes) Format of Win. AVR Ø C: Win. AVR-20100110docavr-libc-user-manual. pdf 의 p. 233 ~ vector : interrupt source Ø p. 237의 표 참조 Ø 예) INT 0_vect : external interrupt 0 (PD 0) attributes : interrupt 속성, 생략 가능 예) ISR(INT 0_vect) { … } /* external interrupt 0 (PD 0)가 발생할 때 ISR */ incoming Lab.
Interrupt Vector Table Initialize Win. AVR : ISR(vector, attributes) ISR의 시작 번지가 자동으로 해당 vector table에 저장 in general (예) unsigned int *ivt; ivt = (unsigned int *)0 x 0002; *ivt = int_service_routine; Ø /* C program에서는 함수의 이름이 주소를 나타냄 */ … … void int_service_routine(){ /* interrupt service routine */ … } incoming Lab.
Interrupt 실습 #include <avr/io. h> #include <avr/interrupt. h> int main(){ DDRD = 0 x 18; EICRA = 0 x 02; /* falling edge */ EIMSK = 0 x 01; /* left S/W interrupt enable */ sei(); /* SEI instruction의 C code, mnemonic code */ while(1); return 0; } incoming Lab.
falling edge or rising edge incoming Lab.
Interrupt Service Routine ISP(INT 0_vect) { PORTD |= 0 x 10; } incoming Lab.
In flash program memory 0 x 0000 : jmp 0 x 0054 Reset or Restart 0 x 0002 : jmp 0 x 00 a 0 INT 0 (left S/W) … 0 x 0054 : …. … main program 0 x 00 a 0 : …. interrupt service routine …. …. : reti incoming Lab.
Interrupt 실습 : LED 다시 켜기, while 문만 변경 #include <avr/io. h> #include <avr/interrupt. h> int main(){ … sei(); while(1) { if( (PIND & 0 x 01) == 1 ) PORTD &= 0 x. EF; } return 0; } incoming Lab.
Interrupt 실습 : INT 1 (RIGHT) #include <avr/io. h> #include <avr/interrupt. h> int main(){ DDRD = ____; EICRA = ____; EIMSK =____; sei(); while(1); return 0; } incoming Lab.
Interrupt Service Routine ISR(INT 1_vect) { PORTD |= 0 x 10; } incoming Lab.
실습 : INT 0, INT 1 모두 사용 #include <avr/io. h> #include <avr/interrupt. h> int main(){ DDRD = ____; EICRA = ____; EIMSK =____; sei(); while(1); return 0; } incoming Lab.
실습 : INT 0, INT 1 모두 사용 ISP(INT 0_vect) /* Left S/W => LED Off */ { PORTD |= 0 x 10; } ISR(INT 1_vect) /* Right S/W => LED On */ { PORTD &= 0 x. EF; } incoming Lab.
main switch problem : wait-polling int main() { … while (1) { unsigned char rxd_char() { unsigned char data; while( (UCSR 0 A & 0 x 80) == 0) ; cmd = rxd_char(); if( main S/W is left) { Motor Off; } else { switch(cmd){ case … data = UDR 0 ; return data ; } incoming Lab.
one possible solution : still polling int main() { … while (1) { if( (UCSR 0 A & 0 x 80) != 0 ) cmd = UDR 0 ; if( main S/W is left) { Motor Off; } else { switch(cmd){ case … incoming Lab.
solution with interrupt (I) int main() { … while (1) { main S/W interrupt ISR(INT 0_vect) { cmd = rxd_char(); if( main S/W is left) { Motor Disable; } else { switch(cmd){ case … Motor Disable; } incoming Lab.
solution with interrupt (II) int main() { … while (1) { left S/W interrupt ISR(INT 0_vect) { Left Motor Disable; } cmd = rxd_char(); if( … ) { Left Motor Disable; } else if (… ) { Right. Motor Disable; } else { switch(cmd){ case … right S/W interrupt ISR(INT 1_vect) { Right Motor Disable; } incoming Lab.
USART Interrupt USART 0 사용 USCR 0 B Register RXCIE 0 (7 bit) = ‘ 1’; USCR 0 B : ’ 18’ -> ’ 98’ incoming Lab.
USART 0 Interrupt Service Routine ISR(USART 0_RX_vect) { Cmd_U 0 = UDR 0; /* Cmd_U 0 : global 변수 */ } … unsigned char Cmd_U 0; int main() { /* global 변수 선언 위치 */ … incoming Lab.
USART 0 interrupt program #include <avr/io. h> #include <avr/interrupt. h> unsigned char Cmd_U 0; int main(){ /* 초기화 code, Port I/O, USART 0, Interrupt Enable */ while(1){ switch(Cmd_U 0) { case : … } } return 0; } incoming Lab.
USART 0 interrupt 실습 ‘n’ : LED on, ‘f’ : LED off switch(Cmd_U 0){ case ‘n’ : PORTD &= 0 x. EF; break; case ‘f’ : PORTD |= 0 x 10; break; default : } incoming Lab.
실습 과제 모든 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 incoming Lab.