解决分帧问题

This commit is contained in:
qiuxin 2025-05-27 11:44:14 +08:00
parent 123869efc4
commit beae8c556b
4 changed files with 252 additions and 73 deletions

View File

@ -60,7 +60,7 @@ void MX_USART3_UART_Init(void);
void MX_USART6_UART_Init(void);
/* USER CODE BEGIN Prototypes */
void dma_usart_send(UART_HandleTypeDef *huart, uint8_t *buf, uint8_t len); // DMA??
HAL_StatusTypeDef dma_usart_send(UART_HandleTypeDef *huart, uint8_t *buf, uint8_t len); // DMA发送函数
/* USER CODE END Prototypes */

View File

@ -25,6 +25,8 @@
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdint.h> // 添加标准整型定义
#include "stm32f4xx_hal.h" // 添加HAL库定义
#include "dac161s997.h"
#include "ad7124.h"
#include "usart.h"
@ -110,6 +112,19 @@ volatile uint8_t tca6416_port0_dir = 0; // Port0方向寄存器值
volatile uint8_t tca6416_port1_dir = 0; // Port1方向寄存器值
volatile uint8_t tca6416_i2c_ack_status = 0; // I2C应答状态
// 添加接收缓冲区
static uint8_t uart6_rx_buffer[1];
static volatile uint8_t uart6_rx_data = 0;
static volatile uint8_t uart6_rx_flag = 0;
// 添加数据缓冲相关变量
#define UART6_BUFFER_SIZE 128
#define UART6_TIMEOUT_MS 50 // 50ms超时认为数据包结束
static uint8_t uart6_data_buffer[UART6_BUFFER_SIZE];
static volatile uint16_t uart6_buffer_index = 0;
static volatile uint32_t uart6_last_rx_time = 0;
/* USER CODE END Variables */
/* Private function prototypes -----------------------------------------------*/
@ -459,11 +474,6 @@ void test_cs_pin(void)
// 添加UART接收回调函数声明
static void UART6_RxCpltCallback(void);
// 添加接收缓冲区
static uint8_t uart6_rx_buffer[1];
static volatile uint8_t uart6_rx_data = 0;
static volatile uint8_t uart6_rx_flag = 0;
// UART接收完成回调函数
static void UART6_RxCpltCallback(void)
{
@ -472,12 +482,12 @@ static void UART6_RxCpltCallback(void)
// 重新启动接收
HAL_UART_Receive_IT(&huart6, uart6_rx_buffer, 1);
}
//HART1 串口测试任务
void start_usart6_test_task(void const *argument)
{
/* USER CODE BEGIN start_usart6_test_task */
uint8_t rx_buffer[1]; // 接收缓冲区
err_t err;
uint32_t current_time;
// 确保UART6已正确初始化
if (huart6.Instance == NULL) {
@ -504,9 +514,15 @@ void start_usart6_test_task(void const *argument)
Error_Handler();
}
// 初始化缓冲区
uart6_buffer_index = 0;
uart6_last_rx_time = 0;
/* Infinite loop */
for(;;)
{
current_time = HAL_GetTick();
// 直接检查接收标志
if (__HAL_UART_GET_FLAG(&huart6, UART_FLAG_RXNE))
{
@ -524,40 +540,30 @@ void start_usart6_test_task(void const *argument)
if (__HAL_UART_GET_FLAG(&huart6, UART_FLAG_FE)) uart6_error_flags |= 0x02;
if (__HAL_UART_GET_FLAG(&huart6, UART_FLAG_ORE)) uart6_error_flags |= 0x04;
// 使用数据位作为接收数据
rx_buffer[0] = uart6_data_bits;
// 检查是否有接收错误
if (uart6_error_flags == 0)
{
// 检查TCP连接状态
if (server_pcb_control != NULL && tcp_echo_flags_control == 1)
// 将数据添加到缓冲区
if (uart6_buffer_index < UART6_BUFFER_SIZE)
{
// 尝试发送数据
err = tcp_write(server_pcb_control, rx_buffer, 1, 1);
if (err == ERR_OK)
uart6_data_buffer[uart6_buffer_index++] = uart6_data_bits;
uart6_last_rx_time = current_time; // 更新最后接收时间
}
else
{
// 缓冲区满,强制发送
if (server_pcb_control != NULL && tcp_echo_flags_control == 1 && uart6_buffer_index > 0)
{
err = tcp_output(server_pcb_control);
if (err != ERR_OK)
err = tcp_write(server_pcb_control, uart6_data_buffer, uart6_buffer_index, 1);
if (err == ERR_OK)
{
// TCP输出失败可能需要重新建立连接
tcp_abort(server_pcb_control);
server_pcb_control = NULL;
tcp_echo_flags_control = 0;
tcp_output(server_pcb_control);
}
}
else if (err == ERR_MEM)
{
// 内存不足,等待一段时间后重试
vTaskDelay(10);
}
else
{
// 其他错误,关闭连接
tcp_abort(server_pcb_control);
server_pcb_control = NULL;
tcp_echo_flags_control = 0;
}
// 重置缓冲区
uart6_buffer_index = 0;
uart6_data_buffer[uart6_buffer_index++] = uart6_data_bits;
uart6_last_rx_time = current_time;
}
}
else
@ -569,7 +575,47 @@ void start_usart6_test_task(void const *argument)
}
}
vTaskDelay(1); // 给其他任务执行的机会
// 检查超时,如果超时且有数据则发送
if (uart6_buffer_index > 0 &&
uart6_last_rx_time > 0 &&
(current_time - uart6_last_rx_time) >= UART6_TIMEOUT_MS)
{
// 检查TCP连接状态并发送缓冲区数据
if (server_pcb_control != NULL && tcp_echo_flags_control == 1)
{
err = tcp_write(server_pcb_control, uart6_data_buffer, uart6_buffer_index, 1);
if (err == ERR_OK)
{
err = tcp_output(server_pcb_control);
if (err != ERR_OK)
{
// TCP输出失败关闭连接
tcp_abort(server_pcb_control);
server_pcb_control = NULL;
tcp_echo_flags_control = 0;
}
}
else if (err == ERR_MEM)
{
// 内存不足,等待一段时间后重试
vTaskDelay(10);
continue; // 不清除缓冲区,下次重试
}
else
{
// 其他错误(如连接已关闭),关闭连接
tcp_abort(server_pcb_control);
server_pcb_control = NULL;
tcp_echo_flags_control = 0;
}
}
// 重置缓冲区
uart6_buffer_index = 0;
uart6_last_rx_time = 0;
}
vTaskDelay(5); // 给其他任务执行的机会
}
/* USER CODE END start_usart6_test_task */
}

