ATmega128 인터럽트 1 제 04 강 인터럽트 (Interrupt) 인터럽트개요외부인터럽트참고 ) FND 회로실습및과제
인터럽트 * 인터럽트처리메커니즘 ATmega128 인터럽트 2
인터럽트 ( 계속 ) ATmega128 인터럽트 3 * 인터럽트벡터 (P.104 표 7.1 참조 ) : 35 개
인터럽트 ( 계속 ) * 인터럽트허용 / 금지메커니즘 ATmega128 인터럽트 4
인터럽트 ( 계속 ) ATmega128 인터럽트 5 * SREG(Status Register) 의 I 비트제어함수 : 헤더파일 : avr/interrupt.h, : I(global Interrupt enable flag bit) sei(); cli(); // 전체인터럽트허용, SREG.I=1 // 전체인터럽트금지, SREG.I=0
인터럽트 ( 계속 ) * ISR(Interrupt Service Routine) 정의 #include <avr/interrupt.h> ISR(vector) { : // 여기에 vector 인터럽트에대한 // 서비스코드를작성... : * Nonpreemption( 비선점 ) Mechanism : SREG 의 I 플래그는 ISR 실행과동시에클리어, ISR 종료와동시에셋됨 ATmega128 인터럽트 6
인터럽트 ( 계속 ) ATmega128 인터럽트 7 * 인터럽트벡터에대한매크로정의 (p.107 참조 )
외부인터럽트 * 외부인터럽트 (INTn) 입력원 : PORTD 의하위니블, PORTE 의상위니블 ATmega128 인터럽트 8 : 해당핀을입력용으로방향설정 (Reset 시 default 로입력임 )
외부인터럽트 ( 계속 ) ATmega128 인터럽트 9 * EICRA(External interrupt control register A) : 인터럽트신호감지방법설정레지스터 : INT0, INT1, INT2, INT3( 각인터럽트당 2비트씩 )
외부인터럽트 ( 계속 ) ATmega128 인터럽트 10 * EICRB(External interrupt control register B) : INT4, INT5, INT6, INT7( 각인터럽트당 2 비트씩 )
외부인터럽트 ( 계속 ) ATmega128 인터럽트 11 * EIMSK(External Interrupt mask register) : 개별적인인터럽트허용 / 금지설정 : 인터럽트허용시 1, 금지시 0
외부인터럽트 ( 계속 ) * EIFR(External interrupt Flag register) : 인터럽트요청시 set, ISR 수행시자동 clear : 해당플래그에 1을기록하면, 플래그리셋 : 레벨트리거모드에서는항시 0 상태유지 ATmega128 인터럽트 12
FND 회로 * FND 회로 (p.128 회로수정본 ) ATmega128 인터럽트 13
FND 회로 ( 계속 ) * 각세그먼트와대응되는비트패턴 ATmega128 인터럽트 14 예 ) "CPU" 패턴 7 6 5 4 3 2 1 0 a b c d e f g dp 문자 a b c d e f g dp Hexa 'C' 0 1 1 0 0 0 1 1 63H 'P' 0 0 1 1 0 0 0 1 31H 'U' 1 0 0 0 0 0 1 1 83H
실습과제 ATmega128 인터럽트 15 [ 실습 1] 외부인터럽트 I ( p.120 소스참조 ) : INT0 요청시마다 LED 출력패턴이동 : 하강에지트리거방식, 디바운싱처리 : PORTA:DotMatrix Cols, PORTC:Rows, PORTD:s/w회로 // INT0 ISR ISR(INT0_vect) { static int i=0; // 라이프사이클동안 1 번만실행 if(++i==8) // 증가값이 8이면 0으로리셋 i=0; PORTA = pattern[i]; // i번째패턴 LED를켠다. msec_delay(debouncing_delay); // 디바운싱 while(~pind & 0x01) ; // 스위치해제를기다림 msec_delay(debouncing_delay); // 디바운싱 EIFR = (1<<INTF0); // 채터링에의한영향제거보장, INTF0 을리셋
int main() { DDRA = 0xFF; // 포트A를출력포트로설정 PORTA = pattern[0]; // 처음패턴으로 LED를켠다. DDRC=0xFF; PORTC = 0xFF; ATmega128 인터럽트 16 DDRD = 0xF0; // PORTD의하위니블을입력용 (INT0,1,2,3) EICRA = (1<<ISC01) (0<<ISC00) ; // 하강모서리트리거, 10 EIMSK = (1<<INT0); // INT0비트세트 (INT0 허용 ) sei(); // 전역인터럽트허용 while(1); // 무한루프, NORMAL 상태의동작 return 0; * 트리거모드를변경하여보자..
실습과제 [ 실습 2] 외부인터럽트 II ATmega128 인터럽트 17 : [ 실습1] 의수정판 1) ISR에서는패턴인덱스만변경, 패턴출력은 main() 에서... ( 패턴인덱스변수를전역변수로선언, p.124 소스참조 ) static int index; // 전역변수로선언 컴파일시문제있다!!!!! 최적화수준을바꾸어보자... ( 문제의이유는 p.126 참조 ) : "project-configuration options" 창의 Optimization 항 -O0 으로변경후컴파일... (-O0 : 최적화고려않음!!)
ATmega128 인터럽트 18 2) 해결책 : volatile 지시어 static volatile int index; 으로선언하고컴파일하면... 결론 : 전역변수이면서, ISR 과기타의일반함수에서공용으로 사용하는변수는 volatile 지시어를사용하는것이바람직!!!
실습과제 ATmega128 인터럽트 19 [ 과제 1] 외부인터럽트 I : 입출력관련과제 (Pooling 방식 ) 를인터럽트방식으로... : INT0 요청시상향, INT1 요청시하향의패턴출력
실습과제 ATmega128 인터럽트 20 [ 과제 2] 외부인터럽트 II : INT0 : up counting, INT1 : down counting : 7-segment 모듈제어 : 인터럽트요청시마다모듈에 1자리카운팅값표시
실습과제 ATmega128 인터럽트 21 [ 과제 3] 외부인터럽트 III : Normal 상태, INT0, INT1 각각에대한출력패턴을각자정의하고구현 : 지금까지의여러모듈들을사용하여...
실습과제 ATmega128 인터럽트 22 [ 과제 4] 중간고사 ( 프로그램문제 ) 완성후검토 : 다수개소스파일상황 ( 아래소스참조 ) : INT0요청시패턴인덱스 +1, INT1-1, INT2 +2 // file1.c ========================================= #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #define DEBOUNCING_DELAY 20 void msec_delay(int n); extern void displaypattern(); int LEDindex = 0; unsigned char LEDpattern[8]={0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80; ISR(INT0_vect) { if(ledindex++==8) LEDindex=0; msec_delay(debouncing_delay); 4 스위치해제를기다림 msec_delay(debouncing_delay); 5 인터럽트플래그 INT0를리셋 // INT0 인터럽트서비스루틴 // 디바운싱 // 디바운싱
ATmega128 인터럽트 23 6 패턴이 1 씩감소되는인터럽트서비스루틴작성 // INT1 인터럽트서비스루틴 7 패턴이 2 씩증가되는인터럽트서비스루틴작성 // INT2 인터럽트서비스루틴 int main() { DDRA = 0xFF; DDRC = 0xF0; PORTC = 0x01; PORTA = ~LEDpattern[0]; 1 INT0, INT1, INT2 모두하강모서리에서인터럽트가발생하도록설정 2 INT0, INT1, INT2 을모두허용하도록설정 3 전역인터럽트허용 while(1) { displaypattern(); // 무한루프 void msec_delay(int n) {// msec 단위시간지연함수 for(; n <0; n--) _delay_ms(1); // file2.c ========================================= #include <avr/io.h> unsigned char LEDpattern[8]; int LEDindex; void displaypattern() { PORTC = 0x01 << LEDindex; PORTA = ~LEDpattern[LEDindex];
실습과제 [ 과제 5] 땅따먹기게임 ( 순발력게임 ) ATmega128 인터럽트 24 : using DotMatrix & s/w module 1) 9개패턴 (all OFF, all ON,...) 2) INT0 index+1 player1, INT1 index-1 player2 3) 카운트다운시작패턴보이기 4) 기타... -경계선에서승자 / 패자결정후, 결과출력패턴보이기 -임의버튼눌리면게임재개...
실습과제 [ 과제 6] 주사위게임 ATmega128 인터럽트 25 : using FND & s/w module 1) INT0 player1, INT1 player2 2) Normal상태에서눈에해당하는숫자패턴을표시 ( 알아볼수없을정도로빠르게...) 3) INT0, INT1 누른순간의숫자값을 5회깜박임 4) 기타.. -승자결정후, 벌칙번호출력
ATmega128 인터럽트 26 // [ 과제 5] 땅따먹기게임 ( 미완, 급조 ) //================================= // [game1] //================================= #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #define DEBOUNCING_DELAY20 void msec_delay(int n); void displaypattern(); void countdown(); void showwinner(int win); volatile int Winner; volatile int LEDindex = 4; unsigned char LEDpattern[9]={0xFF, 0b11111110, 0b11111100, 0b11111000, 0b11110000, 0b11100000, 0b11000000,0b10000000, 0b00000000; ISR(INT0_vect) { if(++ledindex==9) Winner = 2; //LEDindex=0; displaypattern(); // INT0 인터럽트서비스루틴 // // msec_delay(debouncing_delay); while(~pind & 0x01) ; // msec_delay(debouncing_delay); EIFR = (1<<INTF0); ISR(INT1_vect) { if(--ledindex == -1) Winner = 1; //LEDindex=8; displaypattern(); // INT1 인터럽트서비스루틴
ATmega128 인터럽트 27 // msec_delay(debouncing_delay); // while(~pind & 0x02) ; // msec_delay(debouncing_delay); EIFR = (1<<INTF1); int main() { DDRA = 0xFF; DDRC = 0xFF; PORTC = 0x01; PORTA = ~LEDpattern[0]; EICRA = 0b00101010; //(1<<ISC01) (0<<ISC00) ; EIMSK = (7<<INT0); // countdown(); sei(); while(1) { if(winner!=0) { cli(); showwinner(winner); // 전역인터럽트허용 // 무한루프 void msec_delay(int n) { for(; n > 0; n--) _delay_ms(1); // msec 단위시간지연함수 void countdown() {
ATmega128 인터럽트 28 PORTA = 0x00; PORTC = 0b00001111; msec_delay(10000); PORTC = 0b00111100; msec_delay(10000); PORTC = 0xF0; msec_delay(10000); void showwinner(int win) { if(win==1) { PORTA = 0x00; PORTC = 0b00111100; msec_delay(10000); PORTC = ~PINC; msec_delay(10000); else { PORTA = 0x00; PORTC = 0b00011000; msec_delay(10000); PORTC = ~PINC; msec_delay(10000); void displaypattern() { PORTC = 0xFF; //01 << LEDindex; PORTA = ~LEDpattern[LEDindex];