/*对外通讯 modbus从机*/ #include "proto_modbus_tcp_slave_ex.h" #include "string.h" #include "stdio.h" #include "app.h" #include "app_timer.h" #include "app_leakage.h" #include "bsp_relay.h" #include "bsp_Uart.h" #include "bsp_Flash.h" #include "bsp_W5500.h" #include "proto_print.h" #include "proto_modbus_master_leakage.h" static modbus_analysis_data_t modbus_analysis_data;//指令解析结构体 static modbus_communication_send_buf_t send_struct;//发送结构体 static void proto_modbus_communication_data_analysis(u8 *pData, u16 len, void *data); static void proto_modbus_communication_data_send(u8 *pData, u16 len); static void proto_modbus_init(void); static void proto_modbus_task(void); static modbus_error_code_e proto_modbus_data_write(u16 Addr, u16 Value); static u16 proto_modbus_data_read(u16 Addr); proto_Modbus_t modbus_slave_ex= { .id = 0x01, .data_read = proto_modbus_data_read, .data_write = proto_modbus_data_write, .data_analysis = proto_modbus_communication_data_analysis, .init = proto_modbus_init, .task = proto_modbus_task, }; static proto_Modbus_t *p_modbus = &modbus_slave_ex; bsp_W5500_Class_t *p_W5500_Class = NULL; static void proto_modbus_communication_data_send(u8 *p_data, u16 len) { if(NULL != p_W5500_Class) { W5500.Socket_Send(p_W5500_Class,p_data,len); } } static void proto_modbus_init(void) { W5500.W5500_Class[0].Rx_DataAnalysis = proto_modbus_communication_data_analysis; } static void proto_modbus_task(void) { } static void proto_modbus_communication_data_analysis(u8 *pData, u16 len,void *other_data) { modbus_error_code_e error_code; u16 inx; u16 TempAddr, TempData, crc_16; u16 send_buff_index_offset = 0; u16 transaction_type,proto_type,proto_len; /*mobuds_tcp校验*/ transaction_type = pData[0] << 8 | pData[1]; /*事务类型*/ proto_type = pData[2] << 8 | pData[3]; /*协议类型*/ proto_len = pData[4] << 8 | pData[5]; /*协议长度*/ /*协议类型 长度判断*/ if(MODBUS_TCP_PROTO_TYPE != proto_type || proto_len != (len - 6)) { return; } p_W5500_Class = (bsp_W5500_Class_t *)other_data; /*正常modbus协议解析*/ modbus_analysis_data.id = pData[6]; modbus_analysis_data.func = pData[7]; modbus_analysis_data.start_addr = pData[8] << 8 | pData[9]; modbus_analysis_data.reg_number = pData[10] << 8 | pData[11]; send_buff_index_offset = 6; memcpy(send_struct.send_buffer,pData,send_buff_index_offset); error_code = ModbusErrorCode_Success; /* //检查地址是否超出范围 if ((modbus_analysis_data.start_addr >= MODBUS_REG_LEN) || (modbus_analysis_data.reg_number >= MODBUS_REG_LEN) || (modbus_analysis_data.start_addr + modbus_analysis_data.reg_number >= MODBUS_REG_LEN)) { ErrorCode = ModbusErrorCode_IllegalAddr; goto Error; } */ switch (modbus_analysis_data.func) { case 0x03: case 0x04: { TempAddr = modbus_analysis_data.start_addr; send_struct.send_buffer[send_buff_index_offset + 0] = modbus_analysis_data.id; send_struct.send_buffer[send_buff_index_offset + 1] = modbus_analysis_data.func; send_struct.send_buffer[send_buff_index_offset + 2] = 2 * modbus_analysis_data.reg_number; for (inx = 0; inx < modbus_analysis_data.reg_number; inx++) { TempData = proto_modbus_data_read(TempAddr); send_struct.send_buffer[send_buff_index_offset + 3 + 2 * inx] = (TempData >> 8) & 0xff; send_struct.send_buffer[send_buff_index_offset + 4 + 2 * inx] = TempData & 0xff; TempAddr++; } send_struct.len =send_buff_index_offset + 3 + send_struct.send_buffer[send_buff_index_offset + 2]; }goto Success; /*特殊协议*/ case 0x41: { TempAddr = modbus_analysis_data.start_addr; send_struct.send_buffer[send_buff_index_offset + 0] = modbus_analysis_data.id; send_struct.send_buffer[send_buff_index_offset + 1] = modbus_analysis_data.func; send_struct.send_buffer[send_buff_index_offset + 2] = modbus_analysis_data.start_addr >> 8; send_struct.send_buffer[send_buff_index_offset + 3] = modbus_analysis_data.start_addr & 0xff; send_struct.send_buffer[send_buff_index_offset + 4] = (2 * modbus_analysis_data.reg_number) >> 8; send_struct.send_buffer[send_buff_index_offset + 5] = (2 * modbus_analysis_data.reg_number) & 0xff; for (inx = 0; inx < modbus_analysis_data.reg_number; inx++) { TempData = proto_modbus_data_read(TempAddr); send_struct.send_buffer[send_buff_index_offset + 6 + 2 * inx] = (TempData >> 8) & 0xff; send_struct.send_buffer[send_buff_index_offset + 7 + 2 * inx] = TempData & 0xff; TempAddr++; } send_struct.len = send_buff_index_offset + 6 + 2 * modbus_analysis_data.reg_number; }goto Success; case 0x06: { TempAddr = modbus_analysis_data.start_addr; TempData = (modbus_analysis_data.write_data_addr[0] << 8) | modbus_analysis_data.write_data_addr[1]; error_code = proto_modbus_data_write(TempAddr, TempData); if (error_code) { goto Error; } send_struct.len = send_buff_index_offset + 6; send_struct.send_buffer[send_buff_index_offset + 0] = modbus_analysis_data.id; send_struct.send_buffer[send_buff_index_offset + 1] = modbus_analysis_data.func; send_struct.send_buffer[send_buff_index_offset + 2] = modbus_analysis_data.start_addr >> 8; send_struct.send_buffer[send_buff_index_offset + 3] = modbus_analysis_data.start_addr & 0xff; send_struct.send_buffer[send_buff_index_offset + 4] = modbus_analysis_data.write_data_addr[0]; send_struct.send_buffer[send_buff_index_offset + 5] = modbus_analysis_data.write_data_addr[1]; }break; case 0x10: { TempAddr = modbus_analysis_data.start_addr; for (inx = 0; inx < modbus_analysis_data.reg_number; inx++) { TempData = modbus_analysis_data.write_data_addr[2 * inx]; TempData = (TempData << 8) | modbus_analysis_data.write_data_addr[2 * inx + 1]; error_code = proto_modbus_data_write(TempAddr, TempData); TempAddr++; if (error_code) { goto Error; } } send_struct.len = send_buff_index_offset + 6; send_struct.send_buffer[0] = modbus_analysis_data.id; send_struct.send_buffer[1] = modbus_analysis_data.func; send_struct.send_buffer[2] = modbus_analysis_data.start_addr >> 8; send_struct.send_buffer[3] = modbus_analysis_data.start_addr & 0xff; send_struct.send_buffer[4] = modbus_analysis_data.reg_number >> 8; send_struct.send_buffer[5] = modbus_analysis_data.reg_number & 0xff; } break; default: { error_code = ModbusErrorCode_IllegalFunction; } goto Error; } Success: send_struct.send_buffer[4] = (send_struct.len - send_buff_index_offset) >> 8; send_struct.send_buffer[5] = (send_struct.len - send_buff_index_offset) & 0x00ff; proto_modbus_communication_data_send(send_struct.send_buffer, send_struct.len); return; Error: send_struct.len = send_buff_index_offset + 3; send_struct.send_buffer[0] = modbus_analysis_data.id; send_struct.send_buffer[1] = modbus_analysis_data.func | 0x80; send_struct.send_buffer[2] = error_code; send_struct.send_buffer[4] = (send_struct.len - send_buff_index_offset) >> 8; send_struct.send_buffer[5] = (send_struct.len - send_buff_index_offset) & 0x00ff; proto_modbus_communication_data_send(send_struct.send_buffer, send_struct.len); } /****************************************** * 函数: proto_modbus_data_write * 功能: Modbus写寄存器 * 参数: Addr: 地址 Value:数据 * 返回: 无 * 描述: 无 ******************************************/ static modbus_error_code_e proto_modbus_data_write(u16 addr, u16 data) { modbus_error_code_e error_code; u8 temp_point,cali_point; error_code = ModbusErrorCode_Success; switch(addr) { // case 1 ... 4: // { // relay.set(addr-1,data); // }break; // // /*sn*/ // case 20000 ... 20004: // { // Usr_Flash.FlashData.sn[addr - 20000] = data; // Usr_Flash.Write(); // }break; // /*modbus_id*/ // case 20005: // { // Usr_Flash.FlashData.modbus_id = data; // modbus_slave_ex.id = Usr_Flash.FlashData.modbus_id; // Usr_Flash.Write(); // }break; } return error_code; } /****************************************** * 函数: proto_modbus_data_read * 功能: Modbus读寄存器数据 * 参数: Addr: 地址 * 返回: 地址对应的数据 * 描述: 无 ******************************************/ static u16 proto_modbus_data_read(u16 addr) { u16 data = 0; u16 *p_data; u16 num,offset; u16 sensor_index,sensor_ch,reg; u16 *p_string; switch(addr) { case 0 ... 607: { sensor_index = addr / 19; /*哪一个传光强*/ reg = addr % 19; /*哪一个数据*/ switch(reg) { case 0:/*端口&ID*/ { data = (leakage.sub_device_data[sensor_index].flash_data.com + 1)<< 8 | leakage.sub_device_data[sensor_index].flash_data.modbus_id; }break; case 1 ... 5:/*区域名*/ { p_string = (u16 *)leakage.sub_device_data[sensor_index].flash_data.region_name; data = p_string[reg - 1]>> 8 | p_string[reg - 1] << 8; }break; case 6 ... 10:/*设备名*/ { p_string = (u16 *)leakage.sub_device_data[sensor_index].flash_data.device_name; data = p_string[reg - 6]>> 8 | p_string[reg - 6] << 8; }break; case 11 ... 18:/*通道数据*/ { sensor_ch = (addr - 11) / 2; if( (addr - 11) & 0x0001) /*漏液位置*/ { data = leakage.sub_device_data[sensor_index].ch_data[sensor_ch].distance; } else /*设备状态*/ { data = leakage.sub_device_data[sensor_index].ch_data[sensor_ch].state; } }break; default:data = 0; } }break; default:data = 0; } return data; }