#include "bsp_uart.h" #include "elog.h" /** * @brief 使用 UART1 和 DMA 发送数据到 ESP12F 模块(用于 TCP 透传) * @param data: 要发送的数据指针(以 \0 结尾) * @return HAL_StatusTypeDef: HAL_OK 表示成功,其他值表示失败 */ HAL_StatusTypeDef ESP12F_TCP_SendMessage(const char *data) { if (data == NULL) { return HAL_ERROR; // 参数无效 } // 计算数据大小 uint16_t size = strlen(data); if (size == 0) { return HAL_ERROR; // 数据为空 } // 启动 DMA 传输 return HAL_UART_Transmit_DMA(&huart1, (uint8_t *)data, size); } /* External DMA handle */ extern DMA_HandleTypeDef hdma_usart1_rx; /* DMA 接收缓冲区及状态变量 */ uint8_t uart1_rx_buf[UART1_RX_BUF_SIZE]; volatile uint16_t uart1_rx_len = 0; /* 记录最近一次接收到的数据包长度 */ volatile uint8_t uart1_rx_flag = 0; /* 接收完成标志位:1表示有一帧新数据 */ /** * @brief 初始化 UART1 并启动 DMA 接收 * @details 该函数启动 UART1 的 DMA 接收功能,并启用 IDLE 线检测中断, * 用于接收不定长数据包。当检测到 IDLE 事件时,表示一帧数据接收完成。 * @param 无 * @return 无 * @note 需要在调用此函数前确保 UART1 和 DMA 已经正确初始化 */ void BSP_UART1_Init(void) { /* 停止并重置 DMA 状态 */ HAL_UART_DMAStop(&huart1); uart1_rx_len = 0; uart1_rx_flag = 0; memset(uart1_rx_buf, 0, sizeof(uart1_rx_buf)); /* 启动 DMA 接收,将接收到的数据存储到 uart1_rx_buf 缓冲区 */ HAL_UART_Receive_DMA(&huart1, uart1_rx_buf, UART1_RX_BUF_SIZE); /* 使能串口空闲(IDLE)中断,用于判断不定长数据帧接收完成 */ __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); } /** * @brief UART 空闲中断回调函数 * @details 当串口线进入空闲状态(一帧数据传输结束)时被调用。 * 通过 DMA 计数器计算接收到的字节数,更新标志位供上层应用处理。 * @param huart: 串口句柄指针 */ void UART_IDLE_Callback(UART_HandleTypeDef *huart) { /* 仅处理 USART1 的实例 */ if (huart == NULL || huart->Instance != USART1) return; /* 清除空闲中断标志位(HAL库宏) */ __HAL_UART_CLEAR_IDLEFLAG(huart); /* 停止 DMA 以便安全读取计数器并更新状态 */ HAL_UART_DMAStop(huart); /* 计算接收到的字节数:总缓冲区长度 - DMA 剩余传输计数 */ uint16_t recv_len = UART1_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx); if (recv_len > 0 && recv_len < UART1_RX_BUF_SIZE) { uart1_rx_len = recv_len; uart1_rx_buf[recv_len] = '\0'; /* 添加字符串结束符,方便后续字符串处理 */ uart1_rx_flag = 1; /* 置位标志,通知应用层新消息到达 */ /* 仅供调试:在中断中打印接收到的数据(注意:printf 可能会影响实时性) */ elog_raw("UART1 Received: %s\r\n", (char *)uart1_rx_buf); } /* 重新启动新一轮的 DMA 接收 */ HAL_UART_Receive_DMA(&huart1, uart1_rx_buf, UART1_RX_BUF_SIZE); }