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;
}

 

posted @ 2024-10-06 15:07  微笑的''80  阅读(24)  评论(0)    收藏  举报