Maintainer: Ahn Euichan
Last updated: 2026-05-20
STM32F401RE 기반 BLDC 모터를 대상으로 Field Oriented Control(FOC), 3상 전류 피드백, sensorless SMO/PLL observer, 속도 제어를 실험하기 위한 펌웨어 프로젝트입니다.
본 프로젝트는 STM32CubeMX가 생성한 모듈식 구조(adc.c, tim.c, usart.c, gpio.c 등)를 기반으로 하며, FOC 제어 로직은 Core/Src/foc/ 및 Core/Inc/foc/ 아래에 분리되어 있습니다.
| 항목 | 사양 |
|---|---|
| MCU 보드 | NUCLEO-F401RE (STM32F401RET6, Cortex-M4F @ 84 MHz) |
| 모터 드라이버 쉴드 | X-NUCLEO-IHM07M1 계열 3상 인버터 보드 |
| 모터 | 3상 BLDC/PMSM 모터 (현재 설정: 11 pole pairs) |
| 전류 센싱 | 3상 shunt current feedback |
| 통신 | ST-LINK 가상 COM 포트 (USART2, 115200 baud) |
| 도구 | 버전 |
|---|---|
| STM32CubeIDE | 1.20.x 이상 권장 |
| STM32CubeMX | 6.x 계열 |
| STM32Cube FW_F4 | STM32F4 HAL/CMSIS 기반 |
| Compiler | arm-none-eabi-gcc |
- 3상 PWM 출력 — TIM1 center-aligned PWM, 20 kHz
- ADC injected 동기 샘플링 — 3상 전류 및 DC bus 전압 측정
- 전류 오프셋 캘리브레이션 — 부팅 후 1024 sample 평균
- Clarke / Park / inverse Park / SVPWM
- Phase 3 open-loop V/f ramp
- Phase 4 forced-angle d/q current PI
- Phase 5 sensorless observer
- SMO 기반 BEMF 추정
- PLL 기반 전기각/전기각속도 추정
- open-loop ramp 이후 observer handoff
- Phase 8 sensorless speed control
- 저속 BEMF 한계를 고려한 최소 sensorless speed 정책
- speed PI →
iq_ref변환
- UART CLI
p3: open-loop V/f 시작p3v <V>: Phase 3 q축 전압 overridep3w <rad/s>: Phase 3 전기각속도 overridep4: forced-angle current PI 시작p4i <A>: Phase 4 q축 전류 step 설정p5: sensorless observer startup 시작obs <rad>: observer control angle offset 설정spd <rad/s>: Phase 8 기계각속도 명령set <p> <v> <kp> <kd> <tff>: impedance commandhb 0|1: heartbeat 출력 on/off
- 보호 로직
- DC bus undervoltage/overvoltage
- phase overcurrent 및 current sum check
- TIM1 BKIN hardware break
- ADC stall 감지
- command timeout 일부 처리
- CubeMonitor 디버그 미러
g_foc_debug구조체로 전류, 전압, observer, speed/impedance 상태 노출
- STM32CubeIDE에서 File → Open Projects from File System... 으로 본 디렉토리 import
- Project Explorer에서
bldc_foc_f401우클릭 → Build Project - NUCLEO 보드를 USB로 연결
- Run As → STM32 C/C++ Application
CLI 빌드는 CubeIDE가 생성한 Debug/makefile과 ARM GCC toolchain이 PATH에 있을 때 사용할 수 있습니다.
make -C Debug allbldc_foc_f401/
├── Core/
│ ├── Inc/
│ │ ├── app/ # 애플리케이션 계층 헤더
│ │ ├── foc/ # FOC API 및 SVPWM 헤더
│ │ └── *.h # CubeMX 생성 peripheral 헤더
│ ├── Src/
│ │ ├── app/ # UART CLI, heartbeat, app init
│ │ ├── foc/ # FOC 상태머신, observer, PI 제어
│ │ └── *.c # CubeMX 생성 peripheral 소스
│ └── Startup/ # STM32 startup assembly
├── Drivers/
│ ├── CMSIS/ # ARM/ST CMSIS
│ └── STM32F4xx_HAL_Driver/ # STM32F4 HAL
├── STM32F401RETX_FLASH.ld # Flash linker script
├── STM32F401RETX_RAM.ld # RAM linker script
├── bldc_foc_f401.ioc # CubeMX 프로젝트 설정
├── README.md # 한국어 README
├── README.en.md # English README
└── LICENSE # 라이선스 고지
본 프로젝트는 인터럽트 기반으로 동작합니다. main() 루프는 app_poll()을 호출하고, 실시간 제어는 ADC/TIM 인터럽트에서 수행됩니다.
TIM1 PWM Update
└─ ADC1 injected trigger
└─ HAL_ADCEx_InjectedConvCpltCallback()
├─ 3상 전류 / DC bus 전압 샘플링
├─ 전류 오프셋 보정 및 SI 단위 변환
└─ foc_inner_loop() # 20 kHz FOC inner loop
TIM4 Update IRQ
└─ HAL_TIM_PeriodElapsedCallback()
└─ foc_outer_loop() # 1 kHz protection / speed / impedance / debug mirror
USART2 RX IRQ
└─ app_process_rx_line()
└─ UART CLI 명령 처리
주요 구현 위치:
- FOC inner loop: Core/Src/foc/foc.c
- SVPWM helper: Core/Inc/foc/svm.h
- UART CLI / heartbeat: Core/Src/app/app.c
- ADC 설정: Core/Src/adc.c
- TIM1/TIM4 설정: Core/Src/tim.c
기본적인 bring-up은 아래 순서로 진행합니다.
p5
spd 10
현재 speed control은 BEMF 기반 sensorless observer를 사용하므로 매우 낮은 속도에서는 안정적인 속도 추정이 어렵습니다. 비영속도 명령이 너무 낮으면 내부적으로 최소 sensorless speed 이상으로 올려서 처리합니다.
주요 heartbeat 필드:
| 필드 | 의미 |
|---|---|
m |
run mode |
f |
fault code |
vb |
DC bus voltage [V] |
ia, ib, ic |
phase current [A] |
id, iq |
measured d/q current [A] |
iqr |
q-axis current reference [A] |
vr, vm |
mechanical speed reference / estimate [rad/s] |
omo |
observer electrical speed [rad/s] |
terr |
observer control angle error against open-loop ramp [rad] |
eq, emag |
observer BEMF q-axis component / magnitude [V] |
vq |
q-axis voltage command [V] |
주요 튜닝 상수는 Core/Src/foc/foc.c 상단에 정의되어 있습니다.
| 매크로 | 설명 |
|---|---|
FOC_PHASE6_NPP |
pole pair 수 |
FOC_PHASE6_KT_NM_PER_A |
토크 상수 |
FOC_TORQUE_TO_IQ_SIGN |
기계 토크 명령과 q축 전류 부호 관계 |
FOC_PHASE4_KP_D, FOC_PHASE4_KI_D |
d축 전류 PI gain |
FOC_PHASE4_KP_Q, FOC_PHASE4_KI_Q |
q축 전류 PI gain |
FOC_PHASE4_V_LIMIT_GAIN, FOC_PHASE4_V_LIMIT_MAX |
전류 PI 전압 제한 |
FOC_OBSERVER_PLL_KP, FOC_OBSERVER_PLL_KI |
observer PLL gain |
FOC_SPEED_KP_A_PER_RAD_S, FOC_SPEED_KI_A_PER_RAD |
speed PI gain |
FOC_SPEED_IQ_LIMIT_A |
speed loop 전류 제한 |
FOC_SPEED_SENSORLESS_MIN_RAD_S |
sensorless speed feedback 최소 기계각속도 |
g_foc_debug 구조체는 1 kHz로 갱신되며 CubeMonitor에서 직접 plot할 수 있습니다.
주요 필드:
i_a_amp,i_b_amp,i_c_ampi_d_amp,i_q_ampi_d_ref_amp,i_q_ref_ampv_d_volt,v_q_voltv_bus_voltobserver_e_alpha_volt,observer_e_beta_volt,observer_e_magnitude_voltobserver_theta_rad,observer_omega_rad_sphase6_mech_position_rad,phase6_mech_velocity_rad_sphase6_iq_ref_a,phase6_torque_ref_nm
- BEMF 기반 sensorless 특성상 정지 및 초저속 속도 제어는 제한적임
- 저속 영역 제어를 위해 Hall sensor, encoder, HFI 등 추가 추정 방식 검토 필요
- motor parameter identification 자동화 미구현
- observer handoff 조건 및 PLL gain에 대한 추가 실험 필요
- 전류/전압 보호 임계값을 실제 모터 정격에 맞게 재검증 필요
안의찬 (Ahn Euichan)
라이선스 정보는 LICENSE를 참고하세요.
본 저장소에는 출처가 다른 코드가 함께 포함되어 있으며, 각 출처의 라이선스를 따릅니다.
| 영역 | 출처 | 라이선스 |
|---|---|---|
Drivers/CMSIS/ |
ARM CMSIS | Apache-2.0 (LICENSE.txt) |
Drivers/CMSIS/Device/ST/STM32F4xx/ |
ST CMSIS device files | Apache-2.0 fallback (LICENSE.txt) |
Drivers/STM32F4xx_HAL_Driver/ |
ST HAL | BSD-3-Clause fallback (LICENSE.txt) |
Core/ 일부 CubeMX 생성 코드 |
ST CubeMX | 각 파일 헤더 및 ST 라이선스 고지 참조 |
| 본 프로젝트 신규 FOC/app 코드 | Ahn Euichan | LICENSE 고지 참조 |
ST 또는 ARM이 배포한 코드의 라이선스 조건은 각 디렉토리의 라이선스 파일 및 소스 파일 헤더를 따릅니다. 재배포 시 저작권 표시와 라이선스 고지를 보존해야 합니다.