Skip to main content
Visitor II
August 26, 2024
Solved

Trouble setting up UART on STM32 using HAL library

  • August 26, 2024
  • 2 replies
  • 2010 views

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 */
    This topic has been closed for replies.
    Best answer by mƎALLEm

    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?

    2 replies

    Technical Moderator
    August 26, 2024

    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?

    SamuriAuthor
    Visitor II
    August 26, 2024

    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.

    Technical Moderator
    August 26, 2024

    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.

    SamuriAuthor
    Visitor II
    August 26, 2024

    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.

    mƎALLEmAnswer
    Technical Moderator
    August 26, 2024

    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?