STM32 Grid-Tied Inverter Firmware Architecture: From ADC to PWM
Grid-tied inverters convert DC power from photovoltaic arrays or battery banks into synchronized, high-fidelity AC power for injection into utility grids. On STM32 microcontrollers—particularly the high-performance STM32H7 and real-time-optimized STM32G4 families—the firmware architecture must orchestrate precise timing, deterministic control loops, and rigorous safety enforcement. This article details a production-grade firmware architecture for a three-phase, two-level grid-tied inverter, covering signal acquisition, synchronization, regulation, actuation, and state management—all implemented on a single STM32 MCU without external DSPs or FPGAs.
ADC Sampling and Synchronization
Accurate current and voltage sensing is foundational. For a 50/60 Hz grid, sampling at ≥20 kS/s per channel enables sufficient harmonic resolution for closed-loop control. STM32H7’s dual ADC mode with interleaved sampling allows simultaneous capture of up to six channels (e.g., three phase currents + three grid voltages) with sub-100 ns skew. Critical to grid synchronization is triggered sampling: the ADC conversion start is hardware-synchronized to the PWM timer’s update event (i.e., at each PWM period boundary), ensuring samples align with the control execution window.
Hardware synchronization eliminates software-induced jitter. The ADC is configured in regular injected group mode, where injected conversions (for grid voltage zero-crossing detection) preempt regular conversions (for current feedback). A dedicated GPIO pin monitors the grid voltage zero-crossing via a comparator; its EXTI interrupt initializes the PLL and primes the first ADC trigger, establishing absolute phase alignment within ±0.5°.
Phase-Locked Loop (PLL) Implementation
The PLL estimates grid frequency and phase angle in real time. Unlike classical analog PLLs, the digital implementation uses a software-based second-order type-II loop running at 20 kHz:
- Input: Grid voltage sine/cosine (from ADC or lookup table)
- Phase detector: arctan2(Vq, Vd) → instantaneous phase error
- Loop filter: Proportional-integral (PI) with gains Kp = 0.02, Ki = 0.001
- VCO: Integrator producing θ_grid(t), updated every control cycle
This approach delivers <10 ms lock time after grid disturbance and tracks ±0.5 Hz frequency drift without loss of lock. The output θ_grid serves as the reference for Park transformation in the current controller and as the basis for PWM carrier phase alignment.
Current Control Loop: PI + Resonant Compensation
A synchronous-frame PI controller alone cannot eliminate steady-state error at 50/60 Hz due to finite gain at the fundamental frequency. Hence, the design employs a PI + PR (Proportional-Resonant) controller in the dq-frame:
// Simplified PR controller in dq-frame (executed per control cycle @20 kHz)
float32_t err_d = i_d_ref - i_d_meas;
float32_t err_q = i_q_ref - i_q_meas;
// PR term: infinite gain at ω₀ = 2π·50
float32_t pr_d = Kp_pr * err_d + Ki_pr * (err_d * Ts + integrator_d);
float32_t pr_q = Kp_pr * err_q + Ki_pr * (err_q * Ts + integrator_q);
// Combined output
v_d_out = pi_d_out + pr_d;
v_q_out = pi_q_out + pr_q;
The resonant term provides near-infinite gain precisely at grid frequency, eliminating static error while maintaining stability margins. Anti-windup and saturation handling are enforced before inverse Park transformation.
PWM Generation with Advanced Timers
STM32’s advanced-control timers (e.g., TIM1/TIM8 on H7/G4) deliver the precision required for space-vector PWM (SVPWM). Key features leveraged include:
- Break input (BKIN) for immediate fault-driven PWM shutdown (sub-100 ns response)
- Repetition counter for multi-cycle modulation patterns (e.g., 3-level SVM on 2-level hardware)
- Complementary output with programmable dead-time (25–200 ns granularity)
- Trigger outputs synchronized to counter update events for ADC sampling
The SVPWM algorithm computes sector and duty cycles in fixed-point arithmetic (Q15) to ensure deterministic execution (<1.2 µs worst-case on Cortex-M7 @480 MHz). Carrier synchronization ensures that the PWM zero-voltage vectors occur exactly at grid voltage zero crossings—minimizing reactive current injection during connection transients.
Protection Interrupts and Fault Handling
Safety-critical protections run in dedicated interrupt contexts with strict priority ordering:
| Interrupt Source | Priority | Response Action | Max Latency |
|---|---|---|---|
| TIM1 BRK (hardware overcurrent) | Highest (0) | Disable all PWM outputs, assert hardware fault latch | < 120 ns |
| ADC OVR (overrun) | High (1) | Log overrun, reset DMA, reinitialize ADC | < 3 µs |
| EXTI9_5 (grid disconnect) | Medium (3) | Enter anti-islanding state, ramp down power over 200 ms | < 10 µs |
Each handler executes only essential actions—no floating-point math, no memory allocation, no function calls beyond HAL macros. Full diagnostics (fault type, timestamp, pre-fault waveforms) are logged to backup SRAM with ECC enabled.
State Machine for Grid Connection
A hierarchical state machine governs safe grid interconnection. It enforces IEC 62109 and UL 1741 SA requirements—including anti-islanding, voltage/frequency ride-through, and soft-start sequencing:
- INIT: System self-test, ADC calibration, timer initialization
- STANDBY: Monitor grid voltage magnitude (±5%), frequency (±0.5 Hz), THD (<8%)
- PRECHARGE: Close precharge contactor, verify DC-link voltage ramp rate <50 V/s
- SYNCHRONIZE: Match inverter voltage amplitude, phase, and frequency to grid using PLL + feedforward
- CONNECT: Close main contactor, enable PWM, begin PQ control
- OPERATE: Run MPPT (if PV-coupled) and grid-support functions (reactive power, LVRT)
- DISCONNECT: Initiated on grid fault, anti-islanding detection, or user command
Transitions require triple confirmation: timer-based debounce (20 ms), redundant sensor validation (e.g., two independent voltage dividers), and watchdog supervision. The state machine runs in the main loop at 100 Hz, decoupled from the 20 kHz control loop.
Architectural Integration and Timing Budget
The full firmware stack is partitioned across three execution domains:
- High-frequency domain (20 kHz): ADC ISR → PLL → Current controller → SVPWM update
- Medium-frequency domain (1 kHz): DC-link voltage loop, thermal monitoring, communication framing
- Low-frequency domain (100 Hz): State machine, logging, Modbus/CAN message handling
Cycle timing is verified using STM32CubeMonitor and hardware trace (SWO/ITM). Worst-case 20 kHz ISR execution is 4.8 µs (H743 @480 MHz), leaving 10.2 µs margin before next PWM update. All shared resources (e.g., control setpoints) use lock-free ring buffers or atomic flag handshaking—no RTOS kernel required for core functions.
Frequently Asked Questions
How does this architecture handle grid voltage sags?
During sags, the dq-frame current controller increases reactive current injection (Q-mode support) while limiting active current to preserve thermal limits. The PLL remains locked using adaptive bandwidth (widens during transients), and the state machine transitions to Low-Voltage Ride-Through (LVRT) mode—holding connection for up to 150 ms at 0.5 pu voltage per IEEE 1547-2018.
Can this firmware run on STM32G4 without hardware FPU?
Yes—with minor trade-offs. The G4’s single-precision FPU supports all control math, but fixed-point Q15/Q31 libraries (CMSIS-DSP) reduce latency by ~18% and improve determinism. We recommend Q31 for PI/PR controllers and float32 only for PLL phase integration and logging. All critical paths remain under 3.5 µs on G474 @170 MHz.
What anti-islanding methods are implemented?
Dual-layer detection: (1) Passive—real-time monitoring of grid voltage THD, frequency deviation, and rate-of-change of frequency (ROCOF > 0.5 Hz/s); (2) Active—small, out-of-phase current perturbations (±0.2% amplitude, 1 Hz offset) injected during idle periods. Detection triggers disconnection within 200 ms per UL 1741 SA.
