#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_COM3]->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) { proto_sensor_class_t *p_sensor; p_sensor = &p_leakage->sensor[p_leakage->sensor_index]; if(0 == (p_sensor->comm.sensor_state_code & (0x00000001 << PROTO_LEAKAGE_STATE_CODE_TIME_OUT))) { if((++p_sensor->comm.tx_time_out_count) > 20)/*500ms轮询 10秒通讯超时*/ { p_sensor->comm.sensor_state_code |= (0x00000001 << 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_CURR_DATA_GET: { proto_leakage_tx_curr_data_get(p_leakage); }break; default: { }break; } p_sensor->comm.state_send_time++; if(p_sensor->comm.state_send_time >= 3) /*进入异常*/ { p_sensor->comm.sensor_state_code |= (0x00000001 << p_sensor->comm.sensor_state_code);/*记录异常状态*/ p_sensor->comm.state_send_time = 0; p_sensor->comm.sensor_state_code = 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 &= (~(0x00000001 << 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_leakage->sensor_index; u16 ch_addr_offset[4] = {0,4,8,11}; /*漏液待数据地址偏移*/ 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; } }