How to create stm32 project in stm32cubeide with example code

In this tutorial, we will show how to create an stm32 microcontroller project in stm32cubeide. We also write an example code for STM32 Nucleo Board by using the stm32 Hardware Abstraction Layer (HAL) API library. So, let’s get started.

Our other STM32 related tutorials are:

Component List for the Project

Component NameQuantityPurchase Link
STM32 NUCLEO Development Board1Amazon
Jumper wire pack1Amazon
USB Mini-B cable1Amazon

Affiliate Disclosure: When you click on links to make a purchase, this can result in this website earning a commission. Affiliate programs and affiliations include, but are not limited to

Stm32CubeIDE Installation

STMicroelectronics has its own development environment (IDE) for the ARM Cortex M0/M3/M4 series of microcontrollers called Stm32CubeIDE. You can download the IDE from their website and install it in your windows, MAC, or Linux machine.

STM32Cube IDE download

Project creation in Stm32Cube IDE

Step 1: Open your STM32CubeIDE then go to File > New > STM32 project

how to creat stm32cubeide project

Step 2: Then click on Board Selector tab and search your selected development board or Microcontroller in the search bar. In our case, we select NUCLEO-F446RE development board and click Next.

STM32Cube IDE Board select

Step 3: Write the name of the project in Project Name field also Select your project location (workspace) and click Finish button. In our case, we select the default location.

Screenshot 3 1

Step 4: If you want to view or edit your configuration settings double click to your project.ioc file and open the Device Configuration Tool of STM32CubeIDE. Change the configuration settings as your project needs. By default STM32Cube Ide add some default configuration settings in this tool like RCC Clock settings and UART peripheral configurations, if you select any STM32 development board for your project.


Step 5: If you want to change the clock speed of your STM32 Microcontroller, click on Clock Configuration tab and select the clock source HSI (High Speed Internal) or HSE (High Speed External). Our STM32F446RE MCU has 16 MHz Internal clock (HSI) also, the NUCLEO-F446RE Development has 8 MHz external oscillator as clock source.

You can stretch the clock capabilities of STM32F446RE Microcontroller up to 180 MHz by using PLL (PLL is a clock generation engine in the Microcontroller which is used to generate the clock speed and this is much higher than the internal Clock HSI or External Clock HSE).

We will use 8 MHz external clock because it gives more accurate clock pulses than Internal Clock (SHI) also, enable the PLL engine to configure the clock to 180 MHz.

STM32 Clock Configuration settings

Step 6: After finish all the configurations, click on File > Save and Generate the code.

Step 7: After complete the code writing first build the project by clicking the build tool. If the project in successfully build then connect your STM32 microcontroller to your computer and click the RUN tool to download the project in your stm32 microcontroller.

stm32cubeide build and run

Example Code

This is the example code which we write for demonstration purpose. The code is just ON and OFF the user led of the NUCLEO board after 1 second and repeat the process in a while loop.

main.c file

#include "main.h"

UART_HandleTypeDef huart2;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);

int main(void)

  /* Configure the system clock */

  /* Initialize all configured peripherals */

  while (1)
	  HAL_Delay(1000); //1 second delay
	  HAL_Delay(1000); //1 second delay

  * @brief System Clock Configuration
  * @retval None
void SystemClock_Config(void)
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLM = 16;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

  /** Initializes the CPU, AHB and APB buses clocks
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)

  * @brief USART2 Initialization Function
  * @param None
  * @retval None
static void MX_USART2_UART_Init(void)
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)


  * @brief GPIO Initialization Function
  * @param None
  * @retval None
static void MX_GPIO_Init(void)
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */

  /*Configure GPIO pin Output Level */

  /*Configure GPIO pin : B1_Pin */
  GPIO_InitStruct.Pin = B1_Pin;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : LD2_Pin */
  GPIO_InitStruct.Pin = LD2_Pin;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);


  * @brief  This function is executed in case of error occurrence.
  * @retval None
void Error_Handler(void)
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  while (1)
  /* USER CODE END Error_Handler_Debug */

  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
void assert_failed(uint8_t *file, uint32_t line)
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
#endif /* USE_FULL_ASSERT */

Mahamudul Hasan

I hold a B.Sc degree in Electrical & Electronic Engineering from Daffodil International University, Bangladesh. I am a Printed Circuit Board (PCB) designer and Microcontroller programmer with an avid interest in Embedded System Design and IoT. As an Engineer, I love taking challenges and love being part of the solution. My Linkedin Profile Link:

Recent Posts