How to Program STM32 with STM32CubeIDE – The Complete Guide

TL;DR (Quick Start)
Install STM32CubeIDE (Windows/macOS/Linux).
Create Project: File → New → STM32 Project → pick your MCU or Board (e.g., NUCLEO-L053R8).
Configure Peripherals: in Device Configuration Tool (a.k.a. CubeMX-in-IDE).
Generate Code → open…


This content originally appeared on DEV Community and was authored by Alex Mo


TL;DR (Quick Start)
Install STM32CubeIDE (Windows/macOS/Linux).
Create Project: File → New → STM32 Project → pick your MCU or Board (e.g., NUCLEO-L053R8).
Configure Peripherals: in Device Configuration Tool (a.k.a. CubeMX-in-IDE).
Generate Code → open Core/Src/main.c.
Write Code inside /* USER CODE BEGIN / … / USER CODE END */ blocks.
Build (hammer icon).
Program/Debug (green bug ▶️). Press the board button, watch the LED respond. 🎉


What Is STM32?
STM32 is STMicroelectronics’ family of 32-bit microcontrollers based on ARM Cortex-M cores (M0/M0+, M3, M4, M7, M33…). The range spans ultra-low-power parts to high-performance models with rich peripherals (ADC/DAC, timers, SPI/I²C/UART, USB, CAN, Ethernet, SDMMC, etc.). ST’s MCU Finder helps you filter by power, speed, memory, package, peripherals, and price.

What You Need
1) Documentation (keep it handy)

Datasheet (device features, electricals, pinout)
Reference Manual (peripheral registers & behavior)
Board User Manual (Nucleo/Discovery pin maps, LED/button labels)
You don’t have to memorize it all—just know where things live.

2) Language
C is the right place to start on STM32. (You can mix in C++ later.) Learn the basics of types, pointers, headers, and build systems.

3) Hardware
Nucleo (recommended): On-board ST-LINK debugger/programmer; Arduino headers for shields.
Discovery: Often includes sensors/displays; also has on-board ST-LINK.
BluePill / custom board: Use an external ST-LINK/V2 (or a Nucleo as a programmer). Connect SWDIO, SWCLK, GND, 3V3; set BOOT0=0 for normal boot.

Tip: On Nucleo boards, keep the ST-LINK jumpers in the default “on-board target” position. You can remove them later to use the Nucleo as an external programmer.

4) Software (free)
STM32CubeIDE = Eclipse + CubeMX + GCC + GDB + ST-LINK tools in one install. It handles:
MCU/Board selector
Pin/peripheral configurator
Code generator (HAL/LL)
Compiler, linker
Debugger & programmer

5) Framework Options (how you code)
Bare-metal registers (“pure C”)
Max control & speed; steep learning curve; live in the Reference Manual. Great for experts and ultra-tight targets.

Arduino core for STM32
Easy for small demos; limited board support and quality varies. Not ideal if you plan to move to professional workflows.

Mbed OS
C/C++ with online/offline tooling and drivers. Feels heavier and opinionated; fine if you want its RTOS/driver ecosystem.

LL (Low-Layer) drivers
Thin, close to registers; efficient; more work than HAL.

HAL (Hardware Abstraction Layer) ✅ Recommended for beginners
High-level, readable APIs; fast to prototype; plenty of examples.
You can mix HAL and LL per peripheral in Cube settings.

The STM32CubeIDE Workflow (End-to-End)
Step 0 — Install STM32CubeIDE

Download from ST’s website, install with defaults. On Windows, the installer can also add ST-LINK drivers. On macOS/Linux, you’re generally good out of the box.

Step 1 — Create a New Project
File → New → STM32 Project
Board Selector: search your exact Nucleo/Discovery (e.g., NUCLEO-L053R8) and select it.
Peripherals like LED and USER button are pre-mapped for you.
Name your project (e.g., hello_world) → Finish.
When asked, accept Initialize all peripherals with default.

Step 2 — Configure Peripherals (Device Configuration Tool)

You’re now in the integrated CubeMX view:
Pinout & Configuration: Enable what you need (GPIO, UART, I²C, SPI, timers…). Cube assigns pins automatically; you can remap if needed.
Clock Configuration: Adjust PLL and bus clocks if you’re using an external crystal or need specific peripheral clocks.

Project Manager → Code Generator:
✅ Check “Generate peripheral initialization as a pair of .c/.h per peripheral” for a cleaner structure.

Example: Enable SPI1 as Full Duplex Master; Cube maps SCK/MISO/MOSI and creates spi.c/h with init code.

Step 3 — Generate the Project
Project → Generate Code. This writes the Core/ and Drivers/ scaffolding and peripheral init functions.

Step 4 — Understand the Files
Typical structure:

Core/
  Inc/      // headers (main.h, gpio.h, ... )
  Src/      // sources (main.c, gpio.c, ... )
Drivers/
  STM32xx_HAL_Driver/ // HAL sources
  CMSIS/               // Cortex & device headers

Your entry point is Core/Src/main.c.

Only write inside the marked regions:

/* USER CODE BEGIN Includes */
...
/* USER CODE END Includes */

Anything outside can be overwritten the next time you regenerate code.

Step 5 — “Hello World”: Button → LED

Goal: When the button is pressed, turn the LED on; otherwise off.
Open main.c and in the main loop add:

/* USER CODE BEGIN WHILE */
while (1)
{
  if (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin))
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
  else
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
}
/* USER CODE END WHILE */

Notes:
B1_* and LD2_* macros are board-specific and come from the Board setup. You don’t need to hard-code ports/pins.
To toggle instead, you can use:
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
HAL_Delay(200); // 200 ms

