On this page
The previous series built the tooling foundation: CMake builds the firmware, OpenOCD flashes the board, and VSCode can debug the running target.
This series uses that foundation to work with actual STM32 peripherals. Before writing GPIO, timer, UART, I2C, or SPI code, it is worth taking a focused tour of the board those examples will use: the STM32 Nucleo L433RC-P.
This is not another toolchain setup article. The goal is to identify the board features that matter when firmware starts touching pins, clocks, buses, buttons, LEDs, and external modules.
What This Article Covers
This article covers:
- The role of the STM32 Nucleo L433RC-P in this series.
- The onboard ST-LINK debug and programming interface.
- Power and reset assumptions.
- The user LED and user button as first GPIO targets.
- Expansion headers and why pin mapping matters.
- How board documentation, the MCU datasheet, and the reference manual fit together.
It does not write the first GPIO driver or blink the LED yet. That comes next. Here, the useful result is knowing what hardware the firmware will interact with and where to verify details before coding.
Board Identity
The board for this series is the STM32 Nucleo L433RC-P.
The target MCU is from the STM32L4 family, and the earlier tooling articles used the STM32L433RCTx memory layout, startup naming, and OpenOCD target family.
That identity matters because STM32 examples are not interchangeable by default. A GPIO example for one STM32 family may use different register names, different alternate-function mappings, or different clock tree details on another family.
For this series, assume:
- STM32 Nucleo L433RC-P board.
- STM32L433RCTx-class target.
- Arm Cortex-M4 core.
- Build, flash, and debug workflow from the CMake/VSCode series.
When using a different Nucleo board, keep the workflow ideas but verify every board-specific pin, peripheral, and OpenOCD target setting.
ST-LINK Is Still Part of the Workflow
The Nucleo board includes onboard ST-LINK hardware. That is the debug and programming interface used by OpenOCD and VSCode.
In practical terms, ST-LINK lets the development machine:
- Flash
firmware.elfor another firmware image. - Reset and halt the target.
- Single-step code.
- Read registers and memory.
- Set breakpoints.
ST-LINK is not the application firmware. It is the bridge between the host tools and the target MCU.
Use a USB cable that carries data, not a charge-only cable. A power-only cable can make the board power LED turn on while OpenOCD and VSCode still fail to connect.
Power and Reset
For the examples in this series, the board is normally powered over USB through the Nucleo's ST-LINK connection.
That is enough for basic examples such as blinking the user LED, reading the user button, UART logging through supported board paths, and driving modest external modules when wired correctly.
Before connecting external hardware, check voltage and current requirements. STM32 GPIO pins are not general-purpose power supplies, and many display modules need power from board supply pins rather than directly from an MCU pin.
The reset button remains useful even with a debugger. If firmware gets stuck, a reset gives you a known starting point. In VSCode, a debug session can also reset and halt the target, which is often more useful than pressing the physical button because the debugger can stop early in startup code.
The User LED
The user LED is the first practical GPIO output target.
It is useful because:
- It is already on the board.
- It does not require external wiring.
- It gives visible feedback.
- It is simple enough to isolate build, flash, clock, and GPIO mistakes.
Do not assume the board label is the same thing as the MCU port and pin name. Before writing code, verify the user LED connection in the Nucleo L433RC-P user manual or schematic.
The next article will use that verified port and pin to configure GPIO output deliberately instead of relying on generated magic.
The User Button
The user button is the first practical GPIO input target.
It is useful because it introduces problems that output-only examples avoid:
- Input mode configuration.
- Pull-up or pull-down behavior.
- Active-high versus active-low logic.
- Contact bounce.
- Polling versus interrupt-based input.
As with the LED, verify the exact MCU port and pin from the board documentation before coding. Also verify whether the button circuit expects an internal pull-up, an internal pull-down, or already has external components on the board.
The button article will keep the first implementation simple and use polling. Debounce and interrupt-driven input can come later once the basic electrical and GPIO behavior is clear.
Headers and Expansion Connectors
The Nucleo board exposes MCU pins through expansion headers.
Two connector families matter most:
- Arduino-style headers for shield-like modules and familiar pin labels.
- Morpho headers for broader access to MCU pins.
The labels printed near headers are convenient, but firmware ultimately needs MCU port and pin names, peripheral instances, and alternate-function selections.
For example, a header pin might be convenient for wiring an I2C display, but the firmware still needs to know:
- Which MCU pin reaches that header.
- Whether that pin supports the needed I2C alternate function.
- Which I2C instance it connects to.
- Whether external pull-up resistors are present or required.
- Whether the module uses compatible voltage levels.
This is why peripheral work starts with board mapping, not only C code.
Peripheral Order for This Series
The series uses a practical order:
- GPIO output with the user LED.
- GPIO input with the user button.
- Clocks, enough to understand peripheral timing.
- Timers for delays and periodic work.
- UART logging for visibility.
- I2C for common sensor and display modules.
- SPI for display and shift-register-style modules.
- Small project organization after several peripherals exist.
That order is deliberate. GPIO gives immediate board interaction. Clocks and timers explain timing. UART improves debugging visibility. I2C and SPI then build on pin mapping, timing, and debugging discipline.
Which Documents Matter
STM32 development often involves several documents, and they answer different questions.
The Nucleo board user manual answers board-level questions:
- Which MCU is installed?
- Which pins connect to the user LED and button?
- How are headers wired?
- How is ST-LINK connected?
- What power options are available?
The board schematic answers circuit-level questions:
- Is a pin pulled up or pulled down?
- Is an LED active high or active low?
- Which connector pin reaches which MCU pin?
- Are there solder bridges or jumpers affecting a signal?
The MCU datasheet answers part-level questions:
- Pin alternate functions.
- Package pinout.
- Electrical limits.
- Memory size and device characteristics.
The reference manual answers peripheral behavior questions:
- GPIO register behavior.
- Clock tree configuration.
- Timer modes.
- UART, I2C, and SPI registers.
- Interrupt and DMA behavior.
Do not expect one document to answer everything. Board work usually requires moving between them.
Debug Before Blaming the Hardware
When a peripheral example does not work, the failure is not always in the wiring.
Before changing hardware, use the debugger from the previous series:
- Confirm the firmware was rebuilt.
- Confirm the debugger is attached to the expected
firmware.elf. - Stop in
mainand verify the code path is executing. - Inspect variables used for configuration.
- Check whether the program reaches the peripheral setup code.
For GPIO examples, debugger visibility will not replace measuring a pin with a meter or logic analyzer, but it quickly separates "the firmware did not run" from "the pin did not behave as expected."
Common Mistakes
The first common mistake is using the wrong board variant. Nucleo board names are similar, but pin mappings and target MCUs can differ.
The second is using a charge-only USB cable. The board may power up while ST-LINK communication fails.
The third is assuming Arduino-style labels are the same as STM32 port and pin names. They are not. Firmware needs the MCU signal mapping.
The fourth is using a peripheral pin without checking alternate functions. Not every pin can be used for every UART, I2C, SPI, or timer channel.
The fifth is connecting external modules without checking voltage and current. Many modules are 3.3 V compatible, but not all are wired or powered the same way.
The sixth is blaming HAL, CMake, or VSCode before proving the basic path: the firmware built, flashed, started, and reached the code being tested.
What This Proves
This article does not prove any peripheral behavior yet.
It establishes the hardware context for the rest of the series. The STM32 Nucleo L433RC-P is not just an abstract STM32 target. It is a board with a debugger, power path, reset button, user LED, user button, headers, connector mappings, and documentation that must be checked when firmware touches real pins.
That context prevents a common embedded mistake: writing code before identifying the signal you are actually controlling.
Next Steps
The next article blinks the user LED on STM32 without magic.
It will take the board context from this article, verify the LED's MCU pin, configure GPIO output, and use the existing build/debug workflow to create the first visible peripheral behavior in the series.