[STM32CubeIDE] 인터럽트 사용해보기

YUN·2025년 8월 23일

[기본적인 CS]

목록 보기
19/21

1. 목표

Nucleo 보드B1 버튼을 누르면 외부 인터럽트가 발생하며 LED(LD2)가 깜빡이도록 하는 것

2. Schematic 분석

(1) B1 버튼

B1 버튼은 PC13에 연결되어 있는 것을 확인할 수 있다.

또한, 회로도를 보면 스위치가 Open 상태일때 PC13HIGH(1)이고, Short 상태일때 PC13LOW(0) 상태라는 것을 알 수 있다.

또한 디바운싱을 위한 커패시터도 연결되어있는 것을 확인할 수 있다.
디바운싱 부분은 신경쓰지 않아도 될 것 같다.

(2) LD2 LED

PA5LD2 LED에 연결되어 있음을 확인할 수 있다.

(SB42SB21은 연결되어있다.)

3. 프로젝트 생성 및 설정

프로젝트명을 EXTI로 해서 STM32 프로젝트를 하나 생성한다.

(1) RCC 설정

HSELSEDisable한다.

HCLK64Mhz인 것을 확인한다.

(2) GPIO 설정 (GPIO mode 설정)

현재 PC13GPIO modeExternal Interrupt Mode with Rising edge trigger detction 으로 설정 되어있다.

🧐 External Interrupt Mode (외부 인터럽트 모드)

External Interrupt Mode 란 뭘까?

외부 신호(스위치, 센서, 다른 MCU의 신호 등)가 특정 핀에 들어올 때, CPU가 즉시 반응하도록 인터럽트 발생시키는 모드이다.

일반 gpio 입력 모드와의 차이

  • 일반 GPIO 입력 모드로 스위치 값을 읽는 경우

    • while(1)에서 계속 핀을 읽는 폴링 방식
  • 인터럽트로 스위치 값을 읽는 경우

    • 인터럽트가 발생하면 CPU가 자동으로 인터럽트 서비스 루틴(ISR)을 호출함.

🧐 Rising Edge Trigger Detection (상승 에지 트리거 감지)

Rising Edge을 감지하는 것을 의미한다

다들 알고있겠지만, Rising Edge신호가 0 → 1 (Low → High)로 바뀌는 순간을 의미한다.

앞서 설명했듯이, 회로도를 보면 스위치가 Open 상태일때 PC13HIGH(1)이고, Short 상태일때 PC13LOW(0) 상태임을 알 수 있다.

따라서 현재의 설정(External Interrupt Mode with Rising edge trigger detction) 이면 버튼을 눌렀다가 땔 때 인터럽트가 발생하고 CPUISR을 호출한다.

나는 스위치를 누르자마자 LED가 켜지게 하고 싶으므로 위와같이GPIO mode

External Interrupt Mode with Falling edge trigger detction 로 수정해줬다.

(2) STM32가 인터럽트를 처리하는 순서

(1) 인터럽트가 발생하면 해당 인터럽트 pending 상태로 저장
(2) 만약 여러 개가 pending우선순위(priority) 비교
(3) 우선순위가 가장 높은 인터럽트부터 실행
(우선순위 동일하면 → 벡터 번호가 낮은 쪽 먼저 실행)
(4) CPU가 하나 처리 끝내면 다음 pending 인터럽트를 실행

(3) NVIC(Nested Vectored Interrupt Controller) 설정

NVIC-NVIC 에서 인터럽트를 활성화 및 비활성화 시킬 수 있고, 인터럽트 우선순위도 변경할 수 있다.


NVIC-Code generation에서 인터럽트 코드에 대한 초기화 순서, 인터럽트 서비스 루틴 (IRQ) 생성 여부도 설정할 수 있다.

4. 코드 생성 (Code Generation)

Code를 Generate 해주고 위와 같이 Project Explorer에 EXTI가 뜨는지 확인한다.

5. 소스 코드 작성

CubeMX에서 앞서 수행한 설정 관련 코드는 이미 생성해주었다.

이제 인터럽트 발생시 실행되어야 하는 것들을 코드로 작성해주면된다.

(1) 인터럽트 발생시 호출되는 함수

인터럽트가 발생하면

EXT_15_10_IRQHandler() -> HAL_GPIO_EXTI_IRQHandler() -> HAL_GPIO_EXTI_Callback() 순서로 함수가 호출된다.

사용자는 HAL_GPIO_EXTI_Callback()에 인터럽트 발생시 실행될 코드를 구현해주면 된다.

stm32f1xx_it.c 파일에 들어가면 CubeMX가 자동으로 생성한 ISREXT_15_10_IRQHandler()HAL_GPIO_EXTI_IRQHandler()를 호출하는 것을 확인할 수 있다.

드래그-우클릭-Open Declaration 에 들어가서 HAL_GPIO_EXTI_IRQHandler()의 선언을 확인해보자.


위와같이 HAL_GPIO_EXTI_IRQHandler()HAL_GPIO_EXTI_Callback()을 호출하는 것을 확인할 수 있다.


HAL_GPIO_EXTI_Callback()의 경우user file(main.c)에서 구현(implement) 하라고 나와있는 것을 확인할 수 있다.

(2) HAL_GPIO_EXTI_Callback() 구현

void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin) {
	switch (GPIO_Pin) // switch 문으로 "어떤 핀에서 인터럽트가 발생했는지" 구분하는 것.
	{
	case B1_Pin: //스위치가 연결된 PC13의 User Label이 B1 이다.
		HAL_GPIO_TogglePin (LD2_GPIO_Port, LD2_Pin); // LD2_GPIO_Port의 LD2_Pin을 Toggle(반전)
		break; // case문 종료

	default: // 아무것도 해당 사항 없을 시. switch문의 마지막이라 break문 없어도 됨.
		;
	}
}

HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin) 함수의 사용법을 알아보자.

앞서 설명했듯이, 인터럽트 발생시 HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin) 함수가 자동으로 호출되고 매개변수 GPIO_Pin에는 인터럽트가 발생한 Pin 번호가 들어온다.

switch문을 통해 어떤 핀의 인터럽트 발생인지에 따라 분기해서 처리하면 된다.

6. 빌드 및 업로드

빌드해준다.

성공적으로 빌드되었다.

Run-Run으로 업로드 해준다.

7. 실행

GOOD

profile
안녕하세요. 전자공학부 학부생의 공부 기록입니다.

0개의 댓글