STM32 - Interrupt(feat.GPIO)

EEC·2025년 3월 4일

STM32

목록 보기
7/9

rev.2503041358 : 첫 작성.


이 포스팅에서는 지난 Interrupt 개념에 이어, STM32 MCU로 GPIO를 Interrupt 설정하여 제어해볼 것이다.

지난 Polling 방식으로 GPIO를 통해 스위치 입력을 받았을 때는 스위치를 한번 누를 때마다 해당 프로그램이 여러번 동작하는 에러가 있었다.

STM32의 GPIO Interrupt 설정을 살펴보니, 이 문제를 해결할 수 있을 듯 하다.

우선 설정부터 해보자.

GPIO Interrupt setting

우선 CubeMX 핀 설정 시 아래와 같이 표시된다.

이 중 GPIO_EXTI가 Interrupt에 속한다.(EXTI : External Interrupt)
따라서, 이렇게 설정해주고 Configuration을 보자.

GPIO Interrupt 설정 시 trigger 신호(Interrupt를 발생시키는 trigger신호)를 선택할 수 있는데, Rising/Falling Edge 혹은 Rising & Falling edge로 선택할 수 있다.

Interrupt Mode 외에도 Event Mode라는 것이 있는데, Reference Manual을 살펴보자.

위 내용과 구글링을 해본 결과,

Interrupt Mode : trigger 신호로 IRQ 후, Interrupt Handler(ISR) 실행
Event Mode : ISR을 실행하지 않음

이 두 차이라고 한다.

아직 나로썬 ISR을 실행하지 않을 건데, 굳이 Event Mode를 사용할 이유가 있나 싶다.
나중에 알아보자.

어쨋든 나는 우선 Interrupt Mode와 Rising Edge로 설정할 것이다.

이처럼 Interrupt를 설정해주면 또 설정할 수 있는 것이 있는데,
바로 NVIC이다.

해당 설정을 보면, 아래와 같이 나온다.

NVIC는 Nested Vectored Interrupt Controller의 약자이다.
직역하면 중첩 인터럽트 벡터의 컨트롤러이다.

즉, 인터럽트가 동시에 발생하거나, 어떤 인터럽트 실행 중 다른 인터럽트가 발생하면 어떻게 처리할 지를 정해주는 장치이다.(인터럽트 간의 우선순위를 정하는 것)

앞선 포스팅에서 우선순위를 정할 수 있는 세팅이 이것인 것이다.

동시에 인터럽트가 발생하면 당연히 우선순위가 높은 것부터 처리되고, 한 인터럽트가 실행 중인 와중에 우선순위가 더 높은 인터럽트가 발생하면 그 인터럽트를 우선적으로 실행한다.

즉, 인터럽트의 인터럽트인 것이다.(중첩)

오늘은 하나의 Interrupt만 사용할 것이기 때문에 Enabled Check만 해주고 우선순위는 설정하지 않겠다.

실습

위와 같이 설정하고, Code generate를 하면 Core > Src > xxxx_it.c
에 Interrupt Handler 함수가 생성된다.

생성된 IRQHandler가 선언된 곳으로 들어가보면, 아래와 같이 나온다.

위의 Callback 함수를 수정해서 ISR을 작성해주면 된다.

// app.c
#include "app.h"


void app_init()
{

}

void app_main()
{
	app_init();

	while(1)
	{

	}
}

// ISR
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == SW_Pin)
	{
		HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
	}
}

위와 같이 코딩을 해주면 된다.
실제 실행해보니, 스위치로 인터럽트 여러 번 호출 시 호출 간격이 작으면 여러 번 수행되는 버그가 있는 듯하다.

Polling 방식보다는 확실히 덜 하지만, 이 또한 버그이므로 해결해야 한다.

서칭해보니, 디바운싱 문제로 인한 버그인 듯한데, 확실한 해결법을 제시해주는 곳을 찾기가 힘들다.

나중에 해결 방법에 대해 생각해보기로 하자.

profile
느리지만 확실하게

0개의 댓글