cancel
Showing results for 
Search instead for 
Did you mean: 

Trouble setting up UART on STM32 using HAL library

Samuri
Visitor

Hello.

I am trying to setup UART on my STM32 using the HAL library and without using the .ioc file for auto-configuration.

I first had a test project using the .ioc file to help me setup UART and was able to transmit data. However, when I do it myself and use a logic analyzer to observe TX and RX, I see that no data is being sent.

Below is the code for my STM32L476RG. What am I missing?

Thanks.

#include "main.h"
void SystemClock_Config(void);
static void MX_GPIO_Init();
static void MX_USART1_UART_Init();
UART_HandleTypeDef huart1;
int main(void)
{
  HAL_Init();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  SystemClock_Config();
  uint8_t tx_buff[5] = {1,2,3,4,5};
  while (1)
  {
  HAL_UART_Transmit(&huart1, tx_buff, 5, 100);
  HAL_Delay(1000);
  }
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  {
    Error_Handler();
  }

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = 0;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_GPIO_Init(void){
GPIO_InitTypeDef GPIO_InitStruct = {0};

__HAL_RCC_GPIOA_CLK_ENABLE();
/*GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
*/
}

static void MX_USART1_UART_Init(void){
/* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

}
void Error_Handler(void)
{
  __disable_irq();
  while (1)
  {
  }
}

#ifdef  USE_FULL_ASSERT
/**
  * @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 CODE BEGIN 6 */
  /* 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 */
1 ACCEPTED SOLUTION

Accepted Solutions

HAL_Init() needs to be called first, then SystemClock_Config() ...

Compare what was generated by CubeMx and what you written in your own code. Are you sure you have the same UART config? GPIO configs?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

View solution in original post

6 REPLIES 6
SofLit
ST Employee

I first had a test project using the .ioc file to help me setup UART and was able to transmit data. However, when I do it myself and use a logic analyzer to observe TX and RX, I see that no data is being sent. 


Hello @Samuri and welcome to the community.

Did you copy the same code of the CubeMx generated code in your own created project?

In that case are you sure you copied the GPIO configuration from the xxx_mcp.c file?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
SofLit
ST Employee

Hello,

Just noticed that you called System clock config after the UART config, why?

  MX_USART1_UART_Init();
  SystemClock_Config();

You need to configure the RCC before the UART as the latter is using that clock value to configure the baudrate. In your case the baudrate will be wrong.

So swap the positions of the calls.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Hello.

This is the order I currently have:

SystemClock_Config();
  HAL_Init();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();

However, I  am still unable to send data.

HAL_Init() needs to be called first, then SystemClock_Config() ...

Compare what was generated by CubeMx and what you written in your own code. Are you sure you have the same UART config? GPIO configs?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Ah, I did not know I was supposed to edit xxx_mcp.c to use UART. I copied the code in that file from my old project into my new one.

Yes, this was the issue. Sorry for not reading what was generated by CubeMx carefully.

Thank you for your patience.