#include "proto_Para_Modbus.h" #include "string.h" #include "bsp_Uart.h" #include "os_timer.h" #include "stdio.h" #include "test_echo.h" #include "app.h" #include "bsp_W5500.h" #include "bsp_W5500_1.h" #include "proto_HSMS.h" #include "bsp_Flash.h" #include "bsp_Wdg.h" #include "bsp_DS1302.h" static ModbusAnalysisData_t ModbusAnalysisData;//指令解析结构体 static ModbusCommunicationSendBuf_t SendStruct;//发送结构体 static void ModbusCommunicationDataReceive(u8 *pData, u16 len,void *other_data); static void ModbusCommunicationDataSend(u8 *pData, u16 len); static void proto_Modbus_Init(void); static void proto_Modbus_Task(void); static ModbusErrorCode_e ModbusCommunicationDataWrite(u16 Addr, u16 Value); static u16 ModbusCommunicationDataRead(u16 Addr); proto_Modbus_t Para_Modbus= { .ID = 0x01, .DataRead = ModbusCommunicationDataRead, .DataWrite = ModbusCommunicationDataWrite, .DataAnalysis = ModbusCommunicationDataReceive, .Init = proto_Modbus_Init, .Task = proto_Modbus_Task, }; static proto_Modbus_t *pModbus = &Para_Modbus; static bsp_Uart_t *rx_uart = NULL; static void ModbusCommunicationDataSend(u8 *pData, u16 Len) { if(&COM_Uart1 == rx_uart) { COM_Uart1.Send(&COM_Uart1,pData,Len); } else if(&COM_Uart2 == rx_uart) { COM_Uart2.Send(&COM_Uart2,pData,Len); } } static void proto_Modbus_Init(void) { COM_Uart1.Rx_DataAnalysis = ModbusCommunicationDataReceive; COM_Uart2.Rx_DataAnalysis = ModbusCommunicationDataReceive; } static void proto_Modbus_Task(void) { } static void ModbusCommunicationDataReceive(u8 *pData, u16 len,void *other_data) { ModbusErrorCode_e ErrorCode; u8 inx; u16 TempAddr, TempData, Crc16; if (0 == ModbusAnalysis(&ModbusAnalysisData, pData, len))//检查数据长度 校验是否正确 return; if (pModbus->ID != ModbusAnalysisData.ID)//判断ID是否正确 return; ErrorCode = ModbusErrorCode_Success; rx_uart = (bsp_Uart_t *)other_data; /* //检查地址是否超出范围 if ((ModbusAnalysisData.StartAddress >= MODBUS_REG_LEN) || (ModbusAnalysisData.RegNumber >= MODBUS_REG_LEN) || (ModbusAnalysisData.StartAddress + ModbusAnalysisData.RegNumber >= MODBUS_REG_LEN)) { ErrorCode = ModbusErrorCode_IllegalAddr; goto Error; } */ switch (ModbusAnalysisData.Func) { case 0x03: case 0x04: { TempAddr = ModbusAnalysisData.StartAddress; SendStruct.SendBuffer[0] = ModbusAnalysisData.ID; SendStruct.SendBuffer[1] = ModbusAnalysisData.Func; SendStruct.SendBuffer[2] = 2 * ModbusAnalysisData.RegNumber; for (inx = 0; inx < ModbusAnalysisData.RegNumber; inx++) { TempData = ModbusCommunicationDataRead(TempAddr); SendStruct.SendBuffer[3 + 2 * inx] = (TempData >> 8) & 0xff; SendStruct.SendBuffer[4 + 2 * inx] = TempData & 0xff; TempAddr++; } Crc16 = ModbusCrc16(SendStruct.SendBuffer, 3 + SendStruct.SendBuffer[2]); SendStruct.SendBuffer[3 + SendStruct.SendBuffer[2]] = Crc16 & 0xff; SendStruct.SendBuffer[4 + SendStruct.SendBuffer[2]] = (Crc16 >> 8) & 0xff; SendStruct.Len = 5 + SendStruct.SendBuffer[2]; }goto Success; /*特殊协议*/ case 0x41: { TempAddr = ModbusAnalysisData.StartAddress; SendStruct.SendBuffer[0] = ModbusAnalysisData.ID; SendStruct.SendBuffer[1] = ModbusAnalysisData.Func; SendStruct.SendBuffer[2] = ModbusAnalysisData.StartAddress >> 8; SendStruct.SendBuffer[3] = ModbusAnalysisData.StartAddress & 0xff; SendStruct.SendBuffer[4] = (2 * ModbusAnalysisData.RegNumber) >> 8; SendStruct.SendBuffer[5] = (2 * ModbusAnalysisData.RegNumber) & 0xff; for (inx = 0; inx < ModbusAnalysisData.RegNumber; inx++) { TempData = ModbusCommunicationDataRead(TempAddr); SendStruct.SendBuffer[6 + 2 * inx] = (TempData >> 8) & 0xff; SendStruct.SendBuffer[7 + 2 * inx] = TempData & 0xff; TempAddr++; } Crc16 = ModbusCrc16(SendStruct.SendBuffer, 6 + 2 * ModbusAnalysisData.RegNumber); SendStruct.SendBuffer[6 + 2 * ModbusAnalysisData.RegNumber] = Crc16 & 0xff; SendStruct.SendBuffer[7 + 2 * ModbusAnalysisData.RegNumber] = (Crc16 >> 8) & 0xff; SendStruct.Len = 8 + 2 * ModbusAnalysisData.RegNumber; }goto Success; case 0x06: { TempAddr = ModbusAnalysisData.StartAddress; TempData = (ModbusAnalysisData.wDataAddress[0] << 8) | ModbusAnalysisData.wDataAddress[1]; ErrorCode = ModbusCommunicationDataWrite(TempAddr, TempData); if (ErrorCode) { goto Error; } SendStruct.Len = 8; SendStruct.SendBuffer[0] = ModbusAnalysisData.ID; SendStruct.SendBuffer[1] = ModbusAnalysisData.Func; SendStruct.SendBuffer[2] = ModbusAnalysisData.StartAddress >> 8; SendStruct.SendBuffer[3] = ModbusAnalysisData.StartAddress & 0xff; SendStruct.SendBuffer[4] = ModbusAnalysisData.wDataAddress[0]; SendStruct.SendBuffer[5] = ModbusAnalysisData.wDataAddress[1]; Crc16 = ModbusCrc16(SendStruct.SendBuffer, 6); SendStruct.SendBuffer[6] = Crc16 & 0xff; SendStruct.SendBuffer[7] = (Crc16 >> 8) & 0xff; }break; case 0x10: { TempAddr = ModbusAnalysisData.StartAddress; for (inx = 0; inx < ModbusAnalysisData.RegNumber; inx++) { TempData = ModbusAnalysisData.wDataAddress[2 * inx]; TempData = (TempData << 8) | ModbusAnalysisData.wDataAddress[2 * inx + 1]; ErrorCode = ModbusCommunicationDataWrite(TempAddr, TempData); TempAddr++; if (ErrorCode) { goto Error; } } SendStruct.Len = 8; SendStruct.SendBuffer[0] = ModbusAnalysisData.ID; SendStruct.SendBuffer[1] = ModbusAnalysisData.Func; SendStruct.SendBuffer[2] = ModbusAnalysisData.StartAddress >> 8; SendStruct.SendBuffer[3] = ModbusAnalysisData.StartAddress & 0xff; SendStruct.SendBuffer[4] = ModbusAnalysisData.RegNumber >> 8; SendStruct.SendBuffer[5] = ModbusAnalysisData.RegNumber & 0xff; Crc16 = ModbusCrc16(SendStruct.SendBuffer, 6); SendStruct.SendBuffer[6] = Crc16 & 0xff; SendStruct.SendBuffer[7] = (Crc16 >> 8) & 0xff; } break; default: { ErrorCode = ModbusErrorCode_IllegalFunction; } goto Error; } Success: ModbusCommunicationDataSend(SendStruct.SendBuffer, SendStruct.Len); return; Error: SendStruct.Len = 5; SendStruct.SendBuffer[0] = ModbusAnalysisData.ID; SendStruct.SendBuffer[1] = ModbusAnalysisData.Func | 0x80; SendStruct.SendBuffer[2] = ErrorCode; Crc16 = ModbusCrc16(SendStruct.SendBuffer, 3); SendStruct.SendBuffer[3] = Crc16 & 0xff; SendStruct.SendBuffer[4] = (Crc16 >> 8) & 0xff; ModbusCommunicationDataSend(SendStruct.SendBuffer, SendStruct.Len); } /*modbus接收到的u16转换为ascii的u16 实际为对调高低字节*/ static u16 modbus_u16_to_ascii_u16(u16 modbus_u16) { return (modbus_u16 << 8) | (modbus_u16 >> 8); } /*ascii的u16 转换为modbus u16发送 实际为对调高低字节*/ static u16 ascii_u16_to_modbus_u16(u16 modbus_u16) { return (modbus_u16 << 8) | (modbus_u16 >> 8); } /****************************************** * 函数: ModbusCommunicationDataWrite * 功能: Modbus写寄存器 * 参数: Addr: 地址 Value:数据 * 返回: 无 * 描述: 无 ******************************************/ static ModbusErrorCode_e ModbusCommunicationDataWrite(u16 Addr, u16 Value) { ModbusErrorCode_e ErrorCode; ErrorCode = ModbusErrorCode_Success; switch(Addr) { /*SN*/ case 12 ... 21: { Usr_Flash.FlashData.SN[Addr - 12] = Value; Usr_Flash.Write(); }break; /*IP地址*/ case 22 ... 25: { W5500.IP_Addr[Addr - 22] = Value; Usr_Flash.FlashData.IP_Addr[Addr - 22] = Value; }break; /*端口号*/ case 26: { W5500.W5500_Class[0].ConfigData.Port[0] = Value >> 8; W5500.W5500_Class[0].ConfigData.Port[1] = Value & 0x00ff; Usr_Flash.FlashData.Port[0] = Value >> 8; Usr_Flash.FlashData.Port[1] = Value & 0x00ff; }break; /*子网掩码*/ case 27 ... 30: { W5500.Sub_Mask[Addr - 27] = Value; Usr_Flash.FlashData.Sub_Mask[Addr - 27] = Value; }break; case 31: { HSMS.Flash_ConfigData.Device_Id = Value; Usr_Flash.FlashData.Devic_Id = Value; }break; /* 网关设置*/ case 32 ... 35: { W5500.Gateway_IP[Addr - 32] = Value; Usr_Flash.FlashData.Gateway_IP[Addr - 32] = Value; Wdg.Feed(); W5500.Init(); Wdg.Feed(); Usr_Flash.Write(); } break; /*时间设置*/ case 36: { DS1302.Time.Year = Value % 2000; }break; case 37: { DS1302.Time.Month = Value; }break; case 38: { DS1302.Time.Day = Value; }break; case 39: { DS1302.Time.Hour = Value; }break; case 40: { DS1302.Time.Minute = Value; }break; case 41: { DS1302.Time.Second = Value; DS1302.Set(&DS1302.Time); }break; case 42 ... 45: { W5500_1.IP_Addr[Addr - 42] = Value; Usr_Flash.FlashData.IP_Addr_1[Addr - 42] = Value; }break; case 46: { W5500_1.W5500_Class[0].ConfigData.Port[0] = Value >> 8; W5500_1.W5500_Class[0].ConfigData.Port[1] = Value & 0x00ff; Usr_Flash.FlashData.Port_1[0] = Value >> 8; Usr_Flash.FlashData.Port_1[1] = Value & 0x00ff; }break; case 47 ... 50: { W5500_1.Sub_Mask[Addr - 47] = Value; Usr_Flash.FlashData.Sub_Mask_1[Addr - 47] = Value; }break; case 51 ... 54: { W5500_1.Gateway_IP[Addr - 51] = Value; Usr_Flash.FlashData.Gateway_IP_1[Addr - 51] = Value; Wdg.Feed(); W5500_1.Init(); Wdg.Feed(); Usr_Flash.Write(); }break; case 55 ... 58: { W5500_1.W5500_Class[0].ConfigData.DIP[Addr - 55] = Value; Usr_Flash.FlashData.IP_Addr_2[Addr - 55] = Value; }break; case 59: { W5500_1.W5500_Class[0].ConfigData.DPort[0] = Value >> 8; W5500_1.W5500_Class[0].ConfigData.DPort[1] = Value & 0x00ff; Usr_Flash.FlashData.Port_2[0] = Value >> 8; Usr_Flash.FlashData.Port_2[1] = Value & 0x00ff; Wdg.Feed(); W5500_1.Init(); Wdg.Feed(); Usr_Flash.Write(); } /* 设备 SN */ case 100 ... 111: { Usr_Flash.FlashData.Device_SN[Addr - 100] = modbus_u16_to_ascii_u16(Value); Usr_Flash.Write(); } break; /* 机台和位置(Device_Model) */ case 112 ... 123: { Usr_Flash.FlashData.Device_Model[Addr - 112] = modbus_u16_to_ascii_u16(Value); Usr_Flash.Write(); } break; /* 设备类型(Station_Type) */ case 124 ... 135: { Usr_Flash.FlashData.Station_Type[Addr - 124] = modbus_u16_to_ascii_u16(Value); Usr_Flash.Write(); } break; /* 设备型号(Device_ID) */ case 136 ... 147: { Usr_Flash.FlashData.Device_ID[Addr - 136] = modbus_u16_to_ascii_u16(Value); Usr_Flash.Write(); } break; /* 软件版本(Version) */ case 148 ... 159: { Usr_Flash.FlashData.Version[Addr - 148] = modbus_u16_to_ascii_u16(Value); Usr_Flash.Write(); } break; /* 厂商名称(Manufacturer) */ case 160 ... 171: { Usr_Flash.FlashData.Manufacturer[Addr - 160] = modbus_u16_to_ascii_u16(Value); Usr_Flash.Write(); } break; /* 机台名称(Station_Name) */ case 172 ... 183: { Usr_Flash.FlashData.Station_Name[Addr - 172] = modbus_u16_to_ascii_u16(Value); Usr_Flash.Write(); } break; /* 腔体名称(Chamber_Name) */ case 184 ... 195: { Usr_Flash.FlashData.Chamber_Name[Addr - 184] = modbus_u16_to_ascii_u16(Value); Usr_Flash.Write(); } break; /* ========== 后续参数顺延 ========== */ /* Alarm_info (20个) */ case 196 ... 215: { Usr_Flash.FlashData.Alarm_info[Addr - 196] = Value; Usr_Flash.Write(); } break; /* Data_ID1 */ case 216: { Usr_Flash.FlashData.Data_ID1 = Value; Usr_Flash.Write(); } break; /* Collection_event_ID1 */ case 217: { Usr_Flash.FlashData.Collection_event_ID1 = Value; Usr_Flash.Write(); } break; /* Report_ID1 */ case 218: { Usr_Flash.FlashData.Report_ID1 = Value; Usr_Flash.Write(); } break; /* Alarm_ID */ case 219: { Usr_Flash.FlashData.Alarm_ID = Value; Usr_Flash.Write(); } break; /* Alarm_Type (7个) */ case 220 ... 226: { Usr_Flash.FlashData.Alarm_Type[Addr - 220] = Value; Usr_Flash.Write(); } break; /* Begin_Warning (7个) */ case 227 ... 233: { Usr_Flash.FlashData.Begin_Warning[Addr - 227] = Value; Usr_Flash.Write(); } break; /* IDS (11个) */ case 234 ... 244: { Usr_Flash.FlashData.IDS[Addr - 234] = Value; Usr_Flash.Write(); } break; /* Over_Trigger (9个) */ case 245 ... 253: { Usr_Flash.FlashData.Over_Trigger[Addr - 245] = Value; Usr_Flash.Write(); } break; /* Equipment (5个) */ case 254 ... 258: { Usr_Flash.FlashData.Equipment[Addr - 254] = Value; Usr_Flash.Write(); } break; /* E9 (19个) */ case 259 ... 277: { Usr_Flash.FlashData.E9[Addr - 259] = Value; Usr_Flash.Write(); } break; /* Device_Type */ case 278: { Usr_Flash.FlashData.Device_Type = Value; Usr_Flash.Write(); } break; /* Sensor */ case 279: { Usr_Flash.FlashData.Sensor = Value; Usr_Flash.Write(); } break; /* Alarm_value */ case 280: { Usr_Flash.FlashData.Alarm_value = Value; Usr_Flash.Write(); } break; /* Alarm_ubit */ case 281: { Usr_Flash.FlashData.Alarm_ubit = Value; Usr_Flash.Write(); } break; /* Start_Time (11个) */ case 282 ... 292: { Usr_Flash.FlashData.Start_Time[Addr - 282] = Value; Usr_Flash.Write(); } break; /* Alarm_Time (6个) */ case 293 ... 298: { Usr_Flash.FlashData.Alarm_Time[Addr - 293] = Value; Usr_Flash.Write(); } break; /* Alarm (6个) */ case 299 ... 304: { Usr_Flash.FlashData.Alarm[Addr - 299] = Value; Usr_Flash.Write(); } break; /* Data_ID2 */ case 305: { Usr_Flash.FlashData.Data_ID2 = Value; Usr_Flash.Write(); } break; /* Collection_event_ID2 */ case 306: { Usr_Flash.FlashData.Collection_event_ID2 = Value; Usr_Flash.Write(); } break; /* Report_ID2 */ case 307: { Usr_Flash.FlashData.Report_ID2 = Value; Usr_Flash.Write(); } break; /* Sub_Device_Type (2个) */ case 308 ... 309: { Usr_Flash.FlashData.Sub_Device_Type[Addr - 308] = Value; Usr_Flash.Write(); } break; /* Sub_Device_State (2个) */ case 310 ... 311: { Usr_Flash.FlashData.Sub_Device_State[Addr - 310] = Value; Usr_Flash.Write(); } break; /* State_Change_Time (2个) */ case 312 ... 313: { Usr_Flash.FlashData.State_Change_Time[Addr - 312] = Value; Usr_Flash.Write(); } break; case 1000: // 测试开关 { Usr_Flash.test = Value; Usr_Flash.Write(); test_echo_switch(Usr_Flash.test); } break; } return ErrorCode; } /****************************************** * 函数: ModbusCommunicationDataRead * 功能: Modbus读寄存器数据 * 参数: Addr: 地址 * 返回: 地址对应的数据 * 描述: 无 ******************************************/ static u16 ModbusCommunicationDataRead(u16 Addr) { u8 *p_u8Data; u16 Data; u16 *pData; switch(Addr) { /*SV*/ case 0 ... 11: { p_u8Data = &SwVersion[Addr * 2]; Data = p_u8Data[1] | p_u8Data[0] << 8; }break; /*SN*/ case 12 ... 21: { Data = Usr_Flash.FlashData.SN[Addr - 12]; }break; /*IP地址*/ case 22 ... 25: { Data = W5500.IP_Addr[Addr - 22]; }break; /*端口号*/ case 26: { Data = W5500.W5500_Class[0].ConfigData.Port[0] << 8 | W5500.W5500_Class[0].ConfigData.Port[1]; }break; /*子网掩码*/ case 27 ... 30: { Data = W5500.Sub_Mask[Addr - 27]; }break; /*SECS2协议设备ID*/ case 31: { Data = HSMS.Flash_ConfigData.Device_Id; }break; /* 网关*/ case 32 ... 35: { Data = W5500.Gateway_IP[Addr - 32]; } break; /*时间*/ case 36: { Data = (DS1302.Time.Year) + 2000; }break; case 37: { Data = DS1302.Time.Month; }break; case 38: { Data = DS1302.Time.Day; }break; case 39: { Data = DS1302.Time.Hour; }break; case 40: { Data = DS1302.Time.Minute; }break; case 41: { Data = DS1302.Time.Second; }break; case 42 ... 45: { Data = W5500_1.IP_Addr[Addr - 42]; }break; case 46: { Data = W5500_1.W5500_Class[0].ConfigData.Port[0] << 8 | W5500_1.W5500_Class[0].ConfigData.Port[1]; }break; case 47 ... 50: { Data = W5500_1.Sub_Mask[Addr - 47]; }break; case 51 ... 54: { Data = W5500_1.Gateway_IP[Addr - 51]; }break; case 55 ... 58: { Data = W5500_1.W5500_Class[0].ConfigData.DIP[Addr - 55]; }break; case 59: { Data = W5500_1.W5500_Class[0].ConfigData.DPort[0] << 8 | W5500_1.W5500_Class[0].ConfigData.DPort[1]; }break; /* ========== 字符串字段(每个12个寄存器) ========== */ /* 设备 SN */ case 100 ... 111: { Data = Usr_Flash.FlashData.Device_SN[Addr - 100]; Data = ascii_u16_to_modbus_u16(Data); } break; /* 机台和位置(Device_Model) */ case 112 ... 123: { Data = Usr_Flash.FlashData.Device_Model[Addr - 112]; Data = ascii_u16_to_modbus_u16(Data); } break; /* 设备类型(Station_Type) */ case 124 ... 135: { Data = Usr_Flash.FlashData.Station_Type[Addr - 124]; Data = ascii_u16_to_modbus_u16(Data); } break; /* 设备型号(Device_ID) */ case 136 ... 147: { Data = Usr_Flash.FlashData.Device_ID[Addr - 136]; Data = ascii_u16_to_modbus_u16(Data); } break; /* 软件版本(Version) */ case 148 ... 159: { Data = Usr_Flash.FlashData.Version[Addr - 148]; Data = ascii_u16_to_modbus_u16(Data); } break; /* 厂商名称(Manufacturer) */ case 160 ... 171: { Data = Usr_Flash.FlashData.Manufacturer[Addr - 160]; Data = ascii_u16_to_modbus_u16(Data); } break; /* 机台名称(Station_Name) */ case 172 ... 183: { Data = Usr_Flash.FlashData.Station_Name[Addr - 172]; Data = ascii_u16_to_modbus_u16(Data); } break; /* 腔体名称(Chamber_Name) */ case 184 ... 195: { Data = Usr_Flash.FlashData.Chamber_Name[Addr - 184]; Data = ascii_u16_to_modbus_u16(Data); } break; /* ========== 后续参数顺延 ========== */ /* Alarm_info (20个) */ case 196 ... 215: { Data = Usr_Flash.FlashData.Alarm_info[Addr - 196]; } break; /* Data_ID1 */ case 216: { Data = Usr_Flash.FlashData.Data_ID1; } break; /* Collection_event_ID1 */ case 217: { Data = Usr_Flash.FlashData.Collection_event_ID1; } break; /* Report_ID1 */ case 218: { Data = Usr_Flash.FlashData.Report_ID1; } break; /* Alarm_ID */ case 219: { Data = Usr_Flash.FlashData.Alarm_ID; } break; /* Alarm_Type (7个) */ case 220 ... 226: { Data = Usr_Flash.FlashData.Alarm_Type[Addr - 220]; } break; /* Begin_Warning (7个) */ case 227 ... 233: { Data = Usr_Flash.FlashData.Begin_Warning[Addr - 227]; } break; /* IDS (11个) */ case 234 ... 244: { Data = Usr_Flash.FlashData.IDS[Addr - 234]; } break; /* Over_Trigger (9个) */ case 245 ... 253: { Data = Usr_Flash.FlashData.Over_Trigger[Addr - 245]; } break; /* Equipment (5个) */ case 254 ... 258: { Data = Usr_Flash.FlashData.Equipment[Addr - 254]; } break; /* E9 (19个) */ case 259 ... 277: { Data = Usr_Flash.FlashData.E9[Addr - 259]; } break; /* Device_Type */ case 278: { Data = Usr_Flash.FlashData.Device_Type; } break; /* Sensor */ case 279: { Data = Usr_Flash.FlashData.Sensor; } break; /* Alarm_value */ case 280: { Data = Usr_Flash.FlashData.Alarm_value; } break; /* Alarm_ubit */ case 281: { Data = Usr_Flash.FlashData.Alarm_ubit; } break; /* Start_Time (11个) */ case 282 ... 292: { Data = Usr_Flash.FlashData.Start_Time[Addr - 282]; } break; /* Alarm_Time (6个) */ case 293 ... 298: { Data = Usr_Flash.FlashData.Alarm_Time[Addr - 293]; } break; /* Alarm (6个) */ case 299 ... 304: { Data = Usr_Flash.FlashData.Alarm[Addr - 299]; } break; /* Data_ID2 */ case 305: { Data = Usr_Flash.FlashData.Data_ID2; } break; /* Collection_event_ID2 */ case 306: { Data = Usr_Flash.FlashData.Collection_event_ID2; } break; /* Report_ID2 */ case 307: { Data = Usr_Flash.FlashData.Report_ID2; } break; /* Sub_Device_Type (2个) */ case 308 ... 309: { Data = Usr_Flash.FlashData.Sub_Device_Type[Addr - 308]; } break; /* Sub_Device_State (2个) */ case 310 ... 311: { Data = Usr_Flash.FlashData.Sub_Device_State[Addr - 310]; } break; /* State_Change_Time (2个) */ case 312 ... 313: { Data = Usr_Flash.FlashData.State_Change_Time[Addr - 312]; } break; case 1000: { Data = Usr_Flash.test; } break; default: Data = 0; } return Data; }