← Back to EE Projects

Dual-BLDC Driver Board

STM32 • C • DRV8313 • PWM • Closed-loop commutation • KiCad

Overview

A two-channel brushless DC motor driver built around the TI DRV8313 three-phase pre-driver and an STM32 MCU. The board takes a single battery rail, sequences the motor power on through an inrush-limited path, and exposes UART + SPI interfaces for command and telemetry. I designed the schematic, did layout, brought up the prototype, and wrote the firmware from the HAL up.

Hardware

  • MCU: STM32 — runs commutation ISR off TIM1, ADC-injected for current sense.
  • Driver: 2× DRV8313 three-phase pre-drivers (one per motor).
  • Sensing: three-phase low-side shunts + op-amp gain stage; hall-effect inputs on EXTI.
  • Power: 7–12 V battery rail, LDO down to 3.3 V for logic, bulk caps sized for transient demand.
  • I/O: ultrasonic + IR sensor inputs for the robot platform; SWD header for debug.

Schematics

Schematic exports from KiCad, organized by subsystem. Click any image to open full-resolution.

Top-level schematic of the dual-BLDC driver board
Top-level — power rail, MCU, dual DRV8313 driver blocks, and sensor I/O.
Power section — battery input, protection, 3.3 V LDO
Power section — reverse-polarity protection, bulk capacitance, and 3.3 V LDO for logic.
DRV8313 driver block with phase shunts and hall inputs
DRV8313 channel — three-phase pre-driver, low-side shunt sense, and hall-input filtering.

Firmware

  • HAL: thin abstraction over STM32 HAL exposing motor_set_duty(), motor_get_current(), and event hooks.
  • Commutation: six-step trapezoidal commutation driven from hall transitions on EXTI; soft-start ramp on enable.
  • Current sense: ADC injected conversions synchronized to PWM low-side; closed-loop PI on phase current.
  • Comms: UART command parser with a tiny line protocol for setpoints, telemetry, and faults.
  • Faults: over-current, lost-hall, and stall detection — all latching with an explicit clear command.

Bring-up & Debug

First-power was on a current-limited bench supply with the MCU held in reset. I checked rails, measured DRV8313 quiescent current, then released reset and verified PWM at the gates with a scope before connecting a motor. Hall jitter on long leads was the first real bug — fixed with a Schmitt-buffer + RC filter on each hall input. Then I closed the current loop and tuned the PI gains against a step response captured on the scope.

What I'd do differently

  • Use the DRV8313's nFAULT line on an EXTI instead of polling the status flag — saves an SPI round-trip.
  • Reroute the shunt-sense traces as Kelvin connections; the current readings have a small offset I'd rather not calibrate out in firmware.
  • Add a dedicated test header for the hall inputs; I ended up clipping to test points and it was annoying.