FinsClass.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace OmronFinsTCP.Net
  6. {
  7. class FinsClass
  8. {
  9. /// <summary>
  10. /// 获取内存区码
  11. /// </summary>
  12. /// <param name="mr">寄存器类型</param>
  13. /// <param name="mt">地址类型</param>
  14. /// <returns></returns>
  15. private static byte GetMemoryCode(PlcMemory mr, MemoryType mt)
  16. {
  17. if (mt == MemoryType.Bit)
  18. {
  19. switch (mr)
  20. {
  21. case PlcMemory.CIO:
  22. return 0x30;
  23. case PlcMemory.WR:
  24. return 0x31;
  25. case PlcMemory.HR:
  26. return 0x32;
  27. case PlcMemory.AR:
  28. return 0x33;
  29. case PlcMemory.DM:
  30. return 0x02;
  31. default:
  32. return 0x00;
  33. }
  34. }
  35. else
  36. {
  37. switch (mr)
  38. {
  39. case PlcMemory.CIO:
  40. return 0xB0;
  41. case PlcMemory.WR:
  42. return 0xB1;
  43. case PlcMemory.HR:
  44. return 0xB2;
  45. case PlcMemory.AR:
  46. return 0xB3;
  47. case PlcMemory.DM:
  48. return 0x82;
  49. default:
  50. return 0x00;
  51. }
  52. }
  53. }
  54. /// <summary>
  55. /// PC请求连接的握手信号,第一次连接会分配PC节点号
  56. /// </summary>
  57. /// <returns></returns>
  58. internal static byte[] HandShake()
  59. {
  60. #region fins command
  61. byte[] array = new byte[20];
  62. array[0] = 0x46;
  63. array[1] = 0x49;
  64. array[2] = 0x4E;
  65. array[3] = 0x53;
  66. array[4] = 0;
  67. array[5] = 0;
  68. array[6] = 0;
  69. array[7] = 0x0C;
  70. array[8] = 0;
  71. array[9] = 0;
  72. array[10] = 0;
  73. array[11] = 0;
  74. array[12] = 0;
  75. array[13] = 0;
  76. array[14] = 0;
  77. array[15] = 0;//ERR?
  78. array[16] = 0;
  79. array[17] = 0;
  80. array[18] = 0;
  81. array[19] = 0;//TODO:ask for client and server node number, the client node will allocated automatically
  82. //array[19] = this.GetIPNode(lIP);//本机IP地址的末位
  83. #endregion fins command
  84. return array;
  85. }
  86. /// <summary>
  87. /// Fins读写指令生成
  88. /// </summary>
  89. /// <param name="rw">读写类型</param>
  90. /// <param name="mr">寄存器类型</param>
  91. /// <param name="mt">地址类型</param>
  92. /// <param name="ch">起始地址</param>
  93. /// <param name="offset">位地址:00-15,字地址则为00</param>
  94. /// <param name="cnt">地址个数,按位读写只能是1</param>
  95. /// <returns></returns>
  96. internal static byte[] FinsCmd(RorW rw, PlcMemory mr, MemoryType mt, short ch, short offset, short cnt)
  97. {
  98. //byte[] array;
  99. //if (rw == RorW.Read)
  100. // array = new byte[34];
  101. //else
  102. // array = new byte[(int)(cnt * 2 + 33 + 1)];//长度是如何确定的在fins协议174页
  103. byte[] array = new byte[34];//写指令还有后面的写入数组需要拼接在一起!
  104. //TCP FINS header
  105. array[0] = 0x46;//F
  106. array[1] = 0x49;//I
  107. array[2] = 0x4E;//N
  108. array[3] = 0x53;//S
  109. array[4] = 0;//cmd length
  110. array[5] = 0;
  111. //指令长度从下面字节开始计算array[8]
  112. if (rw == RorW.Read)
  113. {
  114. array[6] = 0;
  115. array[7] = 0x1A;//26
  116. }
  117. else
  118. {
  119. //写数据的时候一个字占两个字节,而一个位只占一个字节
  120. if (mt == MemoryType.Word)
  121. {
  122. array[6] = (byte)((cnt * 2 + 26) / 256);
  123. array[7] = (byte)((cnt * 2 + 26) % 256);
  124. }
  125. else
  126. {
  127. array[6] = 0;
  128. array[7] = 0x1B;
  129. }
  130. }
  131. array[8] = 0;//frame command
  132. array[9] = 0;
  133. array[10] = 0;
  134. array[11] = 0x02;
  135. array[12] = 0;//err
  136. array[13] = 0;
  137. array[14] = 0;
  138. array[15] = 0;
  139. //command frame header
  140. array[16] = 0x80;//ICF
  141. array[17] = 0x00;//RSV
  142. array[18] = 0x02;//GCT, less than 8 network layers
  143. array[19] = 0x00;//DNA, local network
  144. array[20] = BasicClass.plcNode;//DA1
  145. array[21] = 0x00;//DA2, CPU unit
  146. array[22] = 0x00;//SNA, local network
  147. array[23] = BasicClass.pcNode;//SA1
  148. array[24] = 0x00;//SA2, CPU unit
  149. array[25] = 0xFF;
  150. //TODO:array[25] = Convert.ToByte(21);//SID//?????----------------------------------00-FF任意值
  151. //指令码
  152. if (rw == RorW.Read)
  153. {
  154. array[26] = 0x01;//cmdCode--0101
  155. array[27] = 0x01;
  156. }
  157. else
  158. {
  159. array[26] = 0x01;//write---0102
  160. array[27] = 0x02;
  161. }
  162. //地址
  163. //array[28] = (byte)mr;
  164. array[28] = GetMemoryCode(mr, mt);
  165. array[29] = (byte)(ch / 256);
  166. array[30] = (byte)(ch % 256);
  167. array[31] = (byte)offset;
  168. array[32] = (byte)(cnt / 256);
  169. array[33] = (byte)(cnt % 256);
  170. return array;
  171. }
  172. }
  173. }