打印
[应用相关]

STM32调试手段:重定向printf串口

[复制链接]
26|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Jiangxiaopi|  楼主 | 2025-2-8 17:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一、引言
在STM32的开发过程中,调试是必不可少的环节。而在众多调试手段中,使用printf函数通过串口输出调试信息是一种简单且有效的方法。printf函数是C语言标准库中用于格式化输出的函数,在PC端编程时非常常用。但在STM32这类嵌入式系统中,默认情况下printf函数并不能直接使用,需要进行重定向,使其通过串口将调试信息发送出去。本文将详细介绍如何在STM32中重定向printf函数到串口。

二、原理分析
printf函数在C语言标准库中是基于fputc函数实现的。fputc函数用于将一个字符输出到指定的文件流中。在嵌入式系统中,我们可以通过重写fputc函数,将字符输出到串口,从而实现printf函数的重定向。

三、实现步骤
1. 串口初始化
首先,我们需要对串口进行初始化配置,设置波特率、数据位、停止位等参数。以下是使用STM32 HAL库进行串口初始化的示例代码:

#include "stm32f4xx_hal.h"

UART_HandleTypeDef huart1;

void MX_USART1_UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
        Error_Handler();
    }
}

void Error_Handler(void)
{
    while(1)
    {
    }
}



2. 重写fputc函数
接下来,我们需要重写fputc函数,将字符通过串口发送出去。代码如下:

#include <stdio.h>

#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(&huart1, (uint8_t *)&ch, 1, 100);
    return ch;
}


在上述代码中,我们根据不同的编译器定义了不同的PUTCHAR_PROTOTYPE。然后在函数内部,使用HAL_UART_Transmit函数将字符通过串口发送出去。

3. 主函数调用
最后,在主函数中初始化串口,并调用printf函数进行测试。示例代码如下:

int main(void)
{
    HAL_Init();
    MX_USART1_UART_Init();

    while (1)
    {
        printf("Hello, STM32!\r\n");
        HAL_Delay(1000);
    }
}


在主函数中,我们首先调用HAL_Init函数进行HAL库的初始化,然后调用MX_USART1_UART_Init函数进行串口初始化。在循环中,使用printf函数输出调试信息,并通过HAL_Delay函数延时1秒。

四、注意事项
1. 包含必要的头文件
在使用printf函数时,需要包含<stdio.h>头文件。同时,在使用HAL库的串口函数时,需要包含相应的HAL库头文件。

2. 编译器选项
有些编译器需要进行一些额外的配置才能正常使用printf函数。例如,在Keil MDK中,需要在工程选项的“Target”选项卡中勾选“Use MicroLIB”,以使用微库。

3. 缓冲区和超时时间
在HAL_UART_Transmit函数中,需要设置合适的超时时间。如果超时时间设置过短,可能会导致数据发送不完整。同时,如果需要发送大量数据,可能需要考虑使用缓冲区来提高发送效率。

五、总结
通过重定向printf函数到串口,我们可以方便地在STM32开发中输出调试信息,提高开发效率。本文详细介绍了重定向的原理、实现步骤和注意事项,并给出了示例代码。希望读者通过本文的学习,能够掌握这一重要的调试手段。

以下是完整的代码示例:

#include "stm32f4xx_hal.h"
#include <stdio.h>

UART_HandleTypeDef huart1;

void MX_USART1_UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
        Error_Handler();
    }
}

void Error_Handler(void)
{
    while(1)
    {
    }
}

#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(&huart1, (uint8_t *)&ch, 1, 100);
    return ch;
}

int main(void)
{
    HAL_Init();
    MX_USART1_UART_Init();

    while (1)
    {
        printf("Hello, STM32!\r\n");
        HAL_Delay(1000);
    }
}


通过以上代码和步骤,你就可以在STM32中使用printf函数通过串口输出调试信息了。在实际开发中,可以根据需要输出各种变量的值,帮助你快速定位和解决问题。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/duierrorshuobu/article/details/145423108

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

53

帖子

0

粉丝