keil5| printf()函数 | 使用技巧 | STM32|UARST串口输出

在嵌入式开发中,调试是必不可少的一步。在Keil5中,我们可以通过UART串口输出调试信息。STM32使用printf()函数实现UART串口输出,需要进行一些配置和代码编写。本文将详细介绍如何在Keil5中使用printf()函数,并通过UART串口输出调试信息。

一、printf()函数重映射

在Keil5中使用printf()函数时,需要将printf的输出重定向到串口。这通常通过重写fputc()函数来实现。fputc()函数是标准库中用于输出字符的函数,可以将其重定向到串口。

1.1 配置MicroLIB

在Keil5中,可以通过勾选“Target”选项中的“Use MicroLIB”来使用MicroLIB。这样可以减少程序大小,提高运行效率。

1.2 重写fputc()函数

在代码中包含stdio.h头文件,并重写fputc()函数,使其将数据通过UART发送。

#include <stdio.h>

int fputc(int ch, FILE *f) {
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
    return ch;
}

1.3 配置串口

在STM32CubeMX中配置UART串口,设置波特率、数据位、停止位和校验位等参数。

二、sprintf函数格式化输出

sprintf函数可以将格式化的字符输出到一个字符串中。虽然不涉及重定向,但每个串口都可以使用sprintf函数进行格式化打印。

2.1 方法一:直接使用sprintf

char buffer[100];
sprintf(buffer, "Temperature: %d C", 25);
HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);

2.2 方法二:封装printf()函数

为了解决上述方法的缺点,可以对sprintf()函数进行封装,使其更加灵活。

void MyPrintf(const char *format, ...) {
    char buffer[100];
    va_list args;
    va_start(args, format);
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
}

三、中文乱码问题

在使用printf()函数输出中文时,可能会遇到乱码问题。这通常是由于编码格式不一致导致的。

3.1 方法一:使用UTF-8编码

在Keil的项目设置中,添加编译选项--no-multibyte-chars,并确保Keil和串口助手都使用UTF-8编码格式。

printf("你好,世界\n");

3.2 方法二:使用GBK编码

在Keil的项目设置中,不添加任何参数,确保Keil和串口助手都使用GBK编码格式。

四、代码示例

以下是一个完整的示例代码,展示如何在Keil5中使用printf()函数,并通过UART串口输出调试信息。

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

UART_HandleTypeDef huart1;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);

int fputc(int ch, FILE *f) {
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
    return ch;
}

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

    printf("STM32 UART printf test\n");

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

void SystemClock_Config(void) {
    // System Clock Configuration Code
}

static void MX_GPIO_Init(void) {
    // GPIO Initialization Code
}

static void MX_USART1_UART_Init(void) {
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 9600;
    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) {
    // Error Handler Code
}

五、总结

通过上述步骤,可以在Keil5中使用printf()函数,并通过UART串口输出调试信息。这为嵌入式开发提供了一种便捷的调试手段。需要注意的是,在使用printf()函数时,要确保串口已经正确初始化,并且处理好中文编码问题,以避免乱码现象。通过实践,可以更好地掌握Keil5和STM32的调试技巧。

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进

❤欢迎关注我的知乎:对error视而不见

代码获取、问题探讨及文章转载可私信。

☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。

🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇

点击领取更多详细资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI_Guru人工智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值