View File

@ -786,26 +786,50 @@ void HAL_DMA_TxCpltCallback(DMA_HandleTypeDef *hdma)
}
/**
* @brief 使DMA发送USART数据
* @brief 使DMA发送USART数据
*
* USART使用DMA发送数据
* USART使用DMA发送数据
*
* @param huart USART句柄UART_HandleTypeDef结构体指针
* @param buf
* @param len
* @return HAL_StatusTypeDef
*/
void dma_usart_send(UART_HandleTypeDef *huart, uint8_t *buf, uint8_t len)
HAL_StatusTypeDef dma_usart_send(UART_HandleTypeDef *huart, uint8_t *buf, uint8_t len)
{
/* 等待上一次传输完成 */
uint32_t timeout = 1000; // 1秒超时
uint32_t start_time = HAL_GetTick();
// 检查参数有效性
if (huart == NULL || buf == NULL || len == 0) {
return HAL_ERROR;
}
/* 等待上一次传输完成,添加超时机制 */
while(huart->gState == HAL_UART_STATE_BUSY_TX)
{
if ((HAL_GetTick() - start_time) > timeout) {
// 超时强制停止DMA传输
HAL_UART_DMAStop(huart);
huart->gState = HAL_UART_STATE_READY;
return HAL_TIMEOUT;
}
osDelay(1);
}
if (HAL_UART_Transmit_DMA(huart, buf, len) != HAL_OK)
{
Error_Handler();
// 检查UART状态
if (huart->gState != HAL_UART_STATE_READY) {
return HAL_BUSY;
}
// 启动DMA传输
HAL_StatusTypeDef status = HAL_UART_Transmit_DMA(huart, buf, len);
if (status != HAL_OK) {
// DMA启动失败重置UART状态
huart->gState = HAL_UART_STATE_READY;
}
return status;
}
/* USER CODE END 1 */

View File

@ -472,19 +472,21 @@ uint16_t handle_type_88(const uint8_t *body, uint16_t body_len, uint8_t *tx)
tx[total_len - 2] = 0x00; // 高8位强制为0
tx[total_len - 1] = checksum & 0xFF;
if (huart6.gState == HAL_UART_STATE_READY)
// 改进的UART6发送处理
HART1_RTS_SEND;
vTaskDelay(5);
HAL_StatusTypeDef uart_status = HAL_UART_Transmit(&huart6, body, body_len, 1000); // 增加超时时间
if (uart_status != HAL_OK)
{
HART1_RTS_SEND;
vTaskDelay(5);
if (HAL_UART_Transmit(&huart6, body, body_len, 100) != HAL_OK)
{
Error_Handler();
hart_ht1200m_reset();
}
vTaskDelay(5);
HART1_RTS_RECEIVE;
// UART发送失败不调用Error_Handler而是重置HART模块
hart_ht1200m_reset();
HAL_UART_DeInit(&huart6);
MX_USART6_UART_Init();
}
vTaskDelay(5);
HART1_RTS_RECEIVE;
return total_len;
}
@ -498,11 +500,21 @@ static err_t tcpecho_recv_hart1(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,
tcp_recved(tpcb, p->tot_len); // 读取数据的控制块 得到所有数据的长度
server_pcb_hart1 = tpcb; // 直接赋值
memcpy(hart1_uart5.tx_data, (int *)p->payload, p->tot_len);
if (huart5.gState == HAL_UART_STATE_READY)
// 改进的DMA发送处理
HAL_StatusTypeDef dma_status = dma_usart_send(&huart5, hart1_uart5.tx_data, p->tot_len);
if (dma_status != HAL_OK)
{
HART1_RTS_SEND;
dma_usart_send(&huart5, hart1_uart5.tx_data, p->tot_len);
// DMA发送失败记录错误但不调用Error_Handler
// 可以在这里添加错误计数或重试逻辑
if (dma_status == HAL_TIMEOUT)
{
// 超时错误可能需要重置UART
HAL_UART_DeInit(&huart5);
MX_UART5_Init();
}
}
pbuf_free(p);
}
else if (err == ERR_OK) // 检测到对方主动关闭连接时也会调用recv函数此时p为空
@ -523,10 +535,18 @@ static err_t tcpecho_recv_hart2(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,
tcp_recved(tpcb, p->tot_len); // 读取数据的控制块 得到所有数据的长度
server_pcb_hart2 = tpcb; // 直接赋值
memcpy(hart2_uart2.tx_data, (int *)p->payload, p->tot_len);
if (huart2.gState == HAL_UART_STATE_READY)
// 改进的DMA发送处理
HAL_StatusTypeDef dma_status = dma_usart_send(&huart2, hart2_uart2.tx_data, p->tot_len);
if (dma_status != HAL_OK)
{
//HART2_RTS_SEND;
dma_usart_send(&huart2, hart2_uart2.tx_data, p->tot_len);
// DMA发送失败处理
if (dma_status == HAL_TIMEOUT)
{
// 超时错误重置UART
HAL_UART_DeInit(&huart2);
MX_USART2_UART_Init();
}
}
pbuf_free(p);
@ -550,9 +570,18 @@ static err_t tcpecho_recv_ble1(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,
server_pcb_ble1 = tpcb; // 直接赋值
memcpy(ble1_uart6.tx_data, (int *)p->payload, p->tot_len);
if (huart6.gState == HAL_UART_STATE_READY)
// 改进的DMA发送处理
HAL_StatusTypeDef dma_status = dma_usart_send(&huart6, ble1_uart6.tx_data, p->tot_len);
if (dma_status != HAL_OK)
{
dma_usart_send(&huart6, ble1_uart6.tx_data, p->tot_len);
// DMA发送失败处理
if (dma_status == HAL_TIMEOUT)
{
// 超时错误重置UART
HAL_UART_DeInit(&huart6);
MX_USART6_UART_Init();
}
}
pbuf_free(p);
@ -574,10 +603,20 @@ static err_t tcpecho_recv_ble2(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,
tcp_recved(tpcb, p->tot_len); // 读取数据的控制块 得到所有数据的长度
server_pcb_ble2 = tpcb; // 直接赋值
memcpy(ble2_uart3.tx_data, (int *)p->payload, p->tot_len);
if (huart3.gState == HAL_UART_STATE_READY)
// 改进的DMA发送处理
HAL_StatusTypeDef dma_status = dma_usart_send(&huart3, ble2_uart3.tx_data, p->tot_len);
if (dma_status != HAL_OK)
{
dma_usart_send(&huart3, ble2_uart3.tx_data, p->tot_len);
// DMA发送失败处理
if (dma_status == HAL_TIMEOUT)
{
// 超时错误重置UART
HAL_UART_DeInit(&huart3);
MX_USART3_UART_Init();
}
}
pbuf_free(p);
}
else if (err == ERR_OK) // 检测到对方主动关闭连接时也会调用recv函数此时p为空
@ -818,31 +857,101 @@ void tcp_echo_init(void)
void user_send_data_hart1(uint8_t *data, uint16_t len)
{
tcp_write(server_pcb_hart1, data, len, 1);
if (server_pcb_hart1 != NULL && tcp_echo_flags_hart1 == 1 && data != NULL && len > 0)
{
err_t err = tcp_write(server_pcb_hart1, data, len, 1);
if (err != ERR_OK)
{
// TCP写入失败关闭连接
tcp_abort(server_pcb_hart1);
server_pcb_hart1 = NULL;
tcp_echo_flags_hart1 = 0;
}
else
{
// 立即输出数据
tcp_output(server_pcb_hart1);
}
}
}
void user_send_data_hart2(uint8_t *data, uint16_t len)
{
tcp_write(server_pcb_hart2, data, len, 1);
if (server_pcb_hart2 != NULL && tcp_echo_flags_hart2 == 1 && data != NULL && len > 0)
{
err_t err = tcp_write(server_pcb_hart2, data, len, 1);
if (err != ERR_OK)
{
// TCP写入失败关闭连接
tcp_abort(server_pcb_hart2);
server_pcb_hart2 = NULL;
tcp_echo_flags_hart2 = 0;
}
else
{
// 立即输出数据
tcp_output(server_pcb_hart2);
}
}
}
#if (BLE2_USART6 == 1)
void user_send_data_ble1(uint8_t *data, uint16_t len)
{
tcp_write(server_pcb_ble1, data, len, 1);
if (server_pcb_ble1 != NULL && tcp_echo_flags_ble1 == 1 && data != NULL && len > 0)
{
err_t err = tcp_write(server_pcb_ble1, data, len, 1);
if (err != ERR_OK)
{
// TCP写入失败关闭连接
tcp_abort(server_pcb_ble1);
server_pcb_ble1 = NULL;
tcp_echo_flags_ble1 = 0;
}
else
{
// 立即输出数据
tcp_output(server_pcb_ble1);
}
}
}
#endif
void user_send_data_ble2(uint8_t *data, uint16_t len)
{
tcp_write(server_pcb_ble2, data, len, 1);
if (server_pcb_ble2 != NULL && tcp_echo_flags_ble2 == 1 && data != NULL && len > 0)
{
err_t err = tcp_write(server_pcb_ble2, data, len, 1);
if (err != ERR_OK)
{
// TCP写入失败关闭连接
tcp_abort(server_pcb_ble2);
server_pcb_ble2 = NULL;
tcp_echo_flags_ble2 = 0;
}
else
{
// 立即输出数据
tcp_output(server_pcb_ble2);
}
}
}
void user_send_data_control(uint8_t *data, uint16_t len)
{
tcp_write(server_pcb_control, data, len, 1);
if (server_pcb_control != NULL && tcp_echo_flags_control == 1 && data != NULL && len > 0)
{
err_t err = tcp_write(server_pcb_control, data, len, 1);
if (err != ERR_OK)
{
// TCP写入失败关闭连接
tcp_abort(server_pcb_control);
server_pcb_control = NULL;
tcp_echo_flags_control = 0;
}
else
{
// 立即输出数据
tcp_output(server_pcb_control);
}
}
}
void uart_forwarding_tcp(void)