EXTI(External interrupt/event controller)

지난번 글에서 예외와 인터럽트에 대해서 알아보았어요. 그리고 예외도 발생시켜 보았습니다. 이번에는 I/O 핀을 통해서 인터럽트를 발생시킬 수 있는 EXTI(외부 인터럽트/이벤트 컨트롤러)에 대해서 공부해볼까요.

EXTI block diagram

레퍼런스 메뉴얼의 블록 다이어그램을 살펴볼까요.

EXTI_BlockDiagram

블록 다이어그램의 왼쪽의 Input Line에서 Edge detect circuit 으로 신호가 입력됩니다. 입력된 신호는 Rising trigger selection register와 Falling trigger selection register의 설정에 따라 이벤트 시그널을 set 할지 여부를 결정합니다. Edge detect circuit의 출력 신호는 OR 게이트에 입력되는데요. 이 OR 게이트의 입력에는 Software interrupt event register 도 연결되어있네요. 즉, 인터럽트/이벤트 요청은 외부 신호나 하드웨어에서 Edge detect circuit에 입력되는 신호뿐만 아니라 소프트웨어적으로도 인터럽트/이벤트 요청을 할 수 있다는 것입니다. 이 OR 게이트의 출력은 2개의 AND 게이트에 입력되고 각각의 AND 게이트의 입력에는 Interrupt mask register와 Event mask register가 연결되어 있어 각인터럽트/이벤트 요청 허용 여부를 개별적으로 설정할 수 있습니다.

Wakeup event

NVIC로 입력되는 인터럽트 요청 신호는 물론 인터럽트를 발생시켜 인터럽트 핸들러를 실행시키는 용도로 사용되지만, 설정에 따라 인터럽트를 발생시키지는 않고 WFI 상태로부터 프로세서를 wake up 시킬 수 있습니다 다만 이렇게 사용할 때는 EXTI의 Pending request register의 pending 비트와 NVIC의 IRQ 채널 pending 비트를 wake up 시킬 때마다 클리어 해주어야합니다. EXTI 라인을 이벤트 모드로 설정하면, 이벤트 모드에는 pending register가 없기 때문에 별도로 클리어해주어야 하는 레지스터가 없습니다.

EXTI Mapping

112개의 GPIO는 각 EXTI 라인에 다음과 같이 맵핑되어 있습니다.

EXTI_Mapping

나머지 4개의 EXTI 라인은 다음과 같이 연결되어 있습니다.

  • EXTI line 16 is connected to the PVD output
  • EXTI line 17 is connected to the RTC Alarm event
  • EXTI line 18 is connected to the USB Wakeup event
  • EXTI line 19 is connected to the Ethernet Wakeup event (available only in connectivity line devices)

또, EXTI 라인을 통해 인터럽트나 이벤트를 발생시키는 것 이외에도 ADC나 DAC를 트리거 할 수도 있어요.

LAB

이전에 GPIO 글에서 작성했던 프로그램의 버튼 입력 부분을 폴링 방식에서 인터럽트 방식으로 바꾸어 봅시다.

폴링 방식의 코드를 다시 리뷰해보면,

1
2
3
4
5
6
7
    <div id=“crayon-58a05a30ba5bf919106826” class=“crayon-syntax crayon-theme-eclipse crayon-font-monaco crayon-os-pc print-yes notranslate” style=“margin-top: 12px;margin-bottom: 12px;font-size: 12px !important;line-height: 15px !important”>
 
        <div class=“crayon-toolbar” style=“font-size: 12px !important;height: 18px !important;line-height: 18px !important”><span class=“crayon-title”></span>
        <div class=“crayon-tools” style=“font-size: 12px !important;height: 18px !important;line-height: 18px !important”><div class=“crayon-button crayon-nums-button” title=“Toggle Line Numbers”><div class=“crayon-button-icon”></div></div><div class=“crayon-button crayon-plain-button” title=“Toggle Plain Code”><div class=“crayon-button-icon”></div></div><div class=“crayon-button crayon-wrap-button” title=“Toggle Line Wrap”><div class=“crayon-button-icon”></div></div><div class=“crayon-button crayon-expand-button” title=“Expand Code”><div class=“crayon-button-icon”></div></div><div class=“crayon-button crayon-copy-button” title=“Copy”><div class=“crayon-button-icon”></div></div><div class=“crayon-button crayon-popup-button” title=“Open Code In New Window”><div class=“crayon-button-icon”></div></div><span class=“crayon-language”>C++</span></div></div>
        <div class=“crayon-info” style=“min-height: 16.8px !important;line-height: 16.8px !important”></div>
        <div class=“crayon-plain-wrap”><textarea class=“crayon-plain print-no” readonly style=“font-size: 12px !important;line-height: 15px !important”>