使用STM32CUBEMX生成MDK工程,到printf函数会卡死

使用STM32CUBEMX生成MDK工程,已在魔术棒选项勾选use mircolib,且已定义重定向函数如下,在debug时printf还是会卡住

int fputc(int ch, FILE *f)
{
    
    //FIFO 未达到 1/8 深度
    while((UART5->ISR & USART_ISR_TXFT_Msk) == 0);
    
    UART5->TDR = ch;
    
    return ch;
}

修改默认heap size,建议加大一倍

卡死在哪了

这个while循环的内容确定是对的吗?

可以考虑将这两行调换一下执行顺序试一下,有可能是要先读一下DR寄存器然后在等待

int fputc(int ch, FILE *f)
{
     UART5->TDR = ch;
    //FIFO 未达到 1/8 深度
    while((UART5->ISR & USART_ISR_TXFT_Msk) == 0);

    return ch;
}

波特率、数据位、停止位等参数是否匹配

首先检查下,程序编译是否报了错误。其次,安装以下如图所示,点击魔法棒,取消微库的勾选框:

img


或者参考这个博主的解决方法,需要在你的代码中添加一些代码就是:
STM32中串口使用printf函数时出现程序卡死、运行不了的现象:https://blog.csdn.net/ZIIllIIll/article/details/118150878

STM32CubeMX(6)——Printf导致程序卡死
现成的‘

在STM32CUBEMX中配置好串口的参数,比如波特率、数据位、停止位等。
在STM32CUBEMX中启用串口的全局中断,在NVIC Settings中勾选USARTx global interrupt。
在MDK工程中重写_write函数,将printf的输出重定向到串口发送函数。例如:

#include <errno.h>
#include <sys/unistd.h> // STDOUT_FILENO, STDERR_FILENO

int _write(int file, char *data, int len)
{
  if ((file != STDOUT_FILENO) && (file != STDERR_FILENO))
  {
    errno = EBADF;
    return -1;
  }
  
  // arbitrary timeout 1000
  HAL_StatusTypeDef status = 
      HAL_UART_Transmit(&huart1, (uint8_t*)data, len, 1000);
  
  // return # of bytes written - as best we can tell
  return (status == HAL_OK ? len : 0);
}
```c


```

基于new bing部分指引作答:
在使用STM32CUBEMX生成MDK工程时,遇到printf函数卡死的问题可能是由于以下原因:

1、重定向函数的实现:你已经定义了重定向函数fputc,但是可能存在问题。请确保以下几点:

确保你正确地选择了适用于你的平台的重定向函数。不同的平台可能需要不同的重定向函数实现。
检查你的重定向函数是否正确地将数据发送到UART5的数据寄存器(TDR)。
确保重定向函数的返回值是发送的字符(ch)。
2、UART5配置:确保你已正确地配置了UART5的参数。请注意以下几点:

检查波特率设置是否正确。确保与你的终端设备或调试器的波特率匹配。
确保UART5的发送和接收功能都已启用,并且引脚设置正确。
3、魔术棒选项:你提到已经勾选了"Use MicroLIB"选项。请确保你选择的是与你的平台兼容的MicroLIB版本。

如果你已经检查了以上几点,仍然无法解决问题,可以尝试以下步骤进行故障排除:

1、检查硬件连接:确保你的UART5引脚连接正确,没有接线问题或者短路。

2、调试输出:在重定向函数中添加调试输出,例如使用GPIO口控制LED灯或者通过调试器发送调试信息。这样可以帮助你确定程序的执行是否到达了重定向函数,并检查是否存在其他问题。

3、剥离其他功能:如果可能的话,尝试创建一个简化的项目,仅包含最基本的初始化和重定向函数。这样可以帮助你确定是否有其他功能或配置引起了问题。

以下答案参考newbing,回答由博主波罗歌编写:
根据您提供的信息,您已经在STM32CUBEMX中勾选了MicroLIB库,并在代码中定义了重定向函数fputc。但是在使用printf函数时仍然卡住。

首先,请确保以下几个问题:

  1. 您的代码中是否包含了stdio.h头文件?如果没有包含,需要在代码中添加#include <stdio.h>。
  2. 您的代码中是否初始化了UART5的时钟和GPIO引脚?如果没有进行初始化,需要在代码中添加对应的初始化代码。

如果上述都已经确认无误,请根据以下步骤进一步定位问题:

  1. 使用调试器(如ST-Link)连接到目标设备,并在MDK中打开调试窗口。
  2. 在主函数的开头添加一个简单的printf语句作为测试,例如printf("Hello World\n")。
  3. 在调试窗口中设置断点,使程序在printf语句处停止执行。
  4. 运行程序并观察调试窗口中的变量和寄存器的值。特别关注是否有任何错误或警告信息,以及任何有关UART5的相关寄存器值是否正确。
  5. 如果调试窗口中没有任何异常信息,并且无法从printf中看到输出,则可能是因为printf函数被卡住在发送数据时。您可以尝试以下解决方法:
    • 检查UART5的波特率设置是否与终端设备(例如PC)的波特率一致。
    • 检查UART5的发送缓冲区是否已满。可以通过读取UART5的状态寄存器(例如SR)来判断。如果发送缓冲区已满,需要等待一段时间直到缓冲区有空间。
    • 如果以上方法仍然无法解决问题,可以尝试使用其他的调试技术,如使用JTAG调试或仿真器。

此外,如果您使用的是Cortex-M系列的STM32微控制器,建议使用Semihosting或使用串口打印调试信息,而不是依赖于重定向函数。可以在STM32CubeMX中将调试模式设置为“Serial Wire”(SW)或“Serial Wire +JTAG”(SWD)模式,以便使用J-Link或ST-Link调试器通过UART与PC进行通信并输出调试信息。

希望以上信息对您有所帮助。如果问题仍然存在,请提供更多细节或代码片段,以便进一步帮助您解决问题。
如果我的回答解决了您的问题,请采纳!

根据您提供的代码,重定向函数fputc似乎是正确的。然而,在使用STM32CubeMX生成MDK工程时,printf函数可能会导致卡住的问题。这通常是由于缓冲区溢出或其他串口配置问题引起的。

以下是一些建议来解决这个问题:

确保在CubeMX中正确配置了UART5的波特率、数据位、停止位和校验位等参数。确保它们与调试器/终端程序中的设置一致。

检查UART5的中断使能是否正确设置。你可能需要启用接收中断(RXNE)和发送完成中断(TC)。

尝试使用较小的缓冲区大小。在CubeMX的配置中,你可以找到一个名为"Peripheral Configuration"的选项,它允许你设置缓冲区的大小。尝试将缓冲区大小设置为更小的值,以避免可能的缓冲区溢出问题。

确保你的代码没有导致死循环或其他可能导致程序卡住的问题。

在调用printf之前,尝试将stdout设置为无缓冲模式。你可以在main函数中添加以下代码:

setvbuf(stdout, NULL, _IONBF, 0);

这将禁用printf的缓冲功能,确保每次调用printf时都会立即发送数据。

如果上述方法都没有解决问题,你可能需要更详细地检查串口配置和代码逻辑,以确定导致printf卡住的具体原因。