stm32 printf 重定向
https://www.digikey.cn/zh/forum/t/topic/2855
#define uart_debug huart2
void Usart_SendString(uint8_t *str) {
unsigned int k = 0;
if (str == NULL)
return; // 增加空指针判断,避免崩溃
// 修复原逻辑:先发送当前字符,再判断下一个字符,原逻辑会漏发最后一个字符
do {
HAL_UART_Transmit(&uart_debug, (uint8_t *)(str + k), 1, 1000);
k++;
} while (*(str + k - 1) != '\0'); // 修正终止条件:判断已发送的字符是否为'\0'
}
/* 仅保留GCC适配代码,删除其他编译器分支
* @brief 重定向fputc,支持printf输出到串口(GCC)
* @param ch: 要输出的字符
* @param f: 文件指针(GCC下忽略)
* @retval 输出的字符
*/
int fputc(int ch, FILE *f) {
HAL_UART_Transmit(&uart_debug, (uint8_t *)&ch, 1, 1000);
return (ch);
}
/**
* @brief 重定向fgetc,支持scanf从串口输入(GCC)
* @param f: 文件指针(GCC下忽略)
* @retval 读取的字符
*/
int fgetc(FILE *f) {
int ch = 0;
HAL_UART_Receive(&uart_debug, (uint8_t *)&ch, 1, 0xFFFF); // 阻塞等待接收
return (ch);
}
/**
* @brief GCC底层字符输出函数,适配printf
* @param ch: 要输出的字符
* @retval 输出的字符
*/
int __io_putchar(int ch) {
// 处理换行符:将'\n'转为'\r\n',避免printf换行错位
if (ch == '\n') {
HAL_UART_Transmit(&uart_debug, (uint8_t *)"\r", 1, 1000);
}
HAL_UART_Transmit(&uart_debug, (uint8_t *)&ch, 1, 1000);
return ch;
}
/**
* @brief GCC底层写函数,适配printf/puts等输出函数
* @param file: 文件描述符(串口固定为1)
* @param ptr: 要输出的字符数组指针
* @param len: 要输出的长度
* @retval 实际输出的长度
*/
int _write(int file, char *ptr, int len) {
int DataIdx;
if (ptr == NULL || len <= 0)
return 0; // 增加异常判断
for (DataIdx = 0; DataIdx < len; DataIdx++) {
__io_putchar(*ptr++);
}
return len;
}
/**
* @brief 可选:重定向putchar,直接调用putchar也能输出(GCC)
* @param ch: 要输出的字符
* @retval 输出的字符
*/
int putchar(int ch) {
return __io_putchar(ch); // 复用__io_putchar,避免重复代码
}
keil 下面
int fputc(int ch, FILE *f)
{
// 1. 等待串口发送完成(避免数据覆盖)
while(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE) == RESET);
// 2. 发送单个字符(HAL库方式,兼容所有Keil版本)
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}

浙公网安备 33010602011771号