Skip to main content
Graduate II
June 17, 2025
Solved

Able to use printf on uart3, but not on uart2

  • June 17, 2025
  • 4 replies
  • 563 views

Hello, so I was originally using printf with uart3, and that seemed to work fine. The characters were being printed as expected on a PuTTY terminal that I was using. I was using the following code:

/* USER CODE BEGIN PV */
UART_HandleTypeDef *uartHandlerDebug = &huart3; // UART bank used for communication with computer for debugging
/* USER CODE END PV */

int main(void)
{

 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */
 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */
 setvbuf(stdout, NULL, _IONBF, 0); //! Disables buffering for stdout
 HAL_Delay(1000); // Allow previous code to be erased
 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_DMA_Init();
 MX_USART3_UART_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */
 /*
 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 printf("Hello!\r\n");
 HAL_Delay(1000);
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

/**
 * @brief USART2 Initialization Function
 * None
 * @retval None
 */
static void MX_USART2_UART_Init(void)
{

 /* USER CODE BEGIN USART2_Init 0 */

 /* USER CODE END USART2_Init 0 */

 /* USER CODE BEGIN USART2_Init 1 */

 /* USER CODE END USART2_Init 1 */
 huart2.Instance = USART2;
 huart2.Init.BaudRate = 1000000;
 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;
 huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart2) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USART2_Init 2 */

 /* USER CODE END USART2_Init 2 */
}

/**
 * @brief USART3 Initialization Function
 * None
 * @retval None
 */
static 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 = 1000000; //MODIFY THIS
 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;
 huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart3) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USART3_Init 2 */

 /* USER CODE END USART3_Init 2 */

/* USER CODE BEGIN 4 */
/**
 * @brief Print the characters to UART (printf).
 * @retval int
 */
#ifdef __GNUC__
/* With GCC, small printf (option LD Linker->Libraries->Small printf
 set to 'Yes') calls __io_putchar() */
int __io_putchar(int ch)
#else
int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
{
 /* Place your implementation of fputc here */
 /* e.g. write a character to the UART3 and Loop until the end of transmission */
 HAL_UART_Transmit(uartHandlerDebug, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
 return ch;
}
/* USER CODE END 4 */

}

I have only put the relevant functions in the code snippet above.

 

However, when I switched the value of uartHandlerDebug to huart2, and I rerun the code, nothing is printed on my PuTTY terminal.

This is my pin configuration:

is45_0-1750147553853.png

My UART2_RX pin is PA3, TX pin is PA2

My UART3_RX pin is PD8, TX pin is PD9

 

This is my PuTTY terminal configuration, although I don't think that should be the factor here:

is45_1-1750147674809.png

I will greatly appreciate any help. Thank you!

Edit 1: I am using STM32 NUCLEO-F746ZG. The board is connected to my PC via a simple Micro USB cable.


Edited to apply source code formatting - please see How to insert source code for future reference.

    This topic has been closed for replies.
    Best answer by Andrew Neil

    Welcome to the forum

    Please see How to write your question to maximize your chances to find a solution for best results - in particular, How to insert source code 

     

    You haven't said what board you are using, or how you are connecting the UARTs to the PC (COM13)?

    If you're using an ST board, with built-in VCP (Virtual COM Port), then you will need to make hardware changes for that to use a different UART - see the User Manual and/or Schematics for details.

     


    @is45 wrote:

     uartHandlerDebug


    Note that it's a Handle - not a Handler.

    4 replies

    Super User
    June 17, 2025

    Welcome to the forum

    Please see How to write your question to maximize your chances to find a solution for best results - in particular, How to insert source code 

     

    You haven't said what board you are using, or how you are connecting the UARTs to the PC (COM13)?

    If you're using an ST board, with built-in VCP (Virtual COM Port), then you will need to make hardware changes for that to use a different UART - see the User Manual and/or Schematics for details.

     


    @is45 wrote:

     uartHandlerDebug


    Note that it's a Handle - not a Handler.

    is45Author
    Graduate II
    June 17, 2025

    Hi, sorry for that, I have added the details to my post. I am using STM32 NUCLEO-F746ZG. The board is connected to my PC via a simple Micro USB cable.

     


    @Andrew Neil wrote:

    If you're using an ST board, with built-in VCP (Virtual COM Port), then you will need to make hardware changes for that to use a different UART - see the User Manual and/or Schematics for details.

     

    I am not very sure whether my board has VCP, but based on what I just read online, I think it does, since I don't have any other hardware that is connected between my laptop and the STM32 board.

    So I am assuming there is no way for me to use any uart other than uart3 by changing like code/pin configurations, and I will have to like change some physical connections on the board to do so?

    Thanks!

    Technical Moderator
    June 17, 2025

    If you need to use USART2, you need to connect USART2_Tx and USART2_Rx to respectively to STLINK_Rx and STLINK_Tx  over CN5:

    mALLEm_0-1750149641640.png

    But you need to keep USART3_Tx and USART3_Rx pin not initialized (Hi-Z).

    Explorer
    June 17, 2025

    What board do you talk about ?

    Most probably, the UART3 pins of the MCU are connected to the ST-Link adapter, and printf works via the VCOM interface provided by the debug adapter.

    If you want to use another UART, you need to attach a USB-to-Serial adapter (or something similiar) on your own.

    > However, when I switched the value of uartHandlerDebug to huart2, and I rerun the code, nothing is printed on my PuTTY terminal.

    And checking both endpoints is not a very detailed analysis either. Check the UART.2 Tx pin output on board level with a scope or logic analyser.

    Technical Moderator
    June 17, 2025

    Hello,

    If you are using NUCLEO-F746ZG board, that's normal. USART3 is connected to STLINK-VCP  (Virtual ComPort), while USART2 NOT.

    From the bord schematic:

    mALLEm_0-1750149154395.png

    mALLEm_1-1750149187095.png

     

     

    is45Author
    Graduate II
    June 17, 2025

    Thanks everyone for the help! I have understood the problem now