Nelson Rodriguez logo
Published on

STM32 Test Board

Authors
  • avatar
    Name
    Nelson Rodriguez
    Twitter

Last Update:

  • 2025-Nov-19
  • SWD connector added.

Architecture

Design

For this simple test board, the pins and peripherals that will be used are:

  • Serial Wire Debug
  • High Speed External Crystal Oscillator
  • USB Differential Pair
  • I2C
  • UART
SubsystemComponent
MCUSTM32F405RGT6
PowerMP2359DJ
USBUSB Type C
DebugSWD (Serial Wire Debug)
Clock8 MHz Crystal
CommunicationI2C, UART

Schematic

Microcontroller

The microcontroller STM32F405RGT6 is powered with 3.3 V, supplied by the MP2359DJ buck regulator. If you want, you can also power the MCU using a backup source, such as a small battery connected to the VBAT pin. In this project, that backup option wasn’t implemented, so both VBAT and all VDD pins are tied together to the same 3.3 V rail.

Now, let’s talk about VDDA. This pin is the analog reference voltage, and according to the datasheet, it powers the internal analog circuits of the MCU—like the DACs and ADCs. If you don’t plan to use these analog features, you can safely connect VDDA directly to VDD. But if you do plan to use them, it’s a good idea to feed VDDA through a filtered version of the 3.3 V line to reduce noise coming from the main power supply.

The VCAP1 and VCAP2 pins are for the MCU’s internal voltage regulators. The datasheet specifies that each should be decoupled with a 2.2 µF low-ESR ceramic capacitor. In this design, I used 2.2 µF capacitors from the JLCPCB library, using the C_Small symbol whose value is changed to 2u2 indicating the 2.2 µF capacitance. They’re not explicitly rated as low-ESR, but they’ve worked well for me in previous projects.

The NRST pin is the hardware reset for the whole MCU. It’s commonly connected to the debugger so you can reset or reprogram the chip. Internally, the pin has a weak pull-up resistor (about 40 kΩ) to prevent unwanted resets caused by noise or floating signals.

The BOOT0 pin determines the boot mode—basically, how the MCU starts up. According to the datasheet (section 2.2.13 Boot Modes, page 23), this pin decides whether the chip runs your program or enters programming mode.
Here’s the quick version:

  • BOOT0 pulled low (GND): the MCU runs your code from flash memory.
  • BOOT0 pulled high (3.3 V): the MCU enters programming mode (UART, USB, etc.).

This pin should never be left floating. In this project, I made BOOT0 switchable using an SPDT switch, so I can easily toggle between run and programming modes. To protect the pin, I added a small 10 kΩ resistor using the R_Small symbol.

Now, let’s take a look at the pin assignments using the STM32CubeIDE layout view.

The crystal oscillator will be connected to pins PH0 and PH1.
To make the schematic cleaner, I’m using global labels:

  • HSE_IN (High-Speed External In)
  • HSE_OUT (High-Speed External Out)

These correspond to the oscillator input and output pins of the MCU.

For debugging, we’re using the Serial Wire Debug (SWD) interface. The connections are as follows:

  • SWDIO → pin PA13
  • SWCLK → pin PA14
  • SWO → pin PB3 (optional, but very handy if you want to do printf-style debugging through the debugger)

For USB communication, the MCU uses:

  • PA12 for D+
  • PA11 for D-

The I2C bus we’ll use is I2C1, with:

  • PB6I2C1_SCL (clock line)
  • PB7I2C1_SDA (data line)

Finally, for UART communication, we’re using USART3:

  • PB10USART3_TX (transmit)
  • PB11USART3_RX (receive)

In embedded systems, having some physical feedback is super helpful—and one of the simplest ways to do that is by toggling an LED on and off. Let’s assign a pin to control a status LED.
Looking at the pin layout in STM32CubeIDE, a good choice would be either PA2 or PA1. In general, these GPIO pins can source or sink enough current to safely drive a typical LED.

STM32 microcontrollers include internal pull-up and pull-down resistors that can be enabled through software. This helps minimize noise and reduce power consumption for any unused pins. In KiCad, though, you should still mark unconnected pins with No Connect flags to avoid design rule violations.

Tip: To quickly place those “X” symbols, press the INS key in KiCad—it repeats the last placed symbol vertically.

Decoupling capacitors

Now, let’s talk about decoupling capacitors. These capacitors go near the power pins of the IC to stabilize the voltage and filter out noise. During PCB layout, you’ll want to place them as close as possible to each power pin.

For this design, I’m adding:

  • One bulk capacitor of 4.7 µF (to handle larger transients).
  • One small capacitor of 100 nF per power pin, as recommended by STMicroelectronics.

