解决分帧问题
This commit is contained in:
parent
123869efc4
commit
beae8c556b
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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,41 +540,31 @@ 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)
|
||||
{
|
||||
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);
|
||||
uart6_data_buffer[uart6_buffer_index++] = uart6_data_bits;
|
||||
uart6_last_rx_time = current_time; // 更新最后接收时间
|
||||
}
|
||||
else
|
||||
{
|
||||
// 其他错误,关闭连接
|
||||
tcp_abort(server_pcb_control);
|
||||
server_pcb_control = NULL;
|
||||
tcp_echo_flags_control = 0;
|
||||
// 缓冲区满,强制发送
|
||||
if (server_pcb_control != NULL && tcp_echo_flags_control == 1 && uart6_buffer_index > 0)
|
||||
{
|
||||
err = tcp_write(server_pcb_control, uart6_data_buffer, uart6_buffer_index, 1);
|
||||
if (err == ERR_OK)
|
||||
{
|
||||
tcp_output(server_pcb_control);
|
||||
}
|
||||
}
|
||||
// 重置缓冲区
|
||||
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 */
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
if (HAL_UART_Transmit(&huart6, body, body_len, 100) != HAL_OK)
|
||||
|
||||
HAL_StatusTypeDef uart_status = HAL_UART_Transmit(&huart6, body, body_len, 1000); // 增加超时时间
|
||||
if (uart_status != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
// 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)
|
||||
|
|
Loading…
Reference in New Issue