上位机透传至HART设备OK

This commit is contained in:
qiuxin 2025-05-23 17:46:01 +08:00
parent 2135af95bb
commit faa836cb94
3 changed files with 145 additions and 47 deletions

View File

@ -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 */
}

View File

@ -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); // 空闲中断

View File

@ -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;