using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace OmronFinsTCP.Net { class FinsClass { /// /// 获取内存区码 /// /// 寄存器类型 /// 地址类型 /// private static byte GetMemoryCode(PlcMemory mr, MemoryType mt) { if (mt == MemoryType.Bit) { switch (mr) { case PlcMemory.CIO: return 0x30; case PlcMemory.WR: return 0x31; case PlcMemory.HR: return 0x32; case PlcMemory.AR: return 0x33; case PlcMemory.DM: return 0x02; default: return 0x00; } } else { switch (mr) { case PlcMemory.CIO: return 0xB0; case PlcMemory.WR: return 0xB1; case PlcMemory.HR: return 0xB2; case PlcMemory.AR: return 0xB3; case PlcMemory.DM: return 0x82; default: return 0x00; } } } /// /// PC请求连接的握手信号,第一次连接会分配PC节点号 /// /// internal static byte[] HandShake() { #region fins command byte[] array = new byte[20]; array[0] = 0x46; array[1] = 0x49; array[2] = 0x4E; array[3] = 0x53; array[4] = 0; array[5] = 0; array[6] = 0; array[7] = 0x0C; array[8] = 0; array[9] = 0; array[10] = 0; array[11] = 0; array[12] = 0; array[13] = 0; array[14] = 0; array[15] = 0;//ERR? array[16] = 0; array[17] = 0; array[18] = 0; array[19] = 0;//TODO:ask for client and server node number, the client node will allocated automatically //array[19] = this.GetIPNode(lIP);//本机IP地址的末位 #endregion fins command return array; } /// /// Fins读写指令生成 /// /// 读写类型 /// 寄存器类型 /// 地址类型 /// 起始地址 /// 位地址:00-15,字地址则为00 /// 地址个数,按位读写只能是1 /// internal static byte[] FinsCmd(RorW rw, PlcMemory mr, MemoryType mt, short ch, short offset, short cnt) { //byte[] array; //if (rw == RorW.Read) // array = new byte[34]; //else // array = new byte[(int)(cnt * 2 + 33 + 1)];//长度是如何确定的在fins协议174页 byte[] array = new byte[34];//写指令还有后面的写入数组需要拼接在一起! //TCP FINS header array[0] = 0x46;//F array[1] = 0x49;//I array[2] = 0x4E;//N array[3] = 0x53;//S array[4] = 0;//cmd length array[5] = 0; //指令长度从下面字节开始计算array[8] if (rw == RorW.Read) { array[6] = 0; array[7] = 0x1A;//26 } else { //写数据的时候一个字占两个字节,而一个位只占一个字节 if (mt == MemoryType.Word) { array[6] = (byte)((cnt * 2 + 26) / 256); array[7] = (byte)((cnt * 2 + 26) % 256); } else { array[6] = 0; array[7] = 0x1B; } } array[8] = 0;//frame command array[9] = 0; array[10] = 0; array[11] = 0x02; array[12] = 0;//err array[13] = 0; array[14] = 0; array[15] = 0; //command frame header array[16] = 0x80;//ICF array[17] = 0x00;//RSV array[18] = 0x02;//GCT, less than 8 network layers array[19] = 0x00;//DNA, local network array[20] = BasicClass.plcNode;//DA1 array[21] = 0x00;//DA2, CPU unit array[22] = 0x00;//SNA, local network array[23] = BasicClass.pcNode;//SA1 array[24] = 0x00;//SA2, CPU unit array[25] = 0xFF; //TODO:array[25] = Convert.ToByte(21);//SID//?????----------------------------------00-FF任意值 //指令码 if (rw == RorW.Read) { array[26] = 0x01;//cmdCode--0101 array[27] = 0x01; } else { array[26] = 0x01;//write---0102 array[27] = 0x02; } //地址 //array[28] = (byte)mr; array[28] = GetMemoryCode(mr, mt); array[29] = (byte)(ch / 256); array[30] = (byte)(ch % 256); array[31] = (byte)offset; array[32] = (byte)(cnt / 256); array[33] = (byte)(cnt % 256); return array; } } }