본문 바로가기

KAIROS 2기

[카이로스2기] STM32 기초 : 실무에서 쓰는 마이크로 컨트롤러 배우기

3D 모델링을 뒤로하고, 다시 배선과 코딩의 시간이 돌아왔다!

특히 이번에 배우는 STM32는 어린 친구들부터 접하는 아두이노와 다르게 현업에서 많이 사용하는 마이크로 컨트롤러라고 하여 기대가 컸다.😻

결론적으로 찍먹해본 STM32는 확실히 어렵지만 강력한 친구임을 느낄 수 있었다.

카이로스 2기에서 다룬 STM32 후기를 아래와 같이 간단히 소개한다!👾 

1. STM & Cube IDE
2. 기본 동작(LED 켜기/모터 연동)
3. Serial 통신
4. Clock & Timer 
5. PWM 제어

 

1. STM & Cube IDE

STM32는 ARM Cortex-M 기반의 마이크로 컨트롤러로, 아래 사진처럼 아두이노와 비교하면 훨씬 많은 핀을 가지고 있다.

아두이노와의 차이는 각 항목마다 조금씩 더 적어보려고 했으니 아래 내용에서 확인😺

STM32를 구동하기 위해 사용하는 IDE는 CubeIDE이다. (개인적으로 이클립스 IDE는 계속 써도 손에 익지 않아서 같은 형식인 IDE라서 슬펐다😂)

 

개발을 시작하며 제일 눈에 띄는 차이점은 역시 PIN 관리방식이었다.

Pin 하나하나 pinMode 적용해주어야했던 아두이노와 달리, STM32는 무려 GUI 방식으로 핀을 설정할 수 있다.

Output 핀의 경우 GPIO_Output으로 설정할 수 있고, 후에 기술할 Timer의 Channel도 부여 가능하다. 또한, 초기 세팅창의 다양한 요소들은 서로 자동 연동되어있어 Serial 설정을 해두면 13, 14번 포트가 자동으로 열린다거나 USART2를 열면 PA2, 3번이 열리는 식으로 바로바로 결과를 확인할 수 있어서 이후 배선을 할때도 매우 편했다.


그리고 또다른 특징은 Debugger 영역이 있어서 디버깅이 가능했다는 점!

위의 실물 사진에서 보드에 전원이 연결된 부분 바로 아래 영역이 디버깅을 위한 부분이라고 한다.

디버깅 모드를 통해 Interrupt의 breakpoint가 잘 들어오는지 확인도 하고, 변수에 실시간으로 들어오는 값을 단계별로 확인할 수 있어서 문제 해결에도 정말 일등공신이었다.👍

 

2) 기본 동작

STM32로 아두이노에서 했던 제일 기본적인 동작들부터 진행했다.

정말 신기했던건 STM32에는 LED와 버튼이 내장되어 있어서 별도 배선 필요없이 바로 시작할 수 있었다는 점!

LED의 경우는 PD12~15번에 각 색별로 연결되어 있다. PD12번을 Output으로 설정하고, TogglePin 함수 한번이면 아두이노에서 꽤나 시간 걸렸던 LED 토글이 바로 된다.

// LED 토글
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);

 

STM32에서는 기본적으로 HAL (Hardware Abstraction Layer) 함수를 통해 동작하는데, 더 Low level로 제어하고자 하는 사람이 아니라면.. HAL 함수를 쓰는 것이 좋다고 강사님께서 말씀하셨다^^ 나는 HAL 함수에 그저 무한한 감사를 할 뿐..🙃

HAL_GPIO는 기본적으로 (GPIO type(A인지 D인지 등..), 핀번호, (필요시)설정값)으로 이루어져 있다.

TogglePin 같은 경우는 PD12를 쓰니까 GPIOD, 12번 핀을 쓰니까 GPIO_PIN_12를 넣고, 토글은 ON/OFF의 반복이니 설정값은 별도로 입력하지 않는다. 함수에 대한 상세 내용은 함수에서 Ctrl 누르고 들어가서 확인할 수 있다!


다음으로 STM32의 내장 버튼을 누르면 모터 돌아가게 하려면?🤔

ReadPin으로 A0 버튼의 값을 읽어오고, 그 버튼 값에 따라 WritePin의 SET/RESET 값을 주면 된다.

이전 RC카에서 다루었듯이 DC모터의 경우 앞으로 도는것, 뒤로 도는것이 한쌍이라 SET/RESET을 번갈아 주었다.

아래 코드는 버튼이지만 interrupt를 사용한 것은 아니고, 단순히 누르고 있을 때, 뗏을 때 기준이다. interrupt는 조금 뒤에~

  int btn_fg = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);

  if (btn_fg == 1) {
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
  }
  else {
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
  }

 
3) Serial 통신

기본 동작을 잘 수행하고 있다면, python과 통신하여 값을 전달하고, 전달받는 단계로 넘어간다.

