直接贴代码,放在main.c,头文件包含#include <stdio.h>
/* USER CODE BEGIN PTD */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
if (ch == '\n') {
uint8_t cr = '\r';
HAL_UART_Transmit(&huart1, &cr, 1, HAL_MAX_DELAY);
}
HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);
return ch;
}
/* USER CODE END PTD */
我在实现printf重定向到串口时,按照其它博主的添加重定向语句,发现实际运行过程中光标总是移动到下一行的与上一行对齐的位置。
原因:
打印问题通常是因为 \n 换行符在一些终端中仅会将光标移动到下一行的开始,而不会将光标移动到当前行的开头。所以当你连续打印时,每个 printf(“test\n”); 之间没有额外的控制字符,导致光标只向下移动了一行,而没有回到行首,从而导致打印结果逐渐向右偏移。
为了完美解决其它打印问题,还可以自己创建自己的printf函数。
#include <stdarg.h>
#define BUFFER_SIZE 256 // 根据需要调整缓冲区大小
// 自定义的 printf 函数包装
int my_printf(const char *fmt, ...)
{
va_list args;
int length;
char log_buf[BUFFER_SIZE];
char output_buf[BUFFER_SIZE * 2]; // 用于存储处理后的输出
int output_len = 0;
va_start(args, fmt);
// 使用 vsnprintf 格式化字符串
length = vsnprintf(log_buf, sizeof(log_buf) - 1, fmt, args);
va_end(args);
// 确保 length 不超过缓冲区大小
if (length < 0) {
// 格式化失败的处理(可选)
length = 0;
} else if (length > sizeof(log_buf) - 1) {
// 如果长度超过缓冲区大小,调整长度
length = sizeof(log_buf) - 1;
}
// 处理 \n 替换为 \r\n
for (int i = 0; i < length; ++i) {
if (log_buf[i] == '\n') {
// 替换为 \r\n
if (output_len < sizeof(output_buf) - 2) {
output_buf[output_len++] = '\r';
output_buf[output_len++] = '\n';
}
} else {
output_buf[output_len++] = log_buf[i];
}
}
// 发送处理后的缓冲区内容到串口
if (output_len > 0) {
HAL_UART_Transmit(&huart1, (uint8_t*)output_buf, output_len, HAL_MAX_DELAY);
}
return length;
}