Files
motor_ili9341/SystemDrivers/uart4.c
T
2026-07-08 10:30:07 +08:00

119 lines
3.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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;
}
}