首先,在 main.c 文件中添加如下代码,实现 printf 函数的重定向:

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
  // 阻塞方式打印 -> 串口1
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}
/* USER CODE END 0 */

当然,前提是使用 STM32CubeMX 配置好串口1。然后,在主循环测试打印效果:

此时,使用串口调试助手是无法得到打印的浮点数。网上解决的方案主要有三个:

  • 使用 union 联合 float 和 uint8_t byte[4] ,这样 float 占的内存空间即是 byte[4]的内存空间,即可将浮点数转换为16进制整数,即遵循 IEEE 754 的表示方法,这时只需要在上位机按照 IEEE 754 格式解析该浮点数即可。显然,这种方法适用于设备通信阶段,不利于调试,并且大多数串口调试工具不能按照 IEEE 754 格式将其解析为浮点数;

  • 使用 sprintf 函数将浮点数格式化为字符串,再进行发送,这在 Keil 中似乎可用,但经过测试,本文环境下则不可用;又或者,将小数转换为整数,在接收端又处理成小数,显然,这也不适用 Debug 阶段。

  • 使用CMake时,加入编译参数:-u_printf_float 即可使用 printf 实现串口传输浮点数。具体来说,需要添加如下的编译选项:

从测试结果来看是可行的:

然而,这种方法会增大芯片的Flash开销,建议在 Debug 阶段后删除该编译选项,同时清除调试所需的非必要串口通信代码,以降低芯片的Flash开销。