#include "syscalls.h" volatile uint8_t usart_dma_tx_over = 1; // 条件编译,适配不同平台 (GNU, GCC) #ifdef __GNUC__ __attribute__((weak)) int _read(int file, char *ptr, int len) { (void)file; int DataIdx; for (DataIdx = 0; DataIdx < len; DataIdx++) { *ptr++ = __io_getchar(); } return len; } __attribute__((weak)) int _write(int file, char *ptr, int len) { (void)file; int DataIdx; for (DataIdx = 0; DataIdx < len; DataIdx++) { __io_putchar(*ptr++); } return len; } #endif /** * @brief 重定向 C 标准库 printf 函数到串口 huart1 * @author Suroy * @param ch * @param f * @return int * * @usage printf("USART1_Target:\r\n"); */ PUTCHAR_PROTOTYPE { HAL_UART_Transmit(HUART, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; } /** * @brief 重定向 c库函数 getchar,scanf到 DEBUG_USARTx * 重定向 C 标准库 scanf 函数到串口 huart1 * 注意以 空格 为结束 * @param f * @return int * * @usage scanf("%c", &RecData); */ GETCHAR_PROTOTYPE { uint8_t ch = 0; HAL_UART_Receive(HUART, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; } // 串口发送完毕回调函数,设置usart_dma_tx_over标志为1 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { #if DEFAULT_HUART == 1 if (huart->Instance == USART1) #else if (huart->Instance == USART2) #endif { usart_dma_tx_over = 1; } } /** * @brief 自定义printf,串口使用头文件定义的DEFAULT_HUART,DMA串口中断方式发送 * * @usage my_printf(HUART1, "USART1_Target:\r\n"); */ int myprintf(const char *format, ...) { va_list arg; static char SendBuff[256] = {0}; int rv; while (!usart_dma_tx_over); // 等待前一次DMA发送完成 va_start(arg, format); rv = vsnprintf((char *)SendBuff, sizeof(SendBuff) + 1, (char *)format, arg); va_end(arg); HAL_UART_Transmit_DMA(HUART, (uint8_t *)SendBuff, rv); usart_dma_tx_over = 0; // 清0全局标志,发送完成后重新置1 return rv; } /** * @brief 自定义printf, 需指定发送串口 * * @usage my_printf(HUART1, "USART1_Target:\r\n"); */ void my_printf(UART_HandleTypeDef *huart, const char *buf, ...) { char str[255] = {0}; va_list v; va_start(v, buf); vsprintf(str, buf, v); HAL_UART_Transmit(huart, (const uint8_t *)str, strlen(str), 0xff); va_end(v); }