0

在过去的几天里,我一直试图让 printf 工作以将调试消息打印到 STM32CubeIDE 控制台。然而,没有运气。我经历了许多论坛主题和讨论,但似乎都没有完全解决这个众所周知的奇怪问题。

我刚刚使用 STM32CubeMX 生成了一个全新的项目,并为 Nucleo 板使用了默认配置。我只是使用内置 ST-link 的 USB 电缆对设备进行编程。

到目前为止,我被建议做的是添加几行代码,这些代码显然应该已经解决了这个问题,但它确实做到了:

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif


PUTCHAR_PROTOTYPE
{
  HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xFFFF);

  return ch;
}

我还包括:

#include "stdio.h"

实际代码:

int main(void)
{
  /* USER CODE BEGIN 1 */
    uint8_t uart3_data[20] = "hello from uart3";
    uint8_t uart1_data[20] = "hello from uart1";
  /* 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 */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART3_UART_Init();
  MX_USART1_UART_Init();
  MX_TIM10_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim10);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      //Toggle_leds(GPIOB,GPIO_PIN_0,100);

      HAL_Delay(1000);
      printf("UART Printf Example: retarget the C library printf function to the UART \n\r");
      printf("** Test finished successfully. ** \n\r");
      HAL_UART_Transmit(&huart3,uart3_data, sizeof(uart3_data), 50); // just to see what happens

      //HAL_UART_Transmit(&huart1,uart1_data, sizeof(uart1_data), 50); // just to see what happens


  }
  /* USER CODE END 3 */
}

当我打开终端并连接到设备时,我可以看到消息按预期出现: 在此处输入图像描述

但是,我无法理解为什么我无法在 stm32cubeIDE 控制台上看到显示的消息。我错过了一些额外的配置吗?

4

1 回答 1

0

我已经设法让它工作了。那些有同样问题的人,只需按照以下简单步骤操作:

  1. 向 syscalls.c 甚至 main.c 添加自定义 _write 函数:
int _write(int file, char *ptr, int len)
{
  /* Implement your write code here, this is used by puts and printf for example */
  int i=0;
  for(i=0 ; i<len ; i++)
    ITM_SendChar((*ptr++));
  return len;
}
  1. 在调试配置中,启用 SWV 跟踪并将内核时钟设置为设备的 SYSCLK。(见下图)

调试配置

  1. 调试您的代码并转到 Windows -> 显示视图 -> SWV -> SWV ITM 数据控制台

现在您应该已经启用了 SWV 数据控制台,请查看下图: SWV ITM 数据控制台

  1. 打开 SWV ITM Data 控制台设置并确保端口 0 被勾选(见下图): 启用端口 0

5.运行代码时,确保启动跟踪已启用: 启用启动跟踪

  1. 玩得开心将消息打印到控制台

可以在此处找到有关 youtube 的详细指南: https ://www.youtube.com/watch?v=Ti-1X8HfVrc&ab_channel=RADAS

不幸的是,使用这种方法仍然很麻烦。每次调试代码时,都需要开始跟踪。必须有一个简单的方法来在控制台中显示消息而不使用跟踪

于 2021-01-11T05:56:31.167 回答