在嵌入式开发中,调试是必不可少的一步。在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视而不见
代码获取、问题探讨及文章转载可私信。
☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。
🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