제04강 인터럽트(Interrupt) · 2017. 6. 7. · ATmega128 인터럽트 5 인터럽트(계속) *...

28
ATmega128 인터럽트 1 제04강 인터럽트(Interrupt) 인터럽트 개요 외부 인터럽트 참고) FND 회로 실습 및 과제

Transcript of 제04강 인터럽트(Interrupt) · 2017. 6. 7. · ATmega128 인터럽트 5 인터럽트(계속) *...

  • 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(); // 전체 인터럽트 허용, SREG.I=1

    cli(); // 전체 인터럽트 금지, SREG.I=0

  • ATmega128 인터럽트 6

    인터럽트(계속)

    * ISR(Interrupt Service Routine) 정의

    #include

    ISR(vector) {:

    // 여기에 vector 인터럽트에 대한 // 서비스 코드를 작성......

    :}

    * Nonpreemption(비선점) Mechanism

    : SREG의 I 플래그는 ISR 실행과 동시에 클리어,

    ISR 종료와 동시에 셋됨

  • ATmega128 인터럽트 7

    인터럽트(계속)

    * 인터럽트 벡터에 대한 매크로 정의(p.107 참조)

  • ATmega128 인터럽트 8

    외부 인터럽트

    * 외부 인터럽트(INTn) 입력원

    : PORTD의 하위니블, PORTE의 상위니블

    : 해당 핀을 입력용으로 방향설정

    (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

  • ATmega128 인터럽트 12

    외부 인터럽트(계속)

    * EIFR(External interrupt Flag register)

    : 인터럽트 요청시 set, ISR 수행시 자동 clear

    : 해당 플래그에 1을 기록하면, 플래그 리셋

    : 레벨트리거 모드에서는 항시 0 상태 유지

  • ATmega128 인터럽트 13

    FND 회로

    * FND 회로(p.128 회로 수정본)

  • ATmega128 인터럽트 14

    FND 회로(계속)

    * 각 세그먼트와 대응되는 비트 패턴

    7 6 5 4 3 2 1 0

    a b c d e f g dp

    예) "CPU" 패턴

    문자 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 ISRISR(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

  • ATmega128 인터럽트 16

    int main() {DDRA = 0xFF; // 포트A를 출력포트로 설정PORTA = pattern[0]; // 처음 패턴으로 LED를 켠다.

    DDRC=0xFF;PORTC = 0xFF;

    DDRD = 0xF0; // PORTD의 하위니블을 입력용(INT0,1,2,3)EICRA = (1

  • ATmega128 인터럽트 17

    실습과제

    [실습2] 외부 인터럽트 II

    : [실습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

    ④ 스위치 해제를 기다림

    ⑤ 인터럽트 플래그 INT0를 리셋

    실습과제

    [과제4] 중간고사(프로그램 문제) 완성후 검토

    : 다수개 소스파일 상황(아래 소스 참조)

    : INT0요청시 패턴인덱스+1, INT1 -1, INT2 +2

    // file1.c =========================================#include #include #include

    #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) { // INT0 인터럽트서비스루틴if(LEDindex++==8)

    LEDindex=0;msec_delay(DEBOUNCING_DELAY); // 디바운싱

    msec_delay(DEBOUNCING_DELAY); // 디바운싱

    }

  • ATmega128 인터럽트 23

    ⑥ 패턴이 1씩 감소되는 인터럽트 서비스루틴 작성 // INT1 인터럽트서비스루틴

    ⑦ 패턴이 2씩 증가되는 인터럽트 서비스루틴 작성 // INT2 인터럽트서비스루틴

    ① INT0, INT1, INT2 모두 하강모서리에서 인터럽트가 발생하도록 설정

    ② INT0, INT1, INT2을 모두 허용하도록 설정

    ③ 전역인터럽트허용

    int main() {DDRA = 0xFF;DDRC = 0xF0;PORTC = 0x01; PORTA = ~LEDpattern[0];

    while(1) { // 무한루프displayPattern();

    }}

    void msec_delay(int n) {// msec단위 시간지연함수for(; n

  • ATmega128 인터럽트 24

    실습과제

    [과제5] 땅따먹기 게임(순발력게임)

    : using DotMatrix & s/w module

    1) 9개 패턴(all OFF, all ON, ....)

    2) INT0 index+1 player1, INT1 index-1 player2

    3) 카운트다운 시작 패턴 보이기

    4) 기타....

    -경계선에서 승자/패자 결정후, 결과 출력 패턴 보이기

    -임의 버튼 눌리면 게임 재개....

  • ATmega128 인터럽트 25

    실습과제

    [과제6] 주사위 게임

    : using FND & s/w module

    1) INT0 player1, INT1 player2

    2) Normal상태에서 눈에 해당하는 숫자패턴을 표시

    (알아볼수 없을 정도로 빠르게...)

    3) INT0, INT1 누른 순간의 숫자 값을 5회 깜박임

    4) 기타..

    -승자 결정후, 벌칙 번호 출력

  • ATmega128 인터럽트 26

    // [과제5] 땅따먹기 게임(미완, 급조)//=================================// [game1]//=================================#include #include #include

    #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) { // INT0 인터럽트서비스루틴if(++LEDindex==9)

    Winner = 2; //LEDindex=0;displayPattern();

    // msec_delay(DEBOUNCING_DELAY);// while(~PIND & 0x01) ;// msec_delay(DEBOUNCING_DELAY);

    EIFR = (1

  • ATmega128 인터럽트 27

    // msec_delay(DEBOUNCING_DELAY);// while(~PIND & 0x02) ;// msec_delay(DEBOUNCING_DELAY);

    EIFR = (1

  • 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