2

我想在带有 IAR 编译器的 STM32F401RE_NUCLEO 中使用 scanf() 函数。

这是我重载的 fgetc 函数。

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;
}

我在 main 函数中使用 scanf ,如下所示。

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

如果我从终端输入“123”,则打印“23”。

%d, %u, %f 相同。

但是,只有 %c 可以正常工作。

我怎么解决这个问题?

4

2 回答 2

1

可能您和mikrocontroller.net论坛中的那个人有同样的问题。

他需要实现函数__write__read而不是fgetcfputc

原型:

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

对您来说可能也很有趣:如何覆盖和重定向库模块

于 2017-05-26T07:44:26.910 回答
0

您必须实现 __read 函数而不是 fgetc。删除 fgetc 的实现并使用以下代码。

将以下代码保存到文件中(例如 read.c)并将此文件添加到您的 IAR 项目中。

#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
}

您可能需要根据您的目标 MCU 包含不同的“stm32xxx...”头文件。

于 2019-11-15T04:10:24.627 回答