Sometimes implementation of UART communication is asymmetric. In general, Rx tasks are time critical and total size of the data is unknown, thus it is best to handle the task in an interrupt service routine where individual incoming bytes are checked without delay. While Tx tasks can be implemented rather relaxed manner. For example, you can use a blocking call inside the main loop. In this sense, UART HAL functions provided by STM32Cube framework is useful for Tx but not very much so for Rx task. Thus you may have to write your own UART interrupt handler using LL drivers while still using HAL UART Tx functions in Tx task. Use STM32Cube to generate all the chores of setting the UART module except the interrupt part. LL interrupt is activated after the UART port is initialized using LL functions: Source file 414 void SerialComm_Init () 415 { 416 LL_USART_EnableIT_RXNE ( huart1 . Instance ); 417 } Then write the interrupt handler to call Rx routine: ...