이 단계가 결국 아두이노든 STM이든, 실 사용자와 소통하며 센서 값을 전달하거나, 동작을 전달받거나 할 수 있다는 점에서 그 중요성과 필요성을 느끼는 부분이다.

이부분 코드의 핵심은 통신에 대한 interrupt가 발생하면, it.c 파일의 IRQHandler가 호출되고, 그 안의 Callback 함수가 실행된다는 것을 이해하는 부분이다.

그러므로 통신에 대한 내용을 추가하고자 할 때, callback 함수에 입력할 수 있지만, hal_uart.c에 정의된 callback은 __weak가 선언된, 실사용을 위한 함수가 아니므로, main.c에 같은 이름의 함수를 재정의하여 사용한다.😎

// it.c 
void UART2_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart2);
}

// hal_uart.c
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_UART_RxCpltCallback could be implemented in the user file
   */
}

// main.c
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  // interrupt시 사용하고 싶은 내용
}

 
4) Clock / Timer

STM32를 배우며 가장 놀랐고 어려웠던 Clock Configuration.. 😇
시간에 대한 개념을 따로 조정할 수 없었던 아두이노와 달리, STM32에서는 HSI/HSE/LSI/LSE 4종류의 시계를 가지고 있다. 우리는 주로 HSE(High Speed External)를 사용했다. 

 

Timer는 Timer4를 사용하였는데, 여기서 중요한 지표값은 Prescaler와 Counter Period 값이다.

- Prescaler : clock이 몇번 돌아야 실제 타이머 증가로 반영할지 결정
- Counter period : 어느 값까지만 올라가고 interrupt 되고 초기화될지 결정

이 값을 조정하여 정확하게 1초 주기로 LED가 깜빡이게 세팅할 수 있었다.

그러나 MHz 단위와 현란한 수식은 나를 혼란스럽게 해요.. 카이로스 2기 종로 반 친구들이 적극적으로 이해한 바를 다양한 예시로 설명해줘서 겨우 이해했다..😧 그러나 앞으로도 자신없다구🤡


5) PWM (Pulse Width Modulation)

마지막으로 PWM까지 다뤄봤는데, PWM은 아두이노의 analogWrite 역할처럼, 디지털 신호를 아날로그 신호처럼 조정하기 위해 Duty를 변경해줄 수 있다.

이를 통해 단순히 ON/OFF 값이 아니라, LED의 밝기나 서보모터의 각도 같은 값을 정밀하게 조정할 수 있다.

(이해 도움을 위해 가져온 사진..아래 사이트에서 Duty Cycle과 Frequency를 조정하며 펄스를 볼 수 있다.)

출처 : https://deepbluembedded.com/stm32-pwm-example-timer-pwm-mode-tutorial/#google_vignette

 
카이로스 2기 강사님께서는 보다 직관적인 이해를 위해 오실로스코프를 통해 직접 펄스를 보여주시기도 했다!😮

코드 상으로는, IDE에서 TIM4에 'PWM Generation CH1'으로 설정해주고, TIM4_CH1이 PD12에 연결되게 하면 타이머4와 12번핀 LED를 연결하여 조작 가능하다.💡

 

이렇게 지금까지 배운 내용을 총정리하여, python tkinter에서 보낸 값으로 STM32에 연결된 서보모터 각도 조절하기를 해보았다. 이를 위해서는 Serial 통신을 연결해서 callback 함수에 PWM을 적용해야하는 만큼 이 과정을 통해 전반적인 흐름에 대한 이해가 크게 늘었던 것 같다.💪

 


STM32 학습 후기 👀
- 처음에는 정말 어리둥절하기만 했는데.. 그래도 일주일이 끝나갈때쯤 삽질을 많이했더니 이해했다. 역시 개발은 삽질하는 맛이야.. 그래도 Fusio360 하다가 코드 짜니까 기분째져😋

- Clock 진짜 어렵다😇 + 개인적으로는 Interrupt에서 weak 함수를 main에서 재정의하는 개념이 깔끔해서 마음에 들었다!
- 실제로 현업에서 어떻게 많이 쓰는건지는 사실 좀 감이 안오는 부분이 있다. 실무에서는 당연히 훨씬 큰 영역의 제어가 될 것 같은데, 더 다룰 수 있는 시간이 있었으면 좋았을 것 같다.
 


🌱 카이로스 2기에서 배우는 Fusion360 3D 모델링이 궁금하다면?

https://bagjo2884.tistory.com/19
 

 

[카이로스2기] Fusion360 기초 : 2D 스케치부터 3D 모델링까지

도면 자체를 본 적도 거의 없는 비전공자인 나에게 3D 모델링은 정말 공대생들만 할 수 있는 미지의 영역이었다.카이로스 2기 교육을 통해 Fusion360(퓨전360) 툴을 배우고, 3D 모델링을 진행해볼 수

bagjo2884.tistory.com

 

 

다음주에는 PLC 강의 1차 후기로 돌아옵니다💃