Step 6 — Build & Flash
Build: click the hammer (or Project → Build All). Zero errors? Great.
Program/Debug: click the bug. STM32CubeIDE will:
Detect ST-LINK, suggest a debug config, and offer firmware update if needed.
Load your .elf to the target and start a debug session.
You can now set breakpoints, step, watch variables, and hit Resume to run.
Going Deeper (Quick Wins)

A) Debounce the Button (simple)

uint32_t t0 = 0;
while (1) {
  GPIO_PinState s = HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin);
  if (s == GPIO_PIN_SET && (HAL_GetTick() - t0) > 30) {
    HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
    t0 = HAL_GetTick();
  }
}

B) Use External Interrupt (EXTI)
In Pinout, set the button pin to GPIO_EXTI.
Cube generates HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin). In it:

if (GPIO_Pin == B1_Pin) {
  HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
}

NVIC tab: ensure EXTI interrupt is enabled.

C) Print Debug Text
Easiest: enable USART in Cube; in retarget.c or syscalls.c map printf to UART.
Alternative: SWV ITM (single-wire viewer) for printf-like tracing without using a UART (supported on many cores).

D) Mix HAL & LL
In Project Manager → Advanced Settings, set specific peripherals to LL for tighter control/latency, while keeping others on HAL for convenience.
Common Pitfalls & Fixes
“Target not found” / connect fails
Use a good USB cable.
Board powered (USB) and ST-LINK jumpers in default position.
Try a slower SWD frequency in the debug config.
On custom boards: verify SWDIO/SWCLK/GND/3V3 and NRST.
My code disappeared after regenerating
You edited outside /* USER CODE */ blocks. Move your code into the blocks and regenerate.

LED/Buttons don’t match pins
Check your board’s User Manual and the Pinout view. Board names (LD2, B1) map correctly when you picked the right Board in the selector.
HAL_Delay blocks everything
Use timers or interrupts for accurate, non-blocking tasks.
Adapting to a BluePill or Custom Board
In New Project, choose the exact MCU (e.g., STM32F103C8Tx) instead of a Board.
Manually enable GPIO, clocks, and any peripherals you need.

Program via external ST-LINK/V2 (SWDIO, SWCLK, GND, 3V3).

If you used an external crystal, configure it in Clock Configuration.

On first connect, do a Full Chip Erase from the debugger if needed.

A Clean Project Template You Can Reuse

Core/Inc/app.h, Core/Src/app.c for your application logic.

Leave main.c minimal (init + scheduler loop).

One module per peripheral/feature (e.g., led.c, buttons.c, uart.c).

Keep code inside USER CODE blocks; add your own blocks within your modules for consistency.

FAQ
Q: HAL vs. LL vs. Registers—what should I pick?
A: Start with HAL. Move hot paths or special cases to LL, and only drop to registers when you truly need it.

Q: Can I reuse my code across STM32 families?
A: Yes—HAL helps a lot. Pin names/peripheral instances may change; keep hardware-dependent bits isolated.

Q: Do I need an RTOS?
A: Not for simple apps. For multiple time-sensitive tasks, consider FreeRTOS (Cube can add it for you).

Next Steps (Mini Roadmap)

UART: send/receive text and logs.

I²C/SPI: talk to sensors and displays.

Timers/PWM: measure signals, drive motors/LEDs.

ADC/DAC: read analog sensors, generate waveforms.

FreeRTOS: structure complex apps with tasks, queues, timers.

Bootloaders & OTA: production-grade updates.

Low-Power modes: for battery devices (STOP/STANDBY, RTC wakeups).

Sample “Hello Button–LED” (Complete Minimal Main Loop)

Where to paste: Core/Src/main.c inside the /* USER CODE BEGIN WHILE */ loop.

/* USER CODE BEGIN WHILE */
while (1)
{
  if (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == GPIO_PIN_SET) {
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
  } else {
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
  }
}
/* USER CODE END WHILE */


This content originally appeared on DEV Community and was authored by Alex Mo


Print Share Comment Cite Upload Translate Updates
APA

Alex Mo | Sciencx (2025-09-18T06:59:12+00:00) How to Program STM32 with STM32CubeIDE – The Complete Guide. Retrieved from https://www.scien.cx/2025/09/18/how-to-program-stm32-with-stm32cubeide-the-complete-guide/

MLA
" » How to Program STM32 with STM32CubeIDE – The Complete Guide." Alex Mo | Sciencx - Thursday September 18, 2025, https://www.scien.cx/2025/09/18/how-to-program-stm32-with-stm32cubeide-the-complete-guide/
HARVARD
Alex Mo | Sciencx Thursday September 18, 2025 » How to Program STM32 with STM32CubeIDE – The Complete Guide., viewed ,<https://www.scien.cx/2025/09/18/how-to-program-stm32-with-stm32cubeide-the-complete-guide/>
VANCOUVER
Alex Mo | Sciencx - » How to Program STM32 with STM32CubeIDE – The Complete Guide. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/09/18/how-to-program-stm32-with-stm32cubeide-the-complete-guide/
CHICAGO
" » How to Program STM32 with STM32CubeIDE – The Complete Guide." Alex Mo | Sciencx - Accessed . https://www.scien.cx/2025/09/18/how-to-program-stm32-with-stm32cubeide-the-complete-guide/
IEEE
" » How to Program STM32 with STM32CubeIDE – The Complete Guide." Alex Mo | Sciencx [Online]. Available: https://www.scien.cx/2025/09/18/how-to-program-stm32-with-stm32cubeide-the-complete-guide/. [Accessed: ]
rf:citation
» How to Program STM32 with STM32CubeIDE – The Complete Guide | Alex Mo | Sciencx | https://www.scien.cx/2025/09/18/how-to-program-stm32-with-stm32cubeide-the-complete-guide/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.