STM32F767 Nucleo 板 printf 到控制台
Posted
技术标签:
【中文标题】STM32F767 Nucleo 板 printf 到控制台【英文标题】:STM32F767 Nucleo board printf to console 【发布时间】:2021-04-14 05:08:48 【问题描述】:在过去的几天里,我一直在尝试让 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 */
当我打开终端并连接到设备时,我可以看到消息按预期出现: enter image description here
但是,我无法理解为什么我无法在 stm32cubeIDE 控制台上看到显示的消息。我是否缺少一些额外的配置?
【问题讨论】:
STM32CubeIDE 控制台显示在您的 PC 上本地运行的命令的输出。它并不意味着显示来自 MCU 的串行输出。要么继续使用外部程序,要么搜索并安装 Eclipse 插件(如 TM Terminal)。 【参考方案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;
-
在调试配置中,启用 SWV 跟踪并将内核时钟设置为设备的 SYSCLK。 (见下图)
Debug configuration
-
调试代码并转到 Windows -> 显示视图 -> SWV -> SWV ITM 数据控制台
现在您应该已启用 SWV 数据控制台,请查看下图: SWV ITM Data console
-
打开 SWV ITM Data 控制台设置并确保端口 0 被勾选(见下图):
Enable port 0
5. 运行代码时,请确保启用了启动跟踪: Enable start tracing
-
享受向控制台打印消息的乐趣
YouTube 上的详细指南可以在这里找到: https://www.youtube.com/watch?v=Ti-1X8HfVrc&ab_channel=RADAS
不幸的是,使用这种方法仍然很麻烦。每次调试代码时,都需要开始跟踪。必须有一个简单的方法可以在不使用跟踪的情况下在控制台中显示消息
【讨论】:
以上是关于STM32F767 Nucleo 板 printf 到控制台的主要内容,如果未能解决你的问题,请参考以下文章
如何使用随附的原始 DEMO 代码重新编程 stm32F769 DISCO 板?
STM32f207ZG NUCLEO 板,ld.exe:.RxDescriptSection VMA [2000e000,2000e09f] 部分与 .bss VMA [20000118,200143