Files
Leakage-Control/leakage_system/usr/protocol/proto_modbus_master_leakage.c
chenzongxiong 7373c0ad95 update:
设备屏蔽功能
适配新版界面
2026-03-06 13:48:42 +08:00

318 lines
9.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "proto_modbus_master_leakage.h"
#include "string.h"
#include "stdio.h"
#include "app.h"
#include "app_timer.h"
#include "bsp_Uart.h"
#include "bsp_Flash.h"
#include "app_leakage.h"
#include "proto_print.h"
#include "proto_modbus_lib.h"
#define PROTO_LEAKAGE_READ_DATA_NUM (14) /*读取一个设备寄存器数量*/
#define PROTO_LEAKAGE_GET_CURR_DATA_START_ADDR (0x0000)
static void proto_leakage_init(proto_leakage_t *p_leakage);
static void proto_leakage_tx_task(proto_leakage_t *p_leakage);
static void proto_leakage_rx_task(u8 *p_data,u16 len,void *other_data);
static void proto_leakage_com1_uart_send(u8 *p_data,u16 len);
static void proto_leakage_com2_uart_send(u8 *p_data,u16 len);
static void proto_leakage_com3_uart_send(u8 *p_data,u16 len);
static void proto_leakage_com4_uart_send(u8 *p_data,u16 len);
proto_leakage_t modbus_leakage[APP_COM_NUM] =
{
/*COM1*/
{
.init = proto_leakage_init,
.tx_task = proto_leakage_tx_task,
.uart_send = proto_leakage_com1_uart_send,
},
/*COM2*/
{
.init = proto_leakage_init,
.tx_task = proto_leakage_tx_task,
.uart_send = proto_leakage_com2_uart_send,
},
/*COM3*/
{
.init = proto_leakage_init,
.tx_task = proto_leakage_tx_task,
.uart_send = proto_leakage_com3_uart_send,
},
/*COM4*/
{
.init = proto_leakage_init,
.tx_task = proto_leakage_tx_task,
.uart_send = proto_leakage_com4_uart_send,
}
};
static void proto_leakage_init(proto_leakage_t *p_leakage)
{
/*绑定串口解析函数*/
if(p_leakage == &modbus_leakage[APP_COM1])
{
com_to_uart[APP_COM1]->rx_data_analysis = proto_leakage_rx_task;
}
else if(p_leakage == &modbus_leakage[APP_COM2])
{
com_to_uart[APP_COM2]->rx_data_analysis = proto_leakage_rx_task;
}
else if(p_leakage == &modbus_leakage[APP_COM3])
{
com_to_uart[APP_COM3]->rx_data_analysis = proto_leakage_rx_task;
}
else if(p_leakage == &modbus_leakage[APP_COM4])
{
com_to_uart[APP_COM4]->rx_data_analysis = proto_leakage_rx_task;
}
/*绑定modbus_id和对应的索引在app_com中完成*/
}
static void proto_leakage_com1_uart_send(u8 *p_data,u16 len)
{
com_to_uart[APP_COM1]->send(com_to_uart[APP_COM1],p_data,len);
}
static void proto_leakage_com2_uart_send(u8 *p_data,u16 len)
{
com_to_uart[APP_COM2]->send(com_to_uart[APP_COM2],p_data,len);
}
static void proto_leakage_com3_uart_send(u8 *p_data,u16 len)
{
com_to_uart[APP_COM3]->send(com_to_uart[APP_COM3],p_data,len);
}
static void proto_leakage_com4_uart_send(u8 *p_data,u16 len)
{
com_to_uart[APP_COM4]->send(com_to_uart[APP_COM4],p_data,len);
}
/*切换读取的漏液子控*/
static void proto_leakage_switch(proto_leakage_t *p_leakage)
{
p_leakage->sensor_index++;
if(p_leakage->sensor_index >= p_leakage->sensor_num)
{
p_leakage->sensor_index = 0;
}
}
static void proto_leakage_tx_curr_data_get(proto_leakage_t *p_leakage)
{
u16 addr = PROTO_LEAKAGE_GET_CURR_DATA_START_ADDR;
u8 len = 14;
u8 id = p_leakage->sensor[p_leakage->sensor_index].comm.id;
modbus_lib_data_read(id,addr,len,p_leakage->uart_send);
}
static void proto_leakage_tx_task(proto_leakage_t *p_leakage)
{
u16 i;
proto_sensor_class_t *p_sensor;
p_sensor = &p_leakage->sensor[p_leakage->sensor_index];
if(0 == p_leakage->sensor_num)/*没有传感器的COM口不发送*/
{
return;
}
if(0 == (p_sensor->comm.sensor_state_code & (PROTO_LEAKAGE_STATE_CODE_TIME_OUT)))
{
if((++p_sensor->comm.tx_time_out_count) > 10)/*连续读取10次 通讯超时*/
{
p_sensor->comm.sensor_state_code |= (PROTO_LEAKAGE_STATE_CODE_TIME_OUT);
/*清除数据*/
//memset(&gas_data[p_sensor->sensor_index],0,sizeof(gas_data_t));
}
}
switch(p_sensor->comm.state)
{
case PROTO_LEAKAGE_COMM_STATE_INIT:
{
}break;
case PROTO_LEAKAGE_COMM_STATE_CURR_DATA_GET:
{
proto_leakage_tx_curr_data_get(p_leakage);
}break;
default:
{
}break;
}
/*通讯超时*/
if(p_sensor->comm.sensor_state_code & (PROTO_LEAKAGE_STATE_CODE_TIME_OUT))
{
for(i=0;i<APP_LEAKAGE_SUB_DEVICE_CH_NUM;i++)
{
leakage.sub_device_data[p_sensor->comm.leakage_data_index].ch_data[i].state |= APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT;
}
}
else
{
for(i=0;i<APP_LEAKAGE_SUB_DEVICE_CH_NUM;i++)
{
leakage.sub_device_data[p_sensor->comm.leakage_data_index].ch_data[i].state &= (~APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT);
}
}
p_sensor->comm.state_send_time++;
if(p_sensor->comm.state_send_time >= 3) /*进入异常*/
{
p_sensor->comm.sensor_state_code |= (p_sensor->comm.sensor_state_code);/*记录异常状态*/
p_sensor->comm.state_send_time = 0;
p_sensor->comm.state = PROTO_LEAKAGE_COMM_STATE_DEFAULT;
proto_leakage_switch(p_leakage); /*切换设备*/
}
}
static void proto_leakage_rx_task(u8 *p_data,u16 len,void *other_data)
{
u8 send_flag = 0;
u8 modbus_id,cmd;
u16 check_crc16,modbus_crc16;
u16 *p_u16_temp;
u16 i,ch;
u8 *p_rx_valid,temp_value;
proto_sensor_class_t *p_sensor;
proto_leakage_t *p_leakage = NULL;
/***********************查找漏液对象**************************/
if(other_data == NULL)
{
return;
}
/*查找漏液modbus对象*/
for(i=0;i<4;i++)
{
if( (bsp_uart_t *)other_data == com_to_uart[i] )
{
p_leakage = &modbus_leakage[i];
}
}
if(p_leakage == NULL)
{
return;
}
p_sensor = &p_leakage->sensor[p_leakage->sensor_index];
/***********************modbus解析**************************/
if(p_sensor->comm.id != p_data[0])
{
p_data = &p_data[1];
len -= 1;
}
modbus_id = *p_data;
cmd = *(p_data+1);
check_crc16 = p_data[len-2] << 8 | p_data[len-1];
if(modbus_id != p_sensor->comm.id) return ;
if(cmd != 0x03 && cmd != 0x06 && cmd != 0x10 && cmd != 0x41) return ;
modbus_crc16 = modbus_lib_crc16(p_data,len-2);
modbus_crc16 = (modbus_crc16 >> 8) | (modbus_crc16 << 8);
if(check_crc16 != modbus_crc16) return ;
if(cmd == 0x41)
{
p_rx_valid = &p_data[6];
}
p_rx_valid = &p_data[3];
p_sensor->comm.tx_time_out_count = 0;
p_sensor->comm.sensor_state_code &= (~PROTO_LEAKAGE_STATE_CODE_TIME_OUT);
switch(p_sensor->comm.state)
{
case PROTO_LEAKAGE_COMM_STATE_INIT:
{
}break;
case PROTO_LEAKAGE_COMM_STATE_CURR_DATA_GET:
{
/*计算当前设备索引*/
u8 sensor_index = p_sensor->comm.leakage_data_index;
// u16 ch_addr_offset[4] = {0,4,8,11}; /*漏液待数据地址偏移*/
u16 ch_addr_offset[4] = {0,8,16,22}; /*漏液待数据地址偏移*/
u16 temp;
if(sensor_index >= APP_LEAKAGE_SUB_DEVICE_NUM)
{
break;
}
/*通道数据重置*/
for(ch = 0;ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM;ch++)
{
leakage.sub_device_data[sensor_index].ch_data[ch].state = 0;
leakage.sub_device_data[sensor_index].ch_data[ch].state = 0;
}
/* 心跳包0x0003*/
temp_value = (p_rx_valid[6] << 8) | p_rx_valid[7];
leakage.sub_device_data[sensor_index].heartbeat = temp_value & 0xFF;
/*测试模式0x0007*/
temp_value = (p_rx_valid[14] << 8) | p_rx_valid[15];
leakage.sub_device_data[sensor_index].test_mode = temp_value & 0xFF;
/*漏液数据*/
for(i=0;i<4;i++)
{
ch = i;
temp = ch_addr_offset[i];
temp_value = (p_rx_valid[temp + 0] << 8) | p_rx_valid[temp + 1];
if(temp_value == 1)
{
leakage.sub_device_data[sensor_index].ch_data[ch].state |=
APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE;
}
temp_value = (p_rx_valid[temp + 2] << 8) | p_rx_valid[temp + 3];
if(temp_value == 1)
{
leakage.sub_device_data[sensor_index].ch_data[ch].state |=
APP_LEAKAGE_SUB_DEVICE_STATE_OPEN;
}
temp_value = (p_rx_valid[temp + 4] << 8) | p_rx_valid[temp + 5];
leakage.sub_device_data[sensor_index].ch_data[ch].distance = temp_value *0.01;
}
}break;
}
if(send_flag)
{
return;
}
else
{
p_sensor->comm.state = PROTO_LEAKAGE_COMM_STATE_DEFAULT;
p_sensor->comm.sensor_state_code &= (~(0x00000001 << p_sensor->comm.state));/*消除异常状态*/
p_sensor->comm.state_send_time = 0;
proto_leakage_switch(p_leakage);
return;
}
}