#include "uart4.h" #include "stdio.h" #include "string.h" #include "stdarg.h" /* * 调试串口相关定义与缓冲区 * * DEBUG_UART_HANDLE: 外部提供的 UART 句柄(在 CubeMX 产生的代码中为 huart4) * DEBUG_TX_BUF_SIZE: 发送缓冲区大小(单位:字节),用于格式化输出 */ #define DEBUG_UART_HANDLE huart4 #define DEBUG_TX_BUF_SIZE 256 /* 发送缓冲区:用于存放格式化后的字符串 */ static char debug_tx_buf[DEBUG_TX_BUF_SIZE]; /* DMA 发送忙标志(若使用 DMA 发送,可用来避免并发访问) */ static volatile uint8_t dma_busy = 0; /* * 阻塞字符串打印(Debug_Print) * 说明: * - 以阻塞方式调用 HAL_UART_Transmit 发送字符串数据,函数在发送完成或超时前会阻塞。 * - 适用场景:启动日志或对可靠性要求高、且发送频率低的调试信息。 * - 注意:不自动添加换行,需要用户在字符串末尾自己加上 "\r\n"(若需要)。 * 参数: * - str:以 '\0' 结尾的字符串指针 */ void Debug_Print(const char *str) { HAL_UART_Transmit(&DEBUG_UART_HANDLE, (uint8_t *)str, strlen(str), 100); } /* * printf 风格的阻塞打印(Debug_Printf) * * 说明: * - 使用 vsnprintf 将可变参数格式化到内部缓冲区 debug_tx_buf,再以阻塞方式发送。 * - vsnprintf 的返回值 len 表示所需的缓冲区长度(不含终止符)。当 len >= DEBUG_TX_BUF_SIZE * 时表示输出被截断。此处将发送的数据长度限定为 DEBUG_TX_BUF_SIZE(不发送终止符)。 * - 若格式化失败(len <= 0)则直接返回,不进行发送。 * - 发送超时时间为 100 ms,可根据实际需要调整。 * * 注意事项: * - debug_tx_buf 为静态缓冲区,若在中断或多任务环境中使用,请确保同步(或改用 DMA/队列)。 * - 如果输出非常频繁或较大,建议改为异步(DMA)发送或使用环形缓冲队列以避免阻塞。 * * 参数: * - format: printf 风格的格式字符串 */ void Debug_Printf(const char *format, ...) { va_list args; int len; va_start(args, format); /* 将格式化内容写入缓冲区,最多写入 DEBUG_TX_BUF_SIZE 字节(包含终止符) */ len = vsnprintf(debug_tx_buf, DEBUG_TX_BUF_SIZE, format, args); va_end(args); /* 格式化失败或没有输出内容,直接返回 */ if (len <= 0) { return; } /* 如果输出长度超过缓冲区容量,截断到缓冲区最大容量(不发送末尾的 '\0') */ if (len > DEBUG_TX_BUF_SIZE) { len = DEBUG_TX_BUF_SIZE; } /* 阻塞发送格式化后的数据 */ HAL_UART_Transmit(&DEBUG_UART_HANDLE, (uint8_t *)debug_tx_buf, len, 100); } /* * DMA 打印:适合后面大量日志输出。 * 注意:TX DMA 建议 CubeMX 配 Normal,不要配 Circular。 */ void Print_DMA(const char *str) { if (dma_busy) { return; } dma_busy = 1; HAL_UART_Transmit_DMA(&DEBUG_UART_HANDLE, (uint8_t *)str, strlen(str)); } uint8_t UART_IsBusy(void) { return dma_busy; } /* * DMA 发送完成回调 * 注意:整个工程里 HAL_UART_TxCpltCallback 只能实现一次。 * 如果你其他地方也需要这个回调,要统一写在这里分发。 */ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == UART4) { dma_busy = 0; } }