/*对外通讯 modbus从机*/ #include "proto_modbus_slave_ex.h" #include "string.h" #include "stdio.h" #include "app.h" #include "os_timer.h" #include "bsp_Uart.h" #include "bsp_Flash.h" #include "proto_print.h" #include "proto_modbus_master_tdlas.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; static bsp_Uart_t * rx_uart; static void proto_modbus_communication_data_send(u8 *pData, u16 len) { if(&COM_Uart1 == rx_uart) { COM_Uart1.Send(&COM_Uart1,pData,len); } else if(&COM_Uart4 == rx_uart) { COM_Uart4.Send(&COM_Uart4,pData,len); } } static void proto_modbus_init(void) { p_modbus->id = Usr_Flash.FlashData.modbus_id; COM_Uart1.Rx_DataAnalysis = proto_modbus_communication_data_analysis; COM_Uart4.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; if (0 == modbus_lib_analysis(&modbus_analysis_data, pData, len))//检查数据长度 校验是否正确 return; if (p_modbus->id != modbus_analysis_data.id && modbus_analysis_data.id != 0xe8)//判断ID是否正确 return; 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; } */ rx_uart = (bsp_Uart_t*)other_data; switch (modbus_analysis_data.func) { case 0x03: case 0x04: { TempAddr = modbus_analysis_data.start_addr; send_struct.send_buffer[0] = modbus_analysis_data.id; send_struct.send_buffer[1] = modbus_analysis_data.func; send_struct.send_buffer[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[3 + 2 * inx] = (TempData >> 8) & 0xff; send_struct.send_buffer[4 + 2 * inx] = TempData & 0xff; TempAddr++; } crc_16 = modbus_lib_crc16(send_struct.send_buffer, 3 + send_struct.send_buffer[2]); send_struct.send_buffer[3 + send_struct.send_buffer[2]] = crc_16 & 0xff; send_struct.send_buffer[4 + send_struct.send_buffer[2]] = (crc_16 >> 8) & 0xff; send_struct.len = 5 + send_struct.send_buffer[2]; }goto Success; /*特殊协议*/ case 0x41: { TempAddr = modbus_analysis_data.start_addr; 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] = (2 * modbus_analysis_data.reg_number) >> 8; send_struct.send_buffer[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[6 + 2 * inx] = (TempData >> 8) & 0xff; send_struct.send_buffer[7 + 2 * inx] = TempData & 0xff; TempAddr++; } crc_16 = modbus_lib_crc16(send_struct.send_buffer, 6 + 2 * modbus_analysis_data.reg_number); send_struct.send_buffer[6 + 2 * modbus_analysis_data.reg_number] = crc_16 & 0xff; send_struct.send_buffer[7 + 2 * modbus_analysis_data.reg_number] = (crc_16 >> 8) & 0xff; send_struct.len = 8 + 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 = 8; 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.write_data_addr[0]; send_struct.send_buffer[5] = modbus_analysis_data.write_data_addr[1]; crc_16 = modbus_lib_crc16(send_struct.send_buffer, 6); send_struct.send_buffer[6] = crc_16 & 0xff; send_struct.send_buffer[7] = (crc_16 >> 8) & 0xff; }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 = 8; 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; crc_16 = modbus_lib_crc16(send_struct.send_buffer, 6); send_struct.send_buffer[6] = crc_16 & 0xff; send_struct.send_buffer[7] = (crc_16 >> 8) & 0xff; } break; default: { error_code = ModbusErrorCode_IllegalFunction; } goto Error; } Success: proto_modbus_communication_data_send(send_struct.send_buffer, send_struct.len); return; Error: send_struct.len = 5; 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; crc_16 = modbus_lib_crc16(send_struct.send_buffer, 3); send_struct.send_buffer[3] = crc_16 & 0xff; send_struct.send_buffer[4] = (crc_16 >> 8) & 0xff; 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 11000: { tdlas.control.fac_calib_para_set(*((u16 *)(&data)),0xffff,0xffff); }break; case 11001: { tdlas.control.fac_calib_para_set(0xffff,data,0xffff); }break; case 11002: { tdlas.control.fac_calib_para_set(0xffff,0xffff,data); }break; /*零点校准*/ case 11003: { tdlas.control.zero_calib(0); }break; /*量程点校准*/ case 11004: { tdlas.control.span_calib(data); }break; /*厂家标定*/ case 11010 ... 11109: { temp_point = (addr - 11010) / 10; cali_point = (addr - 11010) % 10; tdlas.control.fac_calib(data,cali_point,temp_point); }break; /*转发传感器标定信息*/ case 11200: { tdlas.control.fac_calib_data_get(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; /*modbus_read_reg_num*/ case 20006: { if(data > 1000) { error_code = ModbusErrorCode_IllegalData; } else { Usr_Flash.FlashData.modbus_read_reg_num = data; Usr_Flash.Write(); } }break; case 20007: { if(data > 16) { error_code = ModbusErrorCode_IllegalData; } else { Usr_Flash.FlashData.modbus_read_sensor_num = data; Usr_Flash.Write(); } }break; /*FC打印相关数据*/ case 252: { print.set(data); }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; switch(addr) { /*实时数据*/ case 0 ... 639: { u16 size; size = sizeof(gas_data_t); /* TDLAS默认读取*/ if( size== (2 * Usr_Flash.FlashData.modbus_read_reg_num)) { p_data = (u16 *)&gas_data; data = p_data[addr]; } else if((2 * Usr_Flash.FlashData.modbus_read_reg_num )< sizeof(gas_data_t))/*其他传感器*/ { num = addr / Usr_Flash.FlashData.modbus_read_reg_num; offset = addr % Usr_Flash.FlashData.modbus_read_reg_num; p_data = (u16 *)&gas_data[num]; data = p_data[offset]; } }break; /*sn*/ case 20000 ... 20004: { data = Usr_Flash.FlashData.sn[addr - 20000]; }break; /*modbus_id*/ case 20005: { data = Usr_Flash.FlashData.modbus_id; }break; /*modbus_read_reg_num*/ case 20006: { data = Usr_Flash.FlashData.modbus_read_reg_num; }break; case 20007: { data = Usr_Flash.FlashData.modbus_read_sensor_num; }break; default:data = 0; } return data; }