Files
Leakage-Control/leakage_system/usr/protocol/proto_modbus_master_leakage.c
T
2026-04-23 17:20:51 +08:00

334 lines
9.8 KiB
C

#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_2CH_READ_DATA_NUM (8)
#define PROTO_LEAKAGE_4CH_READ_DATA_NUM (14)
#define PROTO_LEAKAGE_READ_DATA_NUM (PROTO_LEAKAGE_2CH_READ_DATA_NUM) /*读取一个设备寄存器数量*/
#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 = PROTO_LEAKAGE_READ_DATA_NUM;
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);
}
}
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;
leakage.sub_device_data[p_sensor->comm.leakage_data_index].ch_data[i].distance = 0;
}
}
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,temp_value;
u8 *p_rx_valid;
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;
u8 sub_device_ch;
u16 ch_addr_offset[4] = {0,8,16,22}; /*漏液待数据地址偏移*/
u16 temp;
/*子漏液控制器为几通道*/
if(PROTO_LEAKAGE_4CH_READ_DATA_NUM == PROTO_LEAKAGE_READ_DATA_NUM)
{
sub_device_ch = APP_LEAKAGE_SUB_DEVICE_CH_NUM;
}
else if(PROTO_LEAKAGE_2CH_READ_DATA_NUM == PROTO_LEAKAGE_READ_DATA_NUM)
{
sub_device_ch = 2;
}
else
{
sub_device_ch = APP_LEAKAGE_SUB_DEVICE_CH_NUM;
}
if(sensor_index >= APP_LEAKAGE_SUB_DEVICE_NUM)
{
break;
}
/*通道数据重置*/
for(ch = 0;ch < sub_device_ch;ch++)
{
leakage.sub_device_data[sensor_index].ch_data[ch].state = 0;
leakage.sub_device_data[sensor_index].ch_data[ch].distance = 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<sub_device_ch;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;
}
}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;
}
}