Field-Oriented Control transformed brushless DC motors from fast but torque-rippled machines into the smooth, precise actuators found in modern EV drivetrains and robotics. If you have ever wondered how a Tesla Model 3 motor achieves linear torque from zero to 18,000 RPM, the answer is FOC running at 20 kHz on a DSP core.

Why FOC?FOC decouples flux-producing (Id) and torque-producing (Iq) stator current components, enabling independent control of each — maximum torque per ampere with minimal ripple.

Why FOC?

Conventional trapezoidal (6-step) commutation produces significant torque ripple at commutation points. FOC replaces this with continuous sinusoidal currents that track rotor position precisely. The trade-off is computational complexity — which modern Cortex-M4/M7 MCUs handle comfortably at 20 kHz control loops.

Clarke and Park Transforms

Clarke Transform

Converts three-phase [Ia, Ib, Ic] into two-axis stationary frame [I-alpha, I-beta]:

/* Clarke Transform (stationary alpha-beta frame) */ float I_alpha = I_a; float I_beta = (I_a + 2.0f * I_b) * ONE_OVER_SQRT3;

Park Transform

Rotates [I-alpha, I-beta] by electrical rotor angle theta_e to produce DC quantities [Id, Iq]:

/* Park Transform (rotating d-q frame) */ float I_d = I_alpha * cos_theta + I_beta * sin_theta; float I_q = -I_alpha * sin_theta + I_beta * cos_theta; // I_d: flux control (= 0 for surface PMSM) // I_q: torque control (set by speed loop)

The Complete FOC Control Loop

  1. Sample Ia and Ib via shunt resistors at PWM valley for minimum switching noise
  2. Clarke transform: [Ia, Ib] to [I-alpha, I-beta]
  3. Read rotor angle from encoder, resolver, or sensorless observer
  4. Park transform: [I-alpha, I-beta] to [Id, Iq] using theta_e
  5. Two independent PI loops regulate Id to 0 and Iq to Iq_ref
  6. Inverse Park: [Vd, Vq] to [V-alpha, V-beta]
  7. Space Vector PWM: generates gate signals — 15% more DC bus utilization vs sinusoidal PWM

Implementing on STM32G4 with CORDIC

The STM32G4’s CORDIC hardware accelerator computes sin/cos pairs in just 4 clock cycles — vs 30-60 cycles for software calls. Critical when the FOC loop must execute in under 5 us at 20 kHz PWM:

/* CORDIC sin/cos computation */ CORDIC->WDATA = theta_q31; uint32_t result = CORDIC->RDATA; float cos_theta = q31_to_float((int32_t)(result & 0xFFFF)); float sin_theta = q31_to_float((int32_t)(result >> 16)); /* Full FOC loop: 3.8 us on 170 MHz Cortex-M4 */

Sensorless: Sliding Mode Observer

When no shaft encoder is available, the SMO estimates back-EMF from measured voltages and currents, then extracts position via arctangent:

  • Applicable above 5-10% of rated speed
  • Typical estimation error: +/-3-5 electrical degrees at rated speed
  • No additional hardware required beyond current sensors
  • Combine with I/f open-loop startup below minimum SMO speed

Conclusion

FOC on STM32 requires CORDIC for transforms, center-aligned PWM with synchronized ADC triggers, and carefully tuned PI loops. At Firmness Technologies, we implement production FOC firmware for EV traction drives, servo actuators, and industrial compressors — always with HIL validation before hardware deployment.

Leave A Comment