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

gpio-interrupt-pico-arduido

Pico Digital I/O - Arduido
Raspberry Pi Pico Digital I/O 와 Interrupt - Arduido


  • Raspberry Pi Pico GPIO Port
    • 일반적인 GPIO Port의 이해에 도움이 되는 참고자료: "ATmega128 I/O Port"

    • RP2040 GPIO Port
      • Pi Pico GPIO Port의 논리적 구조(Logical structure)

      • Raspberry Pi Pico는 RP2040 마이크로 컨트롤러에서 사용할 수 있는 User bank(GPIO0 to GPIO29)의 핀 가운데 Raspberry Pi Pico 보드 핀에 연결된 26개(GP0 - GP22 까지와 GP26, GP27, GP28번)의 핀을 사용할 수 있다. GP23, GP24, GP25, GP29 핀은 Pi Pico 보드의 핀에 연결되지 않았기 때문에 사용할 수 없다.
      • GP22를 제외한 다른 GPIO 핀은 프로그램 설정으로 미리 설정된 다른 목적(PIO, SPI, UART, I2C, ADC, PWM, GPCLK)으로 사용할 수 있다. 그러나 동시에 다른 기능으로 설정할 수는 없다.
      • GPIO 핀의 외부 Interrupt 기능을 설정할 수 있다.
      • 각 GPIO의 CTRL 레지스터에 있는 FUNCSEL 필드에 기능(Function) 코드를 Writing 하면 해당 기능(Function)이 설정된다.
      • 참고자료: "RP2040 Datasheet"의 "2.19.2. Function Select"를 참고 바람.

      • 각 GPIO는 한 번에 하나의 기능을 선택할 수 있다. 각 주변 장치 입력(예: UART0 RX)은 한 번에 하나의 GPIO만 선택해야 한다.
    • GPIO Pads
    • Pad는 칩의 내부 로직과 외부 회로 사이의 전기적 인터페이스(electrical interface)이다.

      GPIO의 IO pad(1개) Diagram

      • 각 GPIO는 "Pad"를 통해 칩 외부에 연결된다.
      • Pad는 신호의 전압 레벨을 변환하고 더 높은 전류를 지원하며 정전기 방전(ESD) 이벤트에 대한 보호 기능을 제공한다.
      • Pad의 전기적 기능은 외부 회로의 요구 사항을 충족하도록 조정할 수 있다.
        • 출력 구동 전류의 강도를(2mA, 4mA, 8mA 또는 12mA) 설정할 수 있다.
        • 출력 슬루율(slew rate)을 느리게 또는 빠르게 설정할 수 있다.
        • 입력 히스테리시스(Schmitt trigger mode드) 기능 활성화가 가능하다.
        • 풀업 또는 풀다운(Pull-up or Pull-down)을 활성화하여 출력 드라이버가 활성화되지 않은 경우 출력 신호 레벨을 설정할 수 있다.
        • Pad가 사용되지 않거나 연결되지 않았거나 아날로그 신호에 연결된 경우 전류 소비를 줄이기 위해 입력 버퍼를 비 활성화할 수 있다.

    • GPIO Interrupts
      • 각 GPIO 핀은 아래와 같이 4종류의 외부 Interrupt를 생성할 수 있다.
        • Level high(Logical 1)
        • Level Low(Logical 0)
        • Positive edge( Transition from active low to active high)
        • Negative edge( Transition from active high to active low)
      • 레벨 인터럽트(Level interrupts)는 래치되지 않는다. 만약 핀이 Logical 1 이고 Level high 인터럽트가 활성화된 경우 핀이 Logical 0로 변경되는 순간 비활성화된다.
      • 에지 인터럽트(Edge interrupts)는 자동으로 INTR 레지스터(Rg)에 저장된다. INTR 레지스터에 저장된 Edge interrupts 상태는 해당 Interrupt 가 실행되거나 INTR 레지스터에 Writing operation을 실행하면 Cleare 된다.
      • 세 가지 인터럽트 대상(proc 0, proc 1,dormant_wake)에 각각 enable, status, force 레지스터가 있다. proc 0의 경우 Enable Rg(PROC0_INTE0), Status Rg(PROC0_INTS0), Force Rg(PROC0_INTF0) 가 있다.
      • 휴면 깨우기(Dormant wake)는 ROSC 또는 XOSC를 휴면 모드에서 깨우는 데 사용된다.

  • Digital I/O 함수 - Arduido
    • pinMode() 함수 - Arduido
      • 이곳에서는 자주 사용하는 GPIO의 기능을 설정하는 함수에 대하여만 설명한다.

      • pinMode(): 지정한 핀이 입력 또는 출력으로 작동하도록 구성한다.
        • 기본형: pinMode(pin, mode)
        • 매개 변수
          • pin: Mode를 설정할 Arduino 핀 번호.
          • mode: INPUT, INPUT_PULLUP 또는 OUTPUT.
        • Returns: Nothing
    • digitalWrite() 함수 - Arduido
      • digitalWrite(): Digital pin에 HIGH 또는 LOW value를 Write 한다.
        • Pin이 pinMode()를 사용하여 출력으로 구성된 경우, 해당 Pin의 전압을 HIGH의 경우 5V(또는 3.3V 보드의 경우 3.3V), LOW의 경우 0V(접지)로 설정된다.

          Pin이 pinMode()를 사용하여 입력으로 구성된 경우, digitalWrite()는 입력 핀의 설정에 따라 내부 Pullup을 활성화(HIGH)하거나 비활성화(LOW)한다. 내부 Pullup 저항을 활성화하려면 핀 모드()를 INPUT_PULLUP로 설정하는 것이 좋다.

          pinMode()를 실행하여 Pin mode를 출력으로 설정하지 않고 LED가 연결된 Pin에 DigitalWrite(HIGH)를 실행하면 LED의 상태가 흐리게 될수 있다. 명시적으로 pinMode()를 사용하여 츌력으로 설정하지 않으면 digitalWrite()가 내부 Pullup 저항을 활성화하여 큰 전류 제한 저항처럼 작동한다.

        • 기본형: digitalWrite(pin, value)
        • 매개 변수
          • pin: 출력으로 설정할 Arduino 핀 번호.
          • value: HIGH or LOW.
        • Returns: Nothing
      • Code 예
    • digitalRead() 함수 - Arduido
      • 이곳에서는 자주 사용하는 GPIO의 기능을 설정하는 함수에 대하여만 설명한다.

      • digitalRead(): 지정된 Digital pin에서 값(HIGH 또는 LOW)을 읽는다.
        • 기본형: digitalRead(pin)
        • 매개 변수
          • pin: 읽고 싶은 Arduino 핀 번호.
        • Returns: HIGH or LOW
      • Code 예
    • Switch(Push button)와 LED를 사용하는 프로그램 예
      • 이 프로그램은 Switch(Input port)와 LED(Output port)의 설정과 제어를 이해하기 위한 예 이다.

        참고자료: 일반적인 I/O port programming에 대한 예는 "ATmega128 I/O Port"를 참고하기 바람.

        실험을 위한 회로 구성 예

        주: Raspberry Pi Pico는 GPIO25를 On-board LED 제어에 사용하고, Raspberry Pi Pico W는 WL_GPIO0(Infineon CYW43439의 GPIO0)를 On-board LED 제어에 사용한다.

        주: 위 회로에서 LED 회로(보드에 점선으로 연결)는 개발보드에 내장된 LED를 사용하기 때문에 실제 회로 구성은 하지 않아도 된다.

      • Switch(Push button)의 상태를 LED에 출력하는 프로그램 예: sw-status-led
      • 실험을 위한 준비
        • Button switch: 위 그림과 같이 Button switch를 GPIO22에 연결한다.
        • 주: Pull up 저항은 RP2040 Microcontroller에 내장되어 있기 때문에 별도로 추가하지 않는다.

          참고자료: Pull up 저항의 이해를 위한 예는 "ATmega128 I/O Port - Switch Interfacing"를 참고하기 바람.

        • LED: 개발보드에 내장(LED_BUILTIN)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
      • 실험 방법
        • "File → New Sketch"를 실행하여 새 Project를 생성한다.
        • Arduino IDE의 Tool 메뉴에서 Board와 Port를 설정 한다.
        • 위 프로그램을 Arduino IDE의 Sketch 편집창에 복사하고 "File → Save As..."를 실행하여 Sketch를 저장 한다.
        • Upload 하여 실행한다.
        • 실험
          • GPIO22에 연결된 외부 Switch를 Push 하거나 Release 하며 LED의 상태를 관찰 한다.
          • 버튼(GPIO22 Pin)을 누르면 LED가 Off 되고 누르지 않으면 On 상태가 된다.

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

      • External Interrupt에 사용하는 GPIO Pins
        • Pico의 GPIO Pin은 모두 외부 신호를 받아 이 신호에 대응하는 인터럽트(External interrupt)를 발생 시키는 목적으로 사용 할 수 있다.
      • External Interrupt Trigger Events
        • 각 외부 인터럽트 핀에 대해 인터럽트를 트리거하는 5가지 다른 이벤트(응용 프로그램에 따라 선택)가 있다.

        • RISING : Rising Edge에서 Interrupt이 Trigger 된다.
        • FALLING : FALLING Edge에서 Interrupt이 Trigger 된다.
        • HIGH : HIGH 상태에서 Interrupt이 Trigger 된다.
        • LOW : LOW 상태에서 Interrupt이 Trigger 된다.
        • CHANGE : Pin의 상태가 변하면(HIGH -> LOW or LOW -> HIGH) Interrupt이 Trigger 된다.
        • 펄스 신호의 4가지 상태 예: 4가지 상태에 CHANGE를 포함하면 5가지 상태가 된다.

    • External Interrupt 관련 함수
      • attachInterrupt(): 지정한 핀의 Interrupt를 설정한다.
        • 기본형: attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)
        • 매개 변수
          • pin: Arduino 핀 번호.
          • ISR: 인터럽트가 발생할 때 호출할 ISR(Interrupt Service Routine). 이 함수는 매개 변수를 사용하지 않고 아무것도 반환하지 않아야 한다.
          • mode: Interrupt가 Trigger 되는 조건(위 "External Interrupt Trigger Events"를 참고요)을 정의한다. 아래 5 가지 조건 중 하나로 설정한다.
            • RISING: Rising Edge에서 Interrupt이 Trigger 된다.
            • FALLING: FALLING Edge에서 Interrupt이 Trigger 된다.
            • HIGH: HIGH 상태에서 Interrupt이 Trigger 된다.
            • LOW: LOW 상태에서 Interrupt이 Trigger 된다.
            • HIGH: HIGH 상태에서 Interrupt이 Trigger 된다.
            • CHANGE: Pin의 상태가 변하면(HIGH -> LOW or LOW -> HIGH) Interrupt이 Trigger 된다.
        • Returns: Nothing
        • Code 예
      • detachInterrupt(): 지정된 Interrupt를 해제한다.
        • 기본형: detachInterrupt(digitalPinToInterrupt(pin))
        • 매개 변수
          • pin: Arduino 핀 번호.
        • Returns: Nothing
      • interrupts(): 인터럽트를 다시 활성화(noInterrupts()로 비활성화된 후)한다.
        • 기본형: interrupts()
        • 매개 변수: Nothing
        • Returns: Nothing
        • Code 예
      • noInterrupts(): 인터럽트를 비활성화한다.
        • 기본형: noInterrupts()
        • 매개 변수: Nothing
        • Returns: Nothing

    • 프로그램 예: External Interrupt(SW)를 이용한 LED 제어
      • Switch를 누르면 LED의 상태가 Toggle(현재 상태가 On 이면 Off 상태로, Off 상태인 경우는 On 상태로 됨)되는 프로그램 예: switch_toggle_led_interrupt
      • 실험을 위한 준비
        • Button switch: 위 그림과 같이 Button switch를 GPIO22에 연결한다.
        • LED: 개발보드에 내장되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
      • 실험 방법
        • "File → New Sketch"를 실행하여 새 Project를 생성한다.
        • Arduino IDE의 Tool 메뉴에서 Board와 Port를 설정 한다.
        • 위 프로그램을 Arduino IDE의 Sketch 편집창에 복사하고 "File → Save As..."를 실행하여 Sketch를 저장 한다.
        • Upload 하여 실행한다.
        • 실험
          • GPIO22에 연결된 외부 Switch를 Push 하면 LED의 상태가 Toggle(현재 On 상태이면 Off되고, Off 상태이면 On 상태로 변환) 되어야 한다.
          • 주: Switch의 상태가 이상적이지 않기 때문에 Switch를 누르면 Switch bouncing 현상에 의하여 Bouncing 현상이 홀수개 발생하면 LED 상태가 Toggle 되고, 짝수개 발생하면 다시 원 상태가 되어 LED 상태가 변동되지 않는다.

      • Switch를 누르면 LED의 상태가 Toggle(현재 상태가 On 이면 Off 상태로, Off 상태인 경우는 On 상태로 됨)되는 프로그램(Debouncing 기능을 포함) 예
      • 실험을 위한 준비
        • Button switch: 위 그림과 같이 Button switch를 GPIO22에 연결한다.
        • LED: 개발보드에 내장되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
      • 실험 방법
        • "File → New Sketch"를 실행하여 새 Project를 생성한다.
        • Arduino IDE의 Tool 메뉴에서 Board와 Port를 설정 한다.
        • 위 프로그램을 Arduino IDE의 Sketch 편집창에 복사하고 "File → Save As..."를 실행하여 Sketch를 저장 한다.
        • Upload 하여 실행한다.
        • 실험
          • GPIO22에 연결된 외부 Switch를 Push 하면 LED의 상태가 Toggle(현재 On 상태이면 Off되고, Off 상태이면 On 상태로 변환) 된다.
          • 주: Debouncing 기능이 포함되어 Switch를 누르면 LED의 상태가 바르게 Toggle 된다.

            주: 이 프로그램은 Interrupt 루틴 내에 Time delay Code를 포함하고 있다. 일반적으로 Interrupt 루틴 내에 Time delay 또는 실행 시간이 많이 걸리는 함수 등을 사용하면 않된다. 그러나 아직 다른 Debouncing 기술을 소개하지 않은 상태 이기 때문에 쉬은 이해를 위하여 이 프로그램에서는 Interrupt 루틴 내에 Time delay Code를 사용하였다.


  • Raspberry Pi Pico Digital I/O 와 Interrupt 관련 페이지 보기