cancel
Showing results for 
Search instead for 
Did you mean: 

How to get printf() to write to USART2? Using NUCLEO-F401RE and IAR.

MSamp.1
Associate

Hello,

Newbie here, need help getting printf() to write to USART2.

Using IDE : IAR EW for ARM 9.50.1

Board: NUCLEO-F401RE

Example Project:

The example project is called UART_Printf. Here is a screen shot of the directory

MSamp1_0-1712334156214.png

This example code can be found here: https://www.st.com/en/embedded-software/stm32cubef4.html

The example code seems to run fine except the printf() output goes to the Terminal I/O window in the IDE. Not out the UART or Virtual USB com port. 

I want printf() to send data out USART2. And if it did,  think I would also see the data on the Virtual USB Com Port too. In device manager I do get this: 

MSamp1_1-1712334484884.png

So that is a good sign. 

And I do see that USART2 has been configured: 

MSamp1_2-1712334586511.png

But when I run the code, the Data Register on USART2 is never written to. I set a break point on a data write to 0x04000'4404 (the DR register) and it never gets written to. I also put a scope on the USART_TX signal (pin 16, PA2 of the MCU) and it is not active. 

But as I said. Printf() is showing up in the Terminal I/O window.

MSamp1_3-1712334967716.png

So, The question is, How do I get printf() to write data to USART2?

I have tried several solutions but no luck. Looked a several post.

Also when I try to step into the printf() function, the debugger switches to disassembly mode, not source code. Not sure why. Makes it hard to see what is going on.

Thanks in advance! Mark

Here is a copy of the code in main.c


/* Includes ------------------------------------------------------------------*/
#include "main.h"

/** @addtogroup STM32F4xx_HAL_Examples
* @{
*/

/** @addtogroup UART_Printf
* @{
*/

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* UART handler declaration */
UART_HandleTypeDef UartHandle;

/* Private function prototypes -----------------------------------------------*/
#ifdef __GNUC__
/* With GCC, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
static void SystemClock_Config(void);
static void Error_Handler(void);

/* Private functions ---------------------------------------------------------*/

/**
* @brief Main program
* @PAram None
* @retval None
*/
int main(void)
{
/* STM32F4xx HAL library initialization:
- Configure the Flash prefetch, instruction and Data caches
- Configure the Systick to generate an interrupt each 1 msec
- Set NVIC Group Priority to 4
- Global MSP (MCU Support Package) initialization
*/
HAL_Init();

/* Configure the system clock to 84 MHz */
SystemClock_Config();

/*##-1- Configure the UART peripheral ######################################*/
/* Put the USART peripheral in the Asynchronous mode (UART Mode) */
/* UART1 configured as follow:
- Word Length = 8 Bits
- Stop Bit = One Stop bit
- Parity = ODD parity
- BaudRate = 9600 baud
- Hardware flow control disabled (RTS and CTS signals) */
UartHandle.Instance = USARTx;

UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_ODD;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;

if(HAL_UART_Init(&UartHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}

/* USER CODE END 3 */
/* Output a message on Hyperterminal using printf function */
/* Infinite loop */
while (1)
{
printf("\n\r UART Printf Example: retarget the C library printf function to the UART\n\r");
}
}

/**
* @brief Retargets the C library printf function to the USART.
* @PAram None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */

HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 0xFFFF);

return ch;
}

/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (HSI)
* SYSCLK(Hz) = 84000000
* HCLK(Hz) = 84000000
* AHB Prescaler = 1
* APB1 Prescaler = 2
* APB2 Prescaler = 1
* HSI Frequency(Hz) = 16000000
* PLL_M = 16
* PLL_N = 336
* PLL_P = 4
* PLL_Q = 7
* VDD(V) = 3.3
* Main regulator output voltage = Scale2 mode
* Flash Latency(WS) = 2
* @PAram None
* @retval None
*/
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;

/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();

/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

/* Enable HSI Oscillator and activate PLL with HSI as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 0x10;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}

/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | 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_2) != HAL_OK)
{
Error_Handler();
}
}

/**
* @brief This function is executed in case of error occurrence.
* @PAram None
* @retval None
*/
static void Error_Handler(void)
{
/* Turn LED2 on */
BSP_LED_On(LED2);
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 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) */

/* Infinite loop */
while (1)
{
}
}
#endif

/**
* @}
*/

/**
* @}
*/

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 

 

3 REPLIES 3

Please use the </> code pasting tool when in-lining code in posts.

Sorry, not familiar with IAR's methods to semi-host, or redirect STDIO.

KEIL's is to use fputc()

Perhaps look at your project's meta-data / settings with regard to the Terminal IO, and related IAR documentation.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
SofLit
ST Employee

Hello,

From the code snippet you shared, it desn't seem to be the native example provided in this path: Projects\STM32F401RE-Nucleo\Examples\UART\UART_Printf

I can see:

/* USER CODE END 3 */

Which concludes you're using CubeMx and you did some modifications by inspiring from the example.

Start by compiling the native example and program your target board with it to ensure the HW is fine.

What about the pins you have configured for USART2: are they PA2 (Tx) and PA3 (Rx)?

Check your HW:

SofLit_0-1712346964934.png

CN3 jumper should be off.

SB13 should be soldered.

 

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.