2

I want to use a scanf() function in STM32F401RE_NUCLEO with IAR compiler.

This is my overloaded fgetc function.

int fgetc(FILE *f) {
  char ch;
  while (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) == RESET);
  HAL_UART_Receive(&UartHandle, (uint8_t*)&ch, 1, 0xFFFF);
  return ch;
}

And I use scanf in main function like below.

int n;
printf("[DBG] Input: ");
scanf("%d", &n);
printf("[DBG] Output: %d\n", n);

If I type a "123" from terminal, then printed "23".

%d, %u, %f was same.

But, only %c works correctly.

How can I solve this problem?

HoYa
  • 324
  • 3
  • 17

2 Answers2

1

Probably you have the same issue like the guy in the mikrocontroller.net forum.

He needed to implement the functions __write and __read instead of fgetc and fputc.

Prototypes:

size_t __write(int Handle, const unsigned char * buf, size_t count);
size_t __read(int Handle, unsigned char * buf, size_t count);

May be also interesting for you: How to override and redirect library modules.

veeman
  • 780
  • 1
  • 8
  • 17
0

You have to implement __read function instead of fgetc. Remove the implementation of fgetc and use the following code.

Save following code into a file (eg. read.c) and add this file to your IAR project.

#include <LowLevelIOInterface.h>
#include "stm32l0xx_hal.h"

#pragma module_name = "?__read"

extern UART_HandleTypeDef huart2;

int MyLowLevelGetchar()
{
  char ch;
  while (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE) == RESET);
  HAL_UART_Receive(&huart2, (uint8_t*)&ch, 1, 0xFFFF);
  return ch;
}

size_t __read(int handle, unsigned char * buffer, size_t size)
{
  /* Remove the #if #endif pair to enable the implementation */
#if 1  

  int nChars = 0;

  /* This template only reads from "standard in", for all other file
   * handles it returns failure. */
  if (handle != _LLIO_STDIN)
  {
    return _LLIO_ERROR;
  }

  for (/* Empty */; size > 0; --size)
  {
    int c = MyLowLevelGetchar();
    if (c < 0)
      break;

    *buffer++ = c;
    ++nChars;
  }

  return nChars;

#else

  /* Always return error code when implementation is disabled. */
  return _LLIO_ERROR;

#endif
}

You might need to include a different "stm32xxx..." header file based on your target MCU.