From faa836cb94d1ec4e07212ed7735042bf54576d2f Mon Sep 17 00:00:00 2001 From: qiuxin Date: Fri, 23 May 2025 17:46:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BD=8D=E6=9C=BA=E9=80=8F=E4=BC=A0?= =?UTF-8?q?=E8=87=B3HART=E8=AE=BE=E5=A4=87OK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Src/freertos.c | 118 +++++++++++++++++++----------- Core/Src/usart.c | 2 + User/application/src/tcpserverc.c | 72 +++++++++++++++++- 3 files changed, 145 insertions(+), 47 deletions(-) diff --git a/Core/Src/freertos.c b/Core/Src/freertos.c index 02dfa4b..4a4763c 100644 --- a/Core/Src/freertos.c +++ b/Core/Src/freertos.c @@ -185,9 +185,9 @@ void MX_FREERTOS_Init(void) // osThreadDef(ad7124_test_task, start_ad7124_test_task, osPriorityNormal, 0, 512); // ad7124_test_taskHandle = osThreadCreate(osThread(ad7124_test_task), NULL); - /* definition and creation of usart6_test_task */ - osThreadDef(usart6_test_task, start_usart6_test_task, osPriorityNormal, 0, 128); - usart6_test_taskHandle = osThreadCreate(osThread(usart6_test_task), NULL); + /* HART测试任务 */ + // osThreadDef(usart6_test_task, start_usart6_test_task, osPriorityNormal, 0, 128); + // usart6_test_taskHandle = osThreadCreate(osThread(usart6_test_task), NULL); /* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */ @@ -416,59 +416,91 @@ void test_cs_pin(void) * @retval None */ /* USER CODE END Header_start_usart6_test_task */ +// 添加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) +{ + uart6_rx_data = uart6_rx_buffer[0]; + uart6_rx_flag = 1; + // 重新启动接收 + HAL_UART_Receive_IT(&huart6, uart6_rx_buffer, 1); +} + void start_usart6_test_task(void const *argument) { /* USER CODE BEGIN start_usart6_test_task */ - // 使用简单的测试模式:0x55 (01010101) 和 0xAA (10101010) - uint8_t test_data[] = {0xFF,0x55, 0xAA, 0x85, 0x8A, 0x57, 0xAB}; // 6字节交替的0和1,便于观察 - uint8_t counter = 0; + uint8_t rx_buffer[1]; // 接收缓冲区 + uint8_t tcp_tx_data[300] = {0}; // TCP发送缓冲区 + uint16_t tx_data_len = 0; - // 重置HART模块 - hart_ht1200m_reset(); - - // 重新配置USART6 - huart6.Instance = USART6; - huart6.Init.BaudRate = 1200; - huart6.Init.WordLength = UART_WORDLENGTH_9B;//9位数据 - huart6.Init.StopBits = UART_STOPBITS_1;//1位停止位 - huart6.Init.Parity = UART_PARITY_ODD;//奇校验 - huart6.Init.Mode = UART_MODE_TX_RX;//收发模式 - huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;//无硬件流控 - huart6.Init.OverSampling = UART_OVERSAMPLING_16;//16倍过采样 - - - if (HAL_UART_Init(&huart6) != HAL_OK) - { + // 确保UART6已正确初始化 + if (huart6.Instance == NULL) { Error_Handler(); } - //MX_GPIO_Init(); + + // 重新初始化UART6 + HAL_UART_DeInit(&huart6); + huart6.Init.BaudRate = 1200; + huart6.Init.WordLength = UART_WORDLENGTH_8B; + huart6.Init.StopBits = UART_STOPBITS_1; + huart6.Init.Parity = UART_PARITY_NONE; + huart6.Init.Mode = UART_MODE_TX_RX; + huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart6.Init.OverSampling = UART_OVERSAMPLING_16; + if (HAL_UART_Init(&huart6) != HAL_OK) { + Error_Handler(); + } + /* Infinite loop */ for(;;) { - - if (huart6.gState == HAL_UART_STATE_READY) + // 使用HAL库函数检查接收状态 + if (HAL_UART_GetState(&huart6) == HAL_UART_STATE_READY) { - - - HART1_RTS_SEND; - vTaskDelay(8); - - if (HAL_UART_Transmit(&huart6, test_data, sizeof(test_data), 100) != HAL_OK) + // 尝试接收一个字节,超时时间设为0 + if (HAL_UART_Receive(&huart6, rx_buffer, 1, 0) == HAL_OK) { - Error_Handler(); + // 检查TCP连接状态 + if (server_pcb_control != NULL && tcp_echo_flags_control == 1) + { + // 构造帧头等 + tcp_tx_data[0] = 0xD5; // 帧头1 + tcp_tx_data[1] = 0xC8; // 帧头2 + tcp_tx_data[2] = 0x00; // 帧长度高字节 (1 + 11 = 12) + tcp_tx_data[3] = 0x0C; // 帧长度低字节 + tcp_tx_data[4] = 0x01; // 源地址高 + tcp_tx_data[5] = 0x02; // 源地址低 + tcp_tx_data[6] = 0x0A; // 目标地址高 + tcp_tx_data[7] = 0x0B; // 目标地址低 + tcp_tx_data[8] = 0x88; // 报文类型(透传) + + // 复制接收到的数据 + tcp_tx_data[9] = rx_buffer[0]; + + // 计算校验和 + uint16_t checksum = 0; + for (int i = 4; i < 10; i++) + { + checksum += tcp_tx_data[i]; + } + tcp_tx_data[10] = 0x00; // 校验和高字节 + tcp_tx_data[11] = checksum & 0xFF; // 校验和低字节 + + // 发送数据 + tx_data_len = 12; // 总长度 = 数据长度(1) + 帧头(2) + 帧长(2) + 源地址(2) + 目标地址(2) + 类型(1) + 校验(2) + user_send_data_control(tcp_tx_data, tx_data_len); + } } - - counter++; - vTaskDelay(5); - HART1_RTS_RECEIVE; - - vTaskDelay(500); // 500ms延时 - } - else - { - // 如果UART不就绪,等待一段时间后重试 - vTaskDelay(100); } + + vTaskDelay(1); // 给其他任务执行的机会 } /* USER CODE END start_usart6_test_task */ } diff --git a/Core/Src/usart.c b/Core/Src/usart.c index e6790e7..e7e7f53 100644 --- a/Core/Src/usart.c +++ b/Core/Src/usart.c @@ -211,6 +211,8 @@ void MX_USART6_UART_Init(void) { Error_Handler(); } + // 重置HART模块 + hart_ht1200m_reset(); /* USER CODE BEGIN USART6_Init 2 */ // __HAL_UART_ENABLE_IT(&huart6, UART_IT_RXNE); // 接收中断 // __HAL_UART_ENABLE_IT(&huart6, UART_IT_IDLE); // 空闲中断 diff --git a/User/application/src/tcpserverc.c b/User/application/src/tcpserverc.c index 6b7140b..caedf65 100644 --- a/User/application/src/tcpserverc.c +++ b/User/application/src/tcpserverc.c @@ -16,6 +16,13 @@ #include "user_gpio.h" #include "tim.h" #include "ad7124.h" + +// 添加test_adc_read_data变量定义 +uint8_t test_adc_read_data[74] = {0}; // 74字节的测试数据缓冲区 + +// 添加handle_type_88函数声明 +uint16_t handle_type_88(const uint8_t *body, uint16_t body_len, uint8_t *tx); + struct tcp_pcb *server_pcb_hart1 = NULL; struct tcp_pcb *server_pcb_hart2 = NULL; struct tcp_pcb *server_pcb_ble1 = NULL; @@ -71,7 +78,7 @@ uint8_t adc_read_data[22] = { 0x0C,0x80,// 模拟输出6高字节, 模拟输出6低字节, 0x0C,0x80,// 输出目标设备4 - 20mA高字节, 输出目标设备4 - 20mA低字节, 0x0C,0x80,// 比例阀1输出高字节, 比例阀1输出低字节, - 0x0C,0x80,// 比例阀2输出高字节, 比例阀2输出低字节 + 0x0C,0x80,// 比例阀2输出高字节, 比例阀2输出低字节, }; uint8_t adc_set_data[22] = { @@ -420,6 +427,61 @@ uint16_t handle_type_87(const uint8_t *body, uint16_t body_len, uint8_t *tx) return total_len; } + +// 添加handle_type_88函数实现 +uint16_t handle_type_88(const uint8_t *body, uint16_t body_len, uint8_t *tx) +{ + uint16_t total_len = 2 + 2 + 2 + 2 + 1 + body_len + 2; // 帧头+帧长+源+目标+类型+体+校验 + + // 帧头 + tx[0] = head_00; + tx[1] = head_01; + + // 帧长度(大端) + tx[2] = (total_len >> 8) & 0xFF; + tx[3] = total_len & 0xFF; + + // 源地址 + tx[4] = source_addr_h; + tx[5] = source_addr_l; + + // 目标地址 + tx[6] = target_addr_h; + tx[7] = target_addr_l; + + // 报文类型 + tx[8] = reply_type; + + // 报文体 - 直接透传数据 + memcpy(&tx[9], body, body_len); + + // 校验和 + uint16_t checksum = 0; + for (int i = 4; i < 9 + body_len; ++i) + { + checksum += tx[i]; + } + + // 校验和2字节(大端,只取低8位) + tx[total_len - 2] = 0x00; // 高8位强制为0 + tx[total_len - 1] = checksum & 0xFF; + + if (huart6.gState == HAL_UART_STATE_READY) + { + + 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; + } + return total_len; +} + /*接收回调函数*/ static err_t tcpecho_recv_hart1(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { // 对应接收数据连接的控制块 接收到的数据 @@ -605,14 +667,16 @@ static err_t tcpecho_recv_control(void *arg, struct tcp_pcb *tpcb, struct pbuf * break; case 0x87://读取测试数据 { - uint16_t body_len = 74; //22个字节表示的是设置的参数 + uint16_t body_len = 74; reply_type = tcp_rx_data[8]; - //tx_data_len = handle_type_87(test_adc_read_data, body_len, tcp_tx_data); + tx_data_len = handle_type_87(test_adc_read_data, body_len, tcp_tx_data); } break; case 0x88://透传数据 { - + uint16_t body_len = rx_data_len - 11; + reply_type = tcp_rx_data[8]; + tx_data_len = handle_type_88(tcp_rx_data + 9, body_len, tcp_tx_data); } break;