STM32CubeMX
This page: the short, concrete workflow for using STM32CubeMX to configure an STM32 project and generate init code without accidentally nuking your work.
Download: https://www.st.com/en/development-tools/stm32cubemx.html
1) Install & open a project
- Install STM32CubeMX from the download page above.
- Open an existing project by opening the
.iocfile (this is the configuration source of truth). - If you are starting new: create a new project and pick the correct MCU/board (ask if unsure).
2) Configure pins & peripherals
- In Pinout & Configuration: enable the peripherals you need (UART/SPI/I2C/CAN/Timers/ADC/etc.).
- Assign pins and resolve conflicts (CubeMX will warn you).
- Configure DMA + NVIC if needed (especially for high-rate IO or RTOS systems).
2b) Sensor configuration (required)
Do not leave sensors as “just code”. Their hardware configuration must be defined in CubeMX.
For each sensor, document and configure the following:
Interface type:ADC→ for analog sensorsI2C→ for digital sensors (e.g. IMUs, temp sensors)SPI→ for high-speed sensorsUART→ for GPS / external modules
Pin configuration:Assign correct pins inPinout viewLabel pins clearly (e.g.IMU_SCL,PRESSURE_CS)
Peripheral settings:I2C: set clock speed (e.g.100kHzor400kHz)SPI: configure mode (CPOL/CPHA), data size, baud prescalerADC: resolution, sampling time, channel selection
DMA (if applicable):Enable DMA for continuous or high-frequency sensorsLink DMA to the correct peripheral stream
Interrupts (NVIC):Enable interrupts if the sensor uses them (e.g. data ready pins)Set priority correctly (important in RTOS setups)
Example setups:
I2C IMU:EnableI2C1, assignSCL/SDA, set speed to400kHz, enable interrupt if using DRDY pin.Analog pressure sensor:EnableADC1, assign channel pin, configure sampling time, optionally enable DMA.SPI encoder:EnableSPI2, configure mode, assignMISO/MOSI/SCK/CS, ensure correct clock polarity.
Important:If it is not configured in CubeMX, it does not exist. Your driver code depends entirely on this configuration being correct.
3) Set up the clocks
- Go to Clock Configuration and set your clock source (HSI/HSE) and PLL to the target system frequency.
- Verify peripheral clocks (UART baud rates and timer frequencies depend on this).
- If USB is used, make sure USB clock requirements are satisfied (CubeMX will usually flag invalid setups).
4) Code generation rules
Do not write custom code in CubeMX-generated files.
CubeMX will overwrite generated files during regeneration. Any custom code placed there will be lost, even if it appears to work temporarily.
Rule:
- Generated code is read-only.
- Your code lives outside of it.
What to do instead:
- Put all application logic in your own source files (
src/, modules, drivers, etc.). - Only use generated code as initialization and hardware configuration.
- Call your own code from the appropriate entry points (e.g. after init in
main()).
Bottom line:
If your code depends on surviving a “Generate Code” click, it’s in the wrong place.
5) Code generation
To generate the code that can adhere to the before mentioned rules, you have to set some settings.
No main:
You should only generate a main function to check what is in there and use it as an example, but when you want to build, you can not have a main function in your auto-generated code. It will conflict with your own main function. You can turn the generations of a main off in Project Manager -> Project.
Generated file structure:
CubeMX can generate the code as pairs of .c and .h files. That is useful, because it is easy to get necessary functions from those files and use it in your own code. You can set this generation feature in Project Manager -> Code Generator
Post code generation:
You should run the post code generation script after running the code. More information in Post-Generation Scripts.
Makefile Toolchain:
The toolchain you should use is Makefile. You should not use another toolchain, because the post code generation script uses information from the makefile. You can set the toolchain in Project Manager -> Project.
6) Generate code, then build & verify
- Open Project Manager and confirm the project type/toolchain and output path are correct.
- Click Generate Code.
- Immediately review changes (e.g.
git diff). If CubeMX changed a lot more than expected, stop and investigate before committing. - Build the firmware and run a basic smoke test (UART prints, LED blink, peripheral init success, etc.).
```