Since the +3.3V net connects to five power pins, that means we’ll need five 100 nF capacitors. I’m using the C_Small symbol for them.

💡 Note for the curious: From a microelectronics perspective, it’s worth exploring why decoupling capacitors are needed and why the IC can’t handle power noise on its own. (That’s a good topic for a future deep dive!)

Filtering the VDDA pin

The VDDA pin provides power to the MCU’s internal analog circuitry, like the ADCs and DACs. Because these blocks are sensitive to noise, it’s a good idea to add an extra filter on this line.

A simple way to do that is to insert a small ferrite bead or inductor—for example, 39 nH using the L_Small symbol—between the +3.3V rail and VDDA. This helps filter out high-frequency noise. On the VDDA side, add both a bulk capacitor (1 µF) and a small capacitor (100 nF) to keep the analog voltage stable.

Crystal Oscillator

On STM32 boards, a 16 MHz crystal oscillator is commonly used because its frequency can be multiplied by the internal PLL to meet the requirements of both the USB interface and the processor core. In this design, the X322516MLB4SI crystal from JLCPCB was selected. According to its datasheet, this crystal has a 4-pin package, so in KiCad it is represented using the Crystal_GND24_Small footprint.

For the surrounding circuitry, it is highly recommended to refer to Application Note AN2867 from STMicroelectronics, which provides detailed guidelines for oscillator design on STM8AF/AL/S and STM32 MCUs/MPUs. Based on this document, 12 pF loading capacitors were chosen, and a 47 Ω feedback resistor was added to ensure proper startup and stability.

Finally I added the circuit for the Status LED, which consists of a limiting current resistor and the LED itself:

STM32 Section

At this point, the first section of the system comprising the STM32 MCU and its essential support circuitry is complete and ready for operation.

Power Section

The part to be used is the MP2359DJ-LF-Z-MS which is a step-down DC-DC buck converter. Due to the symbol of this part is not available in the KiCad built-in libraries, we will have to create it.

To implement this part in the design, we follow the application circuit shown in the datasheet. This circuit is the standard synchronous buck regulator topology. From left to right, we have Cin which stabilizes the regulator's input, EN pin enables or disables the regulator, SW pin toggles between VIN and GND, C1 drives the internal high-side MOSFET of the IC, L1 stores energy when the MOSFET is ON, and with Cout creates a filter to the output, R1, R2 built the feedback divider that sets the output voltage and finally, Cff provides stability to the feedback loop.

Before feeding the 12V into the buck regulator, we should implement some protection mechanisms. The first implementation will be a polyfuse to protect the IC from over current, and the second one will be a PMOS for reverse polarity protection. The MOSFET to be used will be the AO3401A which is a 30V P-Channel MOSFET which has a really low RDSON when it's turned ON. To filter unwanted noise from the supply we added a ferrite bead that has 600 ohms at 100MHz.

In the maximum ratings section of the datasheet, it is established that the enable pin can receive a voltage in the same range of VIN, however the threshold voltage to turn on the regulator is not specified. For that reason I implemented a voltage divider to supply 1.2V to the pin, which is half of the VIN value.

The output voltage is programmed through the resistive feedback network R1 and R2. Below it's a table listing the values of the external passive componentes required to achieve a desired output voltage VOUT. For our system, to get 3.3V we require R1=31.25k and R2=10k. However 31.25k is not a commercial resistor, instead, we choose 30.9k which is the commercial one that sets the VOUT as close as possible to 3.3v. Using the typical regulated feedback voltage of VFB=0.807V, we get VOUT=3.30V.

The value of the bootstrap capacitor C1 is not mentioned in the datasheet, but because this component is a clone of the MP2359DJ-LF-Z from Monolithic Power Systems, we can use the value indicated in its datasheet, which is 10n. Finally, from the table we pick the values of the remaining passive components associated to the row 3.3V:

  • L1 = 3.3uH
  • Cin = 10uF
  • C1 = 10nF
  • Cout = 22uF

Joining all these circuits together, we get the power section as shown below:

Connectors

There are millions of connectors, and the ones you would need will depend on your specific application. For this board, we will use a screw terminal to power the board.

For debugging we look for the SWD pinout of a 10-pin Cortex Debug Connector:

Focusing only on the orange labels, which are associated to SWD, we can start routing our connector in KiCad. The symbol used was Conn_02x05_Odd_Even which matches with the Cortex version. A very good practice is to add a very small resistor between the connector pin and the chip pin. This is done, to limit the short circuit current in the case any of the MCU digital pins is shorted with VCC or GND when doing the connection with the debugger cable. In addition, a low pass filter is used to connect the NRST pin to avoid any kind of parasitic bouncing signal.