STM32 NUCLEO-F413Z board serial output

I’m using the subject board and am trying to get serial debugging output working. I create a simple project in the CUBEIDE and serial output works fine. I create a new project and use the CUBEMX program to initialize the chip to defaults and output to the GPDSC toolchain and the serial output is garbage (indicative of an incorrect baud rate). Does anyone have any suggestions (other than to use the CubeIDE, I’m old school and prefer to use command lines to build things)…

Either the clock setup is wrong in the code or you have not set monitor_speed correctly. Hard to say without the code or platformio.ini.

the code and clock are exactly the same in the 2 environments. I’m not smart enough on the hardware side of things to do anything other than take the defaults for the setup.

Here is the code for initializing the UART

void MX_USART3_UART_Init(void)
{

  /* USER CODE BEGIN USART3_Init 0 */

  /* USER CODE END USART3_Init 0 */

  /* USER CODE BEGIN USART3_Init 1 */

  /* USER CODE END USART3_Init 1 */
  huart3.Instance = USART3;
  huart3.Init.BaudRate = 115200;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART3_Init 2 */

  /* USER CODE END USART3_Init 2 */

}

Platformio.ini

[env:nucleo_f413zh]
platform = ststm32
board = nucleo_f413zh
framework =stm32cube


[env:debug]
platform = ststm32
build_type = debug
;debug_tool=stlink
;debug_build_flags= -Og -g2 -ggdb2
;debug_server=/Users/sbade1/.platformio/packages/tool-stm32duino/stlink/st-util
;debug_port=/dev/tty.usbmodem1461403
upload_protocol=stlink
upload_port=/dev/tty.usbmodem1461403

here is the clock config code

/**
  * @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
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 384;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ = 8;
  RCC_OscInitStruct.PLL.PLLR = 2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  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_3) != HAL_OK)
  {
    Error_Handler();
  }
}

I’ve set the monitor speed to 115200, and also tried multiple slower speeds

This is interesting I started with 9600 Baud and increased until it worked. for some reason it’s working with monitor set to 38400. any ideas why this would be off by a multiplier of 3?

This sets up the clock tree to derive the CPU frequency as the external crystal’s frequency divided by 8, times 384, then divided by 4 again.

What does the crystal on the microcontroller read? That silver thing should have a number engraved, e.g. “8.000” (indicating 8.0 MHz). The build system needs to know the crystal frequency (via the HSE_VALUE macro), and these multipliers have to agree with it too.

Reference pic of a (through-hole) crystal

grafik

Okay I’m pretty sure the problem is as follows:

The HAL default configuration file (C:\Users\<user>\.platformio\packages\framework-stm32cubef4\Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_conf.h) has the code

#if !defined  (HSE_VALUE) 
  #define HSE_VALUE              25000000U /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */

thus if the user does not pre-set the HSE_VALUE macro, an external crystal of 25MHz frequency is expected. Compared to 8MHz, that is off by factor 3.125. Hence why you see the UART speed being off by factor 3 (UART transmission additionally has tolerances, so that .125 part doesn’t matter too much).

To fix it, you should add

build_flags = 
   -DHSE_VALUE=8000000U

to the platformio.ini, since when we look at the Nucleo F103ZH board in CubeMX it shows the default clock tree

with a “Input Frequency” set to 8MHz.