이 블로그는 임베디드 컴퓨터를 이용한 장치(시스템) 개발과 원격제어에 필요한 지식을 공유 하기 위한 블로그 입니다.
실제 개발과 프로그램 예를 위하여 Microchip 사의 ATmega128를 사용한 보드와 Arduino Mega 보드(ATmega2560), Raspberry Pi, Raspberry Pi Pico, WiFi 모듈을 사용 합니다.

atmega2560-interrupt

ATmega2560 interrupt
  ATmega2560 External Interrupt


  • 인터럽트의 개요
    • Interrupt : 외부 장치의 요구에 의해서 현재 실행 중인 프로그램을 잠시 멈추고, Interrupt에 의하여 요구된 작업을 먼저 수행한 후에 다시 원래의 프로그램으로 복귀하여 실행 한다.
    • 주변장치의 서비스 요청에 맞추어(동기 하여) 서비스를 실행 한다.
    • Embedded System의 Program은 대부분 Interrupt Drive 방식으로 작성 한다.
    • Interrupt Processing 예
    • Main Routine 실행 중 Interrupt 요구가 발생 하면 현재 실행 중인 Routine을 잠시 멈추고 Interrupt Service Routine으로 Jmp 하여 Interrupt Service을 실행 하고, Interrupt Service 종료 후 다시 Main Routine 실행 한다.


  • 인터럽트 처리 과정
    • Program 실행 중에 Interrupt가 발생(서로 다른 Interrupt는 Interrupt 번호로 구분) 하면(Interrupt 실행이 허용 된 경우(Interrupt Enable 상태인 경우)),
    • 현재 실행 중인 Program을 잠시 중단 하고(Interrupt Service Routine이 종료 된 다음 현재 실행이 종료된 다음 명령어 부터 실행 할 수 있도록 하기 위하여 다음에 실행 할 명령의 위치를 Stack에 저장 하고),
    • Interrupt Vector Table에서 Interrupt Service Routine의 시작 번지(Interrupt 번호를 이용 하여 Interrupt Vector Table에서 Service Routine의 시작 번지 알 수 있다.)를 획득 하여
    • Interrupt Service Routine으로 Jump 한다.
    • Interrupt Service Routine의 실행이 종료 되면 Stack에 저장된 다음에 실행 할 명령의 Address를 이용 하여 Interrupt 발생 이전에 실행 하던 Program을 계속 하여 실행 한다.

  • ATmega2560 Interrupt Vectors
  • 아래 표는 ATmega2560에서 사용 하는 Interrupt의 종류와 Interrupt 번호, 각 Interrupt(Interrupt 번호에 따른) Service Routine의 시작 번지를 저장 하는 Memory 번지, 그리고 각 Interrupt에 대한 요약된 설명 이다.

    ATmega2560는 External Interrupt와 Timer/Counter, USART 등 다양한 Interrupt Source를 사용 하지만 이 페이지에서는 External Interrupt와 Pin Change Interrupt에 대하여 설명 하고, 기타 Interrupt는 각 장치를 설명 하는 부분에서 설명 한다.

    아래 표를 참고 하여 Interrupt Vector Table을 작성 할 수 있다.

    • Reset and Interrupt Vectors

  • External interrupt
  • External interrupt는 Interrupt Sense Control Mode의 설정(ISCn1, ISCn0)에 따라 입력 신호의 상태(Low level, Any edge, Falling edge, Rising edge) 중 한 상태에서 Interrupt가 발생 한다.

    • External interrupt 0 - 3( Port D)
    • 아래 표는 External Interrupt 0번 - 3번이 사용 하는 Pin에 대한 설명이다.

      External Interrupt 0번 - 3번은 Port D의 PD0 - PD3번 Pin을 사용 한다. 이 Pin은 표와 같이 해당 Port가 Input/Output Port로 사용 되지 않는 경우 다른 장치들이 사용 할 수 있다.


    • External interrupt 4 - 7( Port E)
    • 아래 표는 External Interrupt 4번 - 7번이 사용 하는 Pin에 대한 설명이다.

      External Interrupt 4번 - 7번은 Port E의 PE4 - PE7번 Pin을 사용 한다. 이 Pin은 표와 같이 해당 Port가 Input/Output Port로 사용 되지 않는 경우 다른 장치들이 사용 할 수 있다.


  • Pin Change Interrupt
  • Pin Change Interrupt은 Pin의 상태가 변동(Low -> High or High -> Low) 하는 경우 Interrupt가 발생 한다. Pin Change Interrupt은 Interrupt Sense Mode를 설정 할 수 없기 때문에 Falling edge 또는 Rising edge Interrupt Mode로 사용 하고자 하는 경우에는 Interrupt 처리 Routine에서 현재 Pin의 상태에 따라 Interrupt Sense Mode를 결정 하고 현재 Pin의 상태에 적합한 프로그램 실행 하도록 하여야 한다.

    • Pin Change Interrupt 0-7( Port B)
    • 아래 표는 Pin Change Interrupt 0번 - 7번이 사용 하는 Pin에 대한 설명이다.

      Pin Change Interrupt 0번 - 7번은 Port B의 PB0 - PB7번 Pin을 사용 한다. 이 Pin은 표와 같이 해당 Port가 Input/Output Port로 사용 되지 않는 경우 다른 장치들이 사용 할 수 있다.

    • Pin Change Interrupt 8-15( Port PE0, J(0:6))
    • 아래 표는 Pin Change Interrupt 8번 - 15번이 사용 하는 Pin에 대한 설명이다.

      Pin Change Interrupt 8번은 PORT E의 PE0 Pin을 사용 하고, 9번 - 15번은 Port J의 PJ0 - PJ6번을 사용 한다. 이 Pin은 표와 같이 해당 Port가 Input/Output Port로 사용 되지 않는 경우 다른 장치들이 사용 할 수 있다.

    • Pin Change Interrupt 16-23( Port K)
    • 아래 표는 Pin Change Interrupt 16번 - 23번이 사용 하는 Pin에 대한 설명이다.

      Pin Change Interrupt 16번 - 23번은 Port K의 PK0 - PK7번 Pin을 사용 한다. 이 Pin은 표와 같이 해당 Port가 Input/Output Port로 사용 되지 않는 경우 다른 장치들이 사용 할 수 있다.

  • Software Interrupt
  • External interrupt과 Pin Change Interrupt 신호를 프로그램 제어로 Interrupt 신호를 발생(Software로 Interrupt 신호를 발생 시킴) 하도록 하여 프로그램의 특정 위치에서 Interrupt Service Routine을 실행 시킨다.

    • Software Interrupt로 이용 하고자 하는 Port(Pin)를 Output Port로 설정 한다.
    • Interrupt Pin으로 사용 하기 위한 설정(Interuupt Enable, Interrupt Sense Control 설정)을 한다.
    • 프로그램 내 필요한 위치에서 Interrupt 신호를 발생 하기 위한 프로그램을 작성 한다.

    Hardware interrupt과 Software Interrupt의 차이

      Hardware interrupt과 Software Interrupt 모두 동일한 Interrupt Service Routine를 실행 한다.

    • Hardware interrupt
      • Hardware 장치가 특정한 상태(조건)가 될 때 Interrupt 신호(Request)가 발생 한다.
      • Processor는 이 신호가 발생(신호에 동기 하여) 하면 해당 Interrupt Service Routine를 실행 한다.
      • Hardware interrupt 예: Switch를 누를 때, Timer 가 일정한 상태가 되었을 때, 통신 Port에 새 Data가 도착 하였을 때 등
    • Software Interrupt
      • 프로그램 내의 특정 위치에서 프로그램으로(Software) 특정 Interrupt Service Routine를 실행 한다.
      • Software interrupt은 Subroutine과 같이 프로그램 내에서 위치가 결정 되고, Hardware interrupt은 Hardware 장치가 특정한 상태(조건)가 될때 발생 한다.
  • External Interrupts를 사용 하기 위한 설정
    • INTn(n은 0 - 7)
      • Port D를 사용 하는 Interrupt: PD0(INT0), PD1(INT1), PD2(INT2), PD3(INT3)
      • Port E를 사용 하는 Interrupt: PE4(INT4), PE5(INT5), PE6(INT6), PE7(INT7)
    • External Interrupt을 사용하기 위한 설정
      • External Interrupt의 mode 설정
      • External Interrupt의 mask 설정
        • External Interrupt Mask Register 에서 사용하고자 하는 INT를 Set(Enable) 한다.
      • Interrupt를 Enable
        • Status Register (SREG)의 I-bit를 Set(Enable) 함
    • Interrupt 0를 사용(Push Button Switch(PD0)의 입력) 하기 위한 초기화 설정 예
      • Interrupt 0(PD0)를 사용 하기 위한 초기화 함수

        void port_init(void)

        {

           // PD0(External Interrupt)와 GND 사이에 SW를 연결 한다.

           PORTD |= (1 << PD0);   // External SW PullUp

           DDRD &= ~(1 << PD0);   // External Interrupt Sensing Port(PD0)를 Input Port로 설정

           EICRA = 0x02;   // External Interrupt 0, Falling Edge Asynchronously Interrupt

           EIMSK |= 0x01;   // External Interrupt 0 enable

        }


  • Pin Change Interrupts를 사용 하기 위한 설정
  • Pin Change Interrupt는 8개씩 3그룹으로 나누어 그룹 단위로 Pin Change Interrupt Control Register(PCICR)에서 Enable 하고 개별 Interrupt는 Pin Change Mask Register에서 Enable 하여야 한다.

    • Pin Change Interrupt에 사용 하는 Pin(Port)
      • Port B를 사용 하는 Pin Change Interrupt: PB0(PCINT0) - PB7(PCINT7)
      • Port J, E를 사용 하는 Pin Change Interrupt: PE0(PCINT8), PJ0(PCINT9) - PJ6(PCINT15)
      • Port K를 사용 하는 Pin Change Interrupt: PK0(PCINT16) - PK7(PCINT23)
    • Pin Change Interrupt을 사용하기 위한 설정
      • Pin Change Interrupt Control Register(PCICR)에서 Pin Change Interrupt를 Enable(PCIEn) 한다.
      • Pin Change Mask Register(PCMSKn)에서 사용 하고자 하는 Interrupt Pin을 Enable 한다.
      • Status Register (SREG)의 I-bit를 Set(Enable) 한다.
    • Pin Change Interrupt 16를 사용(Push Button Switch(PB0)의 입력) 하기 위한 초기화 설정 예
      • Pin Change Interrupt 16(PK0)를 사용 하기 위한 초기화 함수

        void port_init(void)

        {

           // PK0(Pin Change Interrupt 16번 Pin)와 GND 사이에 SW를 연결 한다.

           PORTK |= (1 << PK0);   // External SW PullUp

           DDRK &= (1 << PK0);   // External Interrupt Sensing Port(PK0)를 Input Port로 설정

           PCICR |= (1 << PCIE2);   // Pin Change Interrupt 2(Pin16 - Pin23) Enable

           PCMSK2 |= (1 << PCINT16);   // Pin Change Mask Register에서 16번 Pin Enable

        }

  • Interrupt Control Register
    • EICRA - External Interrupt Control Register A
    • External Interrupts(3 - 0 번)은 SREG I-flag 가 Set 되고 EIMSK Rg에서 해당 번호 Interrupt가 Enable 된 경우 External Interrupt pin에 가해지는 신호에 따라 아래 Interrupt Sense Control Table과 같은 Input signal 상태에서 External Interrupt이 발생 한다.

      Interrupt sense control bits(ISCn1: ISCn0)의 설정에 의하여 External Interrupt 3번 - 0번의 Interrupt Sensing Mode을 설정 한다.

      • EICRA – External Interrupt Control Register A
      • Table 15-1. Interrupt Sense Control

    • EICRB - External Interrupt Control Register B
    • External Interrupts(7 - 4 번)은 SREG I-flag 가 Set 되고 EIMSK Rg에서 해당 번호 Interrupt가 Enable 된 경우 External Interrupt pin에 가해지는 신호에 따라 아래 Interrupt Sense Control Table과 같은 Input signal 상태에서 External Interrupt이 발생 한다.

      Interrupt sense control bits(ISCn1: ISCn0)의 설정에 의하여 External Interrupt 7번 - 4번의 Interrupt Sensing Mode을 설정 한다.

      • EICRB – External Interrupt Control Register B
      • Table 15-3. Interrupt Sense Control

      펄스 신호의 4가지 상태


    • EIMSK - External Interrupt Mask Register
    • Status Register(SREG)의 I-bit가 Set 되고 EIMSK Rg내에서 해당 Interrupt 번호(INT7 - INT0) 가 1로 Set 되면 해당 번호의 External Interrupt 가 Enable 된다.

      External Interrupt Control Registers(EICRA, EICRB)의 Interrupt Sense Control bits는 Interrupt 가 발생 하는 External Interrupt pin 신호 상태를 설정 한다. 이 설정에 따라 External Interrupt는 Pin에 가해지는 신호가 설정 상태와 일치 할 때(Low level(0V), 입력 Pin의 신호가 변동 하는 경우(Low -> High or High -> Low로 변동), Falling edge(High -> Low로 변동), Rising edge(Low -> High로 변동)) 발생 한다.

      • INT7~0 Interrupt를 개별적으로 허용하는데 사용
        • 허용 : 1 , 금지 : 0

    • EIFR - External Interrupt Flag Register
      • INT7 ~ 0 Pin에 Interrupt 신호가 입력되어 해당 Interrupt가 Trigger 되었음 표시
      • 프로그램 실행이 Interrupt Vector 로 Jump하면 0으로 Cleared 됨

    • PCICR – Pin Change Interrupt Control Register
      • Bit 2 – PCIE2: Pin Change Interrupt Enable 2
      • PCIE2 bit가 Set(one)되고 Status Register(SREG)의 I-bit가 Set(one) 되면 Pin Change Interrupt 2번이 Enable 된다.

        Pin Change Interrupt Enable 2이 Enable된 상태에서 PCINT23:16번 Pin의 신호가 변동 하면(Low -> High or High -> Low로 변동) Interrupt가 발생 되고 PCI2 Interrupt Vector Sevice Routine이 실행 된다.

        이 Interrupt는 PCINT23:16번 Pin 중 한 Pin의 변동에 의하여 발행 하기 때문에 Interrupt Sevice Routine에서 Pin의 상태를 읽어 어느 Pin에서 발생한 Interrupt인지 구분 하고, Interrupt Pin 번호에 따라 적당한 제어를 하여야 한다.

        PCINT23:16번 Pin Interrupt는 PCMSK2 Register(Pin Change Mask Register 2)에서 개별적으로 Enable 또는 Disable 된다.

      • Bit 1 – PCIE1: Pin Change Interrupt Enable 1
      • PCIE1 bit가 Set(one)되고 Status Register(SREG)의 I-bit가 Set(one) 되면 Pin Change Interrupt 1번이 Enable 된다.

        Pin Change Interrupt Enable 1이 Enable된 상태에서 PCINT15:8번 Pin의 신호가 변동 하면(Low -> High or High -> Low로 변동) Interrupt가 발생 되고 PCI1 Interrupt Vector Sevice Routine이 실행 된다.

        이 Interrupt는 PCINT15:8번 Pin 중 한 Pin의 변동에 의하여 발행 하기 때문에 Interrupt Sevice Routine에서 Pin의 상태를 읽어 어느 Pin에서 발생한 Interrupt인지 구분 하고, Interrupt Pin 번호에 따라 적당한 제어를 하여야 한다.

        PCINT15:8번 Pin Interrupt는 PCMSK1 Register(Pin Change Mask Register 1)에서 개별적으로 Enable 또는 Disable 된다.

      • Bit 0 – PCIE0: Pin Change Interrupt Enable 0
      • PCIE0 bit가 Set(one)되고 Status Register(SREG)의 I-bit가 Set(one) 되면 Pin Change Interrupt 0번이 Enable 된다.

        Pin Change Interrupt Enable 0이 Enable된 상태에서 PCINT7:0번 Pin의 신호가 변동 하면(Low -> High or High -> Low로 변동) Interrupt가 발생 되고 PCI0 Interrupt Vector Sevice Routine이 실행 된다.

        이 Interrupt는 PCINT7:0번 Pin 중 한 Pin의 변동에 의하여 발행 하기 때문에 Interrupt Sevice Routine에서 Pin의 상태를 읽어 어느 Pin에서 발생한 Interrupt인지 구분 하고, Interrupt Pin 번호에 따라 적당한 제어를 하여야 한다.

        PCINT7:0번 Pin Interrupt는 PCMSK0 Register(Pin Change Mask Register 0)에서 개별적으로 Enable 또는 Disable 된다.

    • PCIFR – Pin Change Interrupt Flag Register
      • Bit 2 – PCIF2: Pin Change Interrupt Flag 2
      • PCINT23:16번 Pin의 신호가 변동 하면 Interrupt request가 발생 하고 PCIF2 Flag가 Set(one) 된다.

        만약 SREG Rg의 I-bit와 PCICR Rg의 PCIE2 bit가 Set(one) 되었으면 대응하는 Interrupt Service Routine이 실행 된다.

        Interrupt Service Routine이 실행되면 PCIF2 Flag는 Clear 된다. 또한 이 Flag에 1(One)을 Write 하면 이 Flag는 Clear 된다.

      • Bit 1 – PCIF1: Pin Change Interrupt Flag 1
      • 만약 SREG Rg의 I-bit와 PCICR Rg의 PCIE1 bit가 Set(one) 되었으면 대응하는 Interrupt Service Routine이 실행 된다.

        Interrupt Service Routine이 실행되면 PCIF1 Flag는 Clear 된다. 또한 이 Flag에 1(One)을 Write 하면 이 Flag는 Clear 된다.

      • Bit 0 – PCIF0: Pin Change Interrupt Flag 0
      • 만약 SREG Rg의 I-bit와 PCICR Rg의 PCIE0 bit가 Set(one) 되었으면 대응하는 Interrupt Service Routine이 실행 된다.

        Interrupt Service Routine이 실행되면 PCIF0 Flag는 Clear 된다. 또한 이 Flag에 1(One)을 Write 하면 이 Flag는 Clear 된다.

    • PCMSK2 – Pin Change Mask Register 2
      • Bit 7:0 – PCINT23:16: Pin Change Enable Mask 23:16
      • PCINT23:16 Bit는 각각 대응 하는 Pin Change Interrupt를 Enable 한다.

        만약 PCICR Rg의 PCIE2 Bit가 Set 되고 PCINT23:16 Bit 중 어느 Bit가 Set 되면 해당 I/O Pin의 Pin Change Interrupt가 Enable 된다.

        만약 PCINT23:16 중 어느 Bit가 Clear 되면 해당 I/O Pin의 Pin Change Interrupt는 Disable 된다.

    • PCMSK1 – Pin Change Mask Register 1
      • Bit 7:0 – PCINT15:8: Pin Change Enable Mask 15:8
      • PCINT15:8 Bit는 각각 대응 하는 Pin Change Interrupt를 Enable 한다.

        만약 PCICR Rg의 PCIE1 Bit가 Set 되고 PCINT15:8 Bit 중 어느 Bit가 Set 되면 해당 I/O Pin의 Pin Change Interrupt가 Enable 된다.

        만약 PCINT15:8 중 어느 Bit가 Clear 되면 해당 I/O Pin의 Pin Change Interrupt는 Disable 된다.

    • PCMSK0 – Pin Change Mask Register 0
      • Bit 7:0 – PCINT7:0: Pin Change Enable Mask 7:0
      • PCINT7:0 Bit는 각각 대응 하는 Pin Change Interrupt를 Enable 한다.

        만약 PCICR Rg의 PCIE0 Bit가 Set 되고 PCINT7:0 Bit 중 어느 Bit가 Set 되면 해당 I/O Pin의 Pin Change Interrupt가 Enable 된다.

        만약 PCINT7:0 중 어느 Bit가 Clear 되면 해당 I/O Pin의 Pin Change Interrupt는 Disable 된다.


  • External Interrupt를 이용하는 Program 예:
  • Push Button Switch로 부터 입력되는 신호(SW를 누른 회수)를 LED Bar에 2진수로 출력 하는 실험 구성도

    주: Pin Change Interrupt 실험을 하는 경우에는 PK0에 Push Button Switch를 연결하여야 한다.

    • External Interrupt(PD0)과 Switch Bouncing 현상 Program 예: cho_sw_count_bounc_EX_interrupt_2560.zip
    • 
      // S/W Environment : AVR Studio 7 + WINAVR Compiler
      // Target : ATmega2560
      // Crystal: 16Mhz
      //
      // Author : chowk
      
      // 이 프로그램은 Switch bouncing 현상과 External interrupt을 이해 하기 위한 예 이다.
      // 실험 방법
      //   프로그램을 실행 시키고 PD0 Switch를 누르면 LED에 누른 회수가 2진수로 표시 된다.
      //   이 프로그램은 Switch의 bouncing 현상 때문에 Switch를 한번 누르면 경우에 따라
      //   SW를 누르거나 뗄때 LED 값이 1 또는 2, 3 씩 증가 한다.
      
      #include <avr/io.h>
      #include <stdio.h>
      #include <avr/interrupt.h>
      
      // count: Switch를 누른 횟수를 저장 하기 위한 변수
      unsigned char count=0;
      
      void port_init(void)
      {
      	PORTD |= 0x01;   	// Switch PullUp 저항을 활성화
      	DDRD &= (~0x01);	// PORTD의 PD0를 Input Port로 설정
      
      	PORTL = 0x00;		// PORTL의 초기값 설정(PORTL의 LED가 꺼진 상태)
      	DDRL  = 0xff;		// PORTL를 Output Port로 설정
      	// External Interrupt 0 ,Falling edge between two samples of INTn
      	EICRA = 0x02;
      	// External Interrupt 0 enable
      	EIMSK |= (1 << INT0);
      }
      
      // 사용하는 장치를 초기화 한다.
      void init_devices(void)
      {
      	cli();         // disable all interrupts
      	port_init();
      	sei();         // re-enable interrupts
      }
      
      int main(void)
      {
      	init_devices();
      
      	while(1){
      		// Switch를 누르면 External Interrupt 0 service routine 이
      		// 실행 되고 이 Routine에서 Count와 LED 표시 동작이 실행 된다.
      	}
      }
      
      // External Interrupt이 발생 하였을 때 실행되는 함수
      SIGNAL (INT0_vect)
      {
      	EIMSK &= ~(1 << INT0);  // External Interrupt 0 Disable
      
      	count++;        // count 값을 1 만큼 증가 시킨다.
      	PORTL = count;  // count 값을 LED에 표시
      
      	EIFR |= (1 << INTF0);			// Clear External Interrupt Flag
      	EIMSK |= (1 << INT0);			// External Interrupt 0 enable
      }
          

      • 실험을 위한 준비
        • Arduino Mega 2560를 사용하는 경우 2560 Pin name과 Mega board pin name mapping table을 참고하여 신호선을 연결한다.

          참고자료: Arduino Mega 2560 PIN mapping table

        • PD0에 Push button switch를 연결한다.
        • PORTL에 저항(330Ω)과 LED Array(8Bits)를 연결한다.
        • 참고자료: 8Bit-LED-array-module 제작 예

      • 실험 방법
        • cho_sw_count_bounc_EX_interrupt_2560.zip 파일을 Download하여 압축을 해제 한다.
        • cho_sw_count_bounc_EX_interrupt_2560.hex를 개발 보드에 Upload 한다.
        • 실험: Push button switch(PD0)를 누르면 LED Array(8Bits)의 값(2진수)이 1씩 증가한다.
        • 주: Switch의 상태가 이상적이지 않기 때문에 Switch를 누르면 Switch bouncing 현상에 의하여 LED Array(8Bits)의 값이 1 또는 2, 3씩 불규직하게 증가한다.


    • Pin Change Interrupt(PK0)와 Switch Bouncing 현상 Program 예: cho_sw_count_bounc_PC_interrupt_2560.zip
    • 
      // S/W Environment : AVR Studio 7 + WINAVR Compiler
      // Target : ATmega2560
      // Crystal: 16Mhz
      //
      // Author : chowk
      
      // 이 프로그램은 Pin Change Interrupt와 Switch bouncing 현상에 대한 이해를 위한 예 이다.
      // 실험 준비:
      //   PK0(PCINT16, Mega board Analog pin 8)과 GND 사이에 Switch를 연결 한다.
      //   PORTL(Mega board Digital pin 49 - 42)과 GND 사이에 LED Array를 연결 한다.
      // 실험 방법:
      //   프로그램을 실행 시키고 PK0 Switch를 누르면 LED에 누른 회수가 2진수로 표시 된다.
      //   이 프로그램은 Switch의 bouncing 현상 때문에 Switch를 한번 누르면 경우에 따라
      //   SW를 누르거나 뗄때 LED 값이 1 또는 2, 3 씩 증가 한다.
      #include 
      #include 
      #include 
      
      // count: Switch를 누른 횟수를 저장 하기 위한 변수
      unsigned char count=0;
      
      // I/O Port를 초기화 한다.
      void port_init(void)
      {
      	PORTK|= 0x01;   // Switch PullUp 저항을 활성화
      	DDRK &= (~0x01); // PORTK의 K0를 Input Port로 설정
      
      	PORTL = 0x00;    // PORTL의 초기값 설정(PORTL의 LED가 꺼진 상태)
      	DDRL  = 0xff;    // PORTL를 Output Port로 설정
      	// Pin Change Interrupt 16 Enable
      	PCICR |= (1 << PCIE2);      // Pin Change Interrupt 2(Pin16 - Pin23) Enable
      	PCMSK2 |= (1 << PCINT16);   // Pin Change Mask Register에서 16번 Pin Enable
      	EICRA = 0x02;
      }
      
      // 사용하는 장치를 초기화 한다.
      void init_devices(void)
      {
      	cli();         // disable all interrupts
      	port_init();
      	sei();         // re-enable interrupts
      }
      
      int main(void)
      {
      	init_devices();
      	while(1){
      		// Switch를 누르면 Pin Change Interrupt 2 service routine 이
      		// 실행 되고 이 Routine에서 Count와 LED 표시 동작이 실행 된다.
      	}
      }
      
      // Pin Change Interrupt 2 가 발생 하였을 때 실행되는 함수
      SIGNAL (PCINT2_vect)
      {
      	PCICR &= ~(1 << PCIE2); // Pin Change Interrupt 2 Disable
      
      	// Switch를 누를 때만 Count 한다.
      	if((PINK & 0b00000001) == 0) count++;
      	PORTL = count;  // count 값을 LED에 표시
      
      	PCICR |= (1 << PCIE2);  // Pin Change Interrupt 2(Pin16 - Pin23) Enable
      }
          
      • 실험을 위한 준비
        • PK0에 Push button switch를 연결한다.
        • PORTL에 저항(330Ω)과 LED Array(8Bits)를 연결한다.
      • 실험 방법
        • cho_sw_count_bounc_PC_interrupt_2560.zip 파일을 Download하여 압축을 해제 한다.
        • cho_sw_count_bounc_PC_interrupt_2560.hex를 개발 보드에 Upload 한다.
        • 실험: Push button switch(PK0)를 누르면 LED Array(8Bits)의 값(2진수)이 1씩 증가한다.
        • 주: Switch의 상태가 이상적이지 않기 때문에 Switch를 누르면 Switch bouncing 현상에 의하여 LED Array(8Bits)의 값이 1 또는 2, 3씩 불규직하게 증가한다.


    • Software Interrupt 발생 회수를 하여 LED에 표시하는 Program 예: cho_count_soft_interrupt_2560_c.txt
      • 실험을 위한 준비
      • 실험 방법
        • cho_count_soft_interrupt_2560_c.txt 파일을 Download하여 cho_count_soft_interrupt_2560.c로 이름을 변경하고 Microchip에서 제공하는 IDE를 사용하여 컴파일 한다.
        • cho_count_soft_interrupt_2560.hex를 개발 보드에 Upload 한다.
        • 실험: 프로그램에서 PD0 Soft interrupt를 0.5초 간격으로 발생 시키기 때문에 Push button switch(PD0)를 누르지 않아도 LED Array(8Bits)의 값(2진수)이 1씩 증가한다.
    • External Interrupt(PD0와 PD1)를 이용하여 LED의 회전 방향을 제어 하는 Program 예: cho_led_basic_shift_interrupt_2560_c.txt
      • 실험을 위한 준비
        • PD0와 PD1에 Push button switch를 연결한다.
        • PORTL에 저항(330Ω)과 LED Array(8Bits)를 연결한다.
      • 실험 방법
        • cho_led_basic_shift_interrupt_2560_c.txt 파일을 Download하여 cho_led_basic_shift_interrupt_2560.c로 이름을 변경하고 Microchip에서 제공하는 IDE를 사용하여 컴파일 한다.
        • cho_led_basic_shift_interrupt_2560.hex를 개발 보드에 Upload 한다.
        • 실험: Push button switch(PD0)를 누르면 LED가 Left로 회전 하고,Push button switch(PD1)를 누르면 LED가 Right로 회전 한다.

    • External Interrupt(PD0)과 Switch debouncing Program 예: cho_sw_count_debounc_EX_interrupt_2560_c.txt
      • 실험을 위한 준비
        • PD0에 Push button switch를 연결한다.
        • PORTL에 저항(330Ω)과 LED Array(8Bits)를 연결한다.
      • 실험 방법
        • cho_sw_count_debounc_EX_interrupt_2560_c.txt 파일을 Download하여 cho_sw_count_debounc_EX_interrupt_2560.c로 이름을 변경하고 Microchip에서 제공하는 IDE를 사용하여 컴파일 한다.
        • cho_sw_count_debounc_EX_interrupt_2560.hex를 개발 보드에 Upload 한다.
        • 실험: Push button switch(PD0)를 누르면 LED Array(8Bits)의 값(2진수)이 1씩 증가한다.
        • 주: 이 프로그램에는 Debouncing 기능이 포함되어 있기 때문에 Switch bouncing 현상에 발생하지 않는다. 그러므로 LED Array(8Bits)의 값이 1씩 증가한다.


    • Pin Change Interrupt(PK0)과 Switch debouncing Program 예: cho_sw_count_debounc_PC_interrupt_2560_c.txt
      • 실험을 위한 준비
        • PK0에 Push button switch를 연결한다.
        • PORTL에 저항(330Ω)과 LED Array(8Bits)를 연결한다.
      • 실험 방법
        • cho_sw_count_debounc_PC_interrupt_2560_c.txt 파일을 Download하여 cho_sw_count_debounc_PC_interrupt_2560.c로 이름을 변경하고 Microchip에서 제공하는 IDE를 사용하여 컴파일 한다.
        • cho_sw_count_debounc_PC_interrupt_2560.hex를 개발 보드에 Upload 한다.
        • 실험: Push button switch(PK0)를 누르면 LED Array(8Bits)의 값(2진수)이 1씩 증가한다.
        • 주: 이 프로그램에는 Debouncing 기능이 포함되어 있기 때문에 Switch bouncing 현상에 발생하지 않는다. 그러므로 LED Array(8Bits)의 값이 1씩 증가한다.