Interrupt. incoming Lab. Interrupt an asynchronous signal indicating the need for attention hardware...

Post on 14-Jan-2016

252 views 0 download

Transcript of Interrupt. incoming Lab. Interrupt an asynchronous signal indicating the need for attention hardware...

Interrupt

incoming Lab.

Interrupt

 an asynchronous signal indicating the need for attention

hardware interrupt/software interruptcall “interrupt service routine”(interrupt handler, inter-rupt routine)interrupt source/interrupt vector/interrupt priority

incoming Lab.

생활 속에 인터럽트

영화 감상

문자

영화 정지

답신

재생

중요

스팸

1234

5678…

12345

시간

Gom player cell phone

interrupt interrupt

incoming Lab.

program with or without interrupt

b = *ADC0;c = *ADC1;a = b+c;i=0;while(i<10){ a += b; i++;}

b = *ADC0;c = *ADC1;a = b+c;

i=0;while(i<10){ a += b; i++;}

without interrupt with interrupt

if ( a>10 ) a = c;else a = b;

interruptservice

routine(ISR)

incoming Lab.

interrupt is an asynchronous event

b = *ADC0;c = *ADC1;a = b+c;

i=0;while(i<10){ a += b; i++;}

if ( a>10 ) a = c;else a = b;

b = *ADC0;

c = *ADC1;a = b+c;i=0;while(i<10){ a += b; i++;}

if ( a>10 ) a = c;else a = b;

ISR

ISR

incoming Lab.

c.f.) function in program

b = *ADC0;c = *ADC1;a = b+c;func();i = 0;while(i<10){ a += b; i++;}

b = *ADC0;c = *ADC1;a = b+c;

i=0while(i<10){ a += b; i++;}

void func(){ if ( a>10 ) a = c; else a = b;}

incoming Lab.

ATmega128 interrupt Source (I)

35 개

incoming Lab.

ATmega128 interrupt Source (II)

incoming Lab.

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.

incoming Lab.

Interrupt Vector Table  

 memory address of an interrupt service routine

incoming Lab.

External Interrupt : INT0~INT7

INT0~INT3 : PD0~PD3 (Port D)INT4~INT7 : PE4~PE7 (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 MaSK registerExternal Interrupt (INT0~INT7) 의 허용 여부를 제어

‘1’ : enable ‘0’: disable예 ) EIMSK = 0xA4;address : 0x59

incoming Lab.

External Interrupt Control Register (E-ICRA, 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

0x5A

0x6A

incoming Lab.

EICRA, EICRB

incoming Lab.

예 ) Enable Interrupt

INT0, rising edgeDDRD &= 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 */

incoming Lab.

Interrupt Service Routine

ISR(vector, attributes)Format of WinAVR

C:\WinAVR-20100110\doc\avr-libc\avr-libc-user-manu-al.pdf 의 p.233 ~

vector : interrupt source p.237 의 표 참조 예 ) INT0_vect : external interrupt 0 (PD0)

attributes : interrupt 속성 , 생략 가능예 ) ISR(INT0_vect) { … } /* external interrupt 0 (PD0) 가 발생할 때 ISR */

incoming Lab.

Interrupt Vector Table Initialize

WinAVR : ISR(vector, attributes)ISR 의 시작 번지가 자동으로 해당 vector table 에 저장

in general ( 예 )unsigned int *ivt;ivt = (unsigned int *)0x0002;*ivt = int_service_routine;

/* C program 에서는 함수의 이름이 주소를 나타냄 */ …

…void int_service_routine(){ /* interrupt service routine */…}

incoming Lab.

Interrupt Priority & EIFR

인터럽트의 우선 순위두 개 이상의 인터럽트가 동시에 발생될 경우하위 주소의 인터럽트가 상위 주소의 인터럽트 보다 우선 순위가 높다예 ) INT0 > INT1 > … > USART0 > …

interrupt flag register (EIFR)External Interrupt (INT0~INT7) 의 발생 여부를 나타냄

incoming Lab.

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;

}

incoming Lab.

falling edge or rising edge

incoming Lab.

Interrupt Service Routine

ISP(INT0_vect){ PORTD |= 0x10;}

incoming Lab.

In flash program memory0x0000 : jmp

0x0054

0x0002 : jmp

0x00a0

0x0054 : ….

0x00a0 : ….

….

…. : reti

Reset or Restart

INT0 (left S/W)

main program

interrupt service routine

incoming Lab.

Interrupt 실습 : LED 다시 켜기 , while 문만 변경

#include <avr/io.h>#include <avr/interrupt.h>

int main(){ …

sei();

while(1) { if( (PIND & 0x01) == 1 ) PORTD &= 0xEF;

}return 0;

}

incoming Lab.

Interrupt 실습 : INT1 (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(INT1_vect){ PORTD |= 0x10;}

incoming Lab.

실습 : INT0, INT1 모두 사용

#include <avr/io.h>#include <avr/interrupt.h>

int main(){

DDRD = ________;

EICRA = ________;EIMSK =________;

sei();

while(1); return 0;

}

incoming Lab.

실습 : INT0, INT1 모두 사용

ISP(INT0_vect) /* Left S/W => LED Off */{ PORTD |= 0x10;}

ISR(INT1_vect) /* Right S/W => LED On */{ PORTD &= 0xEF;}

incoming Lab.

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 ; }

incoming Lab.

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 …

incoming Lab.

solution with interrupt (I)

int main() { … while (1) { cmd = rxd_char(); if( main S/W is left) { Motor Disable; } else { switch(cmd){ case …

ISR(INT0_vect) {

Motor Disable; }

main S/Winterrupt

incoming Lab.

solution with interrupt (II)int main() { … while (1) { cmd = rxd_char(); if( … ) { Left Motor Dis-

able; } else if (… ) { RightMotor Dis-

able; } else { switch(cmd){ case …

ISR(INT0_vect) { Left Motor Dis-able;}

left S/Winterrupt

ISR(INT1_vect) { Right Motor Dis-able;}

right S/Winterrupt

incoming Lab.

USART Interrupt

USART0 사용USCR0B Register

RXCIE0 (7 bit) = ‘1’;USCR0B : ’18’ -> ’98’

incoming Lab.

USART0 Interrupt Service Routine

ISR(USART0_RX_vect){ Cmd_U0 = UDR0; /* Cmd_U0 : global 변수 */}

…unsigned char Cmd_U0; /* global 변수 선언

위치 */int main() {

incoming Lab.

변수의 허용 범위

block : {} 내의 선언문 및 실행문block 내에서 선언된 변수는 block 내에서 만 유효Example)

int a = 2;printf(“%d\n”,a);{ int a = 3; printf(“%d\n”,a);}printf(“%d\n”,a);

incoming Lab.

USART0 interrupt program

#include <avr/io.h>#include <avr/interrupt.h>

unsigned char Cmd_U0;int main(){

/* 초기화 code, Port I/O, USART0, Interrupt Enable */

while(1){ switch(Cmd_U0) { case : … } }

return 0;}

incoming Lab.

USART0 interrupt 실습

‘n’ : LED on, ‘f’ : LED off

switch(Cmd_U0){ case ‘n’ : PORTD &= 0xEF; break; case ‘f’ : PORTD |= 0x10; 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