본문 바로가기
임베디드 시스템 설계/Arm Cortex - M3 펌웨어 설계

STM32 NUCLEO-F103RB LED Blink(Toggle) 함수 실습 예제

by 홍소연한고기 2025. 9. 24.

나의 책상메이트 담곰이랑

 

 

회사에서 임베디드 검증 관련한 솔루션(Rapita)을 담당하게 되었따 

on-target 프로젝트 실습을 위해서 stm32IDE 에서 소스코드를 만들어 보는 연습을 진행했다.

 

노션에 근무 일지를 작성하고 있는데, 사내 정보는 외부 공유가 안되니 혼자 갖고 있기 아쉬운 정보가 많은데

stm 정도야 범용으로 사용되니 오랜만에 공유용으로 기록해놓으려고 함

 

23년에 stm32관련해서 잠깐 하만반도체아카데미에서 배운적이 있었는데 강사가 영 못미더웠던 기억이...

2년이 지난 지금 gpt와 함께하니 막힘이 없다..... 갓피티...

 

 


요약

HAL 라이브러리 함수(HAL_GPIO_TogglePin, HAL_Delay, HAL_GPIO_EXTI_Callback)을 이용하여 

NUCLEO-F103RB의 B1 (User button), LD2 (User LED) 입출력을 담당하는 메인함수, 인터럽트 작성법

 

기본 RUN동작에서는 LED가 500ms 간격으로 깜빡이며

B1버튼을 눌렀을때(인터럽트) LED가 100ms 간격으로 빨리 깜빡이게 할것임

 

아래 빨간색 박스 쳐놓은 버튼(B1)과 LED(LD2)가 유저가 임의로 사용가능한 GPIO이다.

 


프로젝트 작성

 

STM32IDE CUBE 프로그램 실행 > New Project > Target Selection > Board Selector

 

사용중인 EVB보드인 'NUCLEO-F103RB' 검색 후에 해당 아이템 클릭

 

 

 

Targeted Language: C

Targeted Binary Type: Executable -> elf, bin 등 실행 가능한 프로그램으로 만듦 / Static 선택시에 lib파일(.a) 생성

Targeted Project Type: STM32Cube

 

 

STM32 MX(.ioc)셋팅)

GPIO mode> External Interrupt Mode with Rising/Falling edge trigger detection

 

우리가 쓰려는 B1 버튼은 PC13 핀과 연결되어 있다. (아래 Schematic 참고- mb1136-default-c04_schematic.pdf )

이는 GPIOC, GPIO_PIN_13번을 의미한다. B1을 인터럽트로 사용할 것이며 버튼을 눌렀을 때/ 뗐을때를 인식해야하기 때문에

위 설정과 같이 Rising/Falling edge 트리거 설정해준다.

 

또한 인터럽트 Enable 시킨다.

NVIC>EXTI line[15:10] interrupts > 아래와 같이 체크

 

 

LD2의 경우에 mx에서 친절하게 PA5(GPIOA, GPIO_PIN_5)로 할당되어있다고 알려준다.

오지랖좀 부려서 회로도를 다시 살펴보면 PA5와 연결되어 있는 것을 확인할 수 있다. (참고용)

 

 

 

이렇게 간단하게 GPIO/NVIC config만 설정해주고 난뒤,

상단 툴에서 저장>code generation이 자동으로 수행된다.


main.c 작성

 

우리가 추가로 작성해야할 부분은 세 가지다.

 

그리고 이미 다 알겠지만, 중간 중간에 ioc 셋팅을 바꿔주면 code generation이 재수행되는데

이때 작성한 코드가 안날아가게 /* USER CODE BEGIN 그리고 END */ 사이 구간에만 작성해야한다!

기본 변수 blink_delay 설정

/* USER CODE BEGIN 0 */
volatile uint32_t blink_delay=500;
/* USER CODE END 0 */

기본 깜빡임 주기를 blink_delay=500ms 으로 설정

HAL_Delay 함수에 쓰이는 변수이다.

 

이건 while문에서 돌아갈 메인 함수

 /* USER CODE BEGIN WHILE */
  while (1)
  {
	  	HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
	  	HAL_Delay(blink_delay);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

 

HAL_GPIO_TogglePin(GPIO_TypeDef, GPIO_Pin) 에 PA5포트는 아래와 같이 설정한다.

GPIO_TypeDef = GPIOA

GPIO_Pin = GPIO_PIN_5 

 

함수의 역할은 말그대로 이전 상태에서 토글시켜 주는 것!

자세한 기능은 F3타고 들어가면 나오는데 먼말인지 모름

 

-> stm32f1xx_hal_gpio.c 참고

 

 

인터럽트 콜백 함수 작성

/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == GPIO_PIN_13)
	{
		if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13) == GPIO_PIN_RESET) {
			blink_delay = 100;
		}else{
			blink_delay = 500;
		}
	}
}
/* USER CODE END 4 */

 

인터럽트가 GPIO 신호를 기다렸다가, GPIO13번핀 (B1버튼의 변화) falling, rising 를 감지한다.

 

B1버튼이 눌려지고 있을 때, 즉 falling한 상태(0=GPIO_PIN_RESET) 가 이어지면

(=if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13) == GPIO_PIN_RESET))

blink_delay를 100으로 주기를 짧게 바꾸고,

 

다시 버튼을 뗐을 때 즉, rising edge가 감지되면 else 문이 돌아서 blink_delay를 다시 500ms 주기로 바꾼다.

 

이 함수도 인터럽트를 enable하면 자동 셋팅되는

stm32f1xx_hal_gpio.c 내부에 선언되어 있고,

 

stm32f1xx_it.c

EXIT15_10_IRQHandler 에서 GPIO13번핀이 할당되어 있는지 확인

 

저장 후에 Run 돌려주면 디버거 통신 불(LD1)이 녹색->빨간색 연달아 깜빡이면서 펌웨어 다운로드/실행 됨


결과 

깜 빡 깜 빡 -> (버튼) 깜빢깜ㅃ까ㅃ깜빢깜ㅃ깎마ㅃㄲ -> (손뗌) 깜 빡 깜 빡

 

어우 왜케 크냐

 

그럼 이만