ModbusClass.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1.  using LogClass;
  2. using NModbus;
  3. using System;
  4. using System.Net.Sockets;
  5. namespace CCDCount.DLL.Tools
  6. {
  7. public class ModbusTcpClient
  8. {
  9. private TcpClient _tcpClient;
  10. private IModbusMaster _modbusMaster;
  11. private string LastIpAddress = string.Empty;
  12. private int LastPort = 0;
  13. public bool IsTcpClientConnected()
  14. {
  15. if (_tcpClient == null || _tcpClient.Client == null)
  16. return false;
  17. try
  18. {
  19. Socket socket = _tcpClient.Client;
  20. bool isReadable = socket.Poll(0, SelectMode.SelectRead);
  21. bool hasNoData = (socket.Available == 0);
  22. // 可读且无数据 = 连接已断开
  23. return !(isReadable && hasNoData);
  24. }
  25. catch (SocketException) { return false; }
  26. catch (ObjectDisposedException) { return false; }
  27. }
  28. /// <summary>
  29. /// 连接 Modbus TCP 服务器
  30. /// </summary>
  31. /// <param name="ipAddress"></param>
  32. /// <param name="port"></param>
  33. /// <returns></returns>
  34. public bool Connect(string ipAddress, int port = 502)
  35. {
  36. try
  37. {
  38. _tcpClient = new TcpClient(ipAddress, port)
  39. {
  40. SendTimeout = 2000,
  41. ReceiveTimeout = 2000
  42. };
  43. // 使用 ModbusFactory 创建 Master(新版本 API)
  44. var factory = new ModbusFactory();
  45. _modbusMaster = factory.CreateMaster(_tcpClient);
  46. LastIpAddress = ipAddress;
  47. LastPort = port;
  48. return true;
  49. }
  50. catch (Exception ex)
  51. {
  52. Console.WriteLine($"连接失败: {ex.Message}");
  53. return false;
  54. }
  55. }
  56. /// <summary>
  57. /// 断开连接
  58. /// </summary>
  59. public void Disconnect()
  60. {
  61. _modbusMaster?.Dispose();
  62. _tcpClient?.Close();
  63. }
  64. /// <summary>
  65. /// 读取线圈(功能码01)
  66. /// </summary>
  67. /// <param name="slaveId"></param>
  68. /// <param name="startAddress"></param>
  69. /// <param name="numRegisters"></param>
  70. /// <returns></returns>
  71. /// <exception cref="InvalidOperationException"></exception>
  72. public bool ReadCoilsRegister(byte slaveId, ushort startAddress, ushort numRegisters,out bool[] returnValue)
  73. {
  74. returnValue = null;
  75. bool result = false;
  76. if (_modbusMaster == null)
  77. {
  78. //FaultLog.RecordErrorMessage($"MainThreadClass-ReadCoilsRegister failed:未连接到服务器");
  79. return false;
  80. }
  81. try
  82. {
  83. returnValue = _modbusMaster.ReadCoils(slaveId, startAddress, numRegisters);
  84. result = true;
  85. }
  86. catch (Exception ex)
  87. {
  88. Console.WriteLine($"读取线圈失败: {ex.Message}");
  89. //FaultLog.RecordErrorMessage($"MainThreadClass-ReadCoilsRegister-ReadCoilsRegister failed:{ex.Message}");
  90. result = false;
  91. }
  92. return result;
  93. }
  94. /// <summary>
  95. /// 读取保持寄存器(功能码03)
  96. /// </summary>
  97. /// <param name="slaveId"></param>
  98. /// <param name="startAddress"></param>
  99. /// <param name="numRegisters"></param>
  100. /// <returns></returns>
  101. /// <exception cref="InvalidOperationException"></exception>
  102. public bool ReadHoldingRegisters(byte slaveId, ushort startAddress, ushort numRegisters,out ushort[] returnValue)
  103. {
  104. bool result = false;
  105. returnValue = null;
  106. if (_modbusMaster == null)
  107. {
  108. //FaultLog.RecordErrorMessage($"MainThreadClass-ReadHoldingRegistersAsReal failed:未连接到服务器");
  109. return false;
  110. }
  111. try
  112. {
  113. returnValue = _modbusMaster.ReadHoldingRegisters(slaveId, startAddress, numRegisters);
  114. result = true;
  115. }
  116. catch (Exception ex)
  117. {
  118. if(ex.HResult== -2146232800)
  119. {
  120. ReConnect();
  121. }
  122. Console.WriteLine($"读取保持寄存器失败: {ex.Message}");
  123. //FaultLog.RecordErrorMessage($"MainThreadClass-ReadHoldingRegisters-ReadHoldingRegisters failed:{ex.Message}");
  124. result = false;
  125. }
  126. return result;
  127. }
  128. /// <summary>
  129. /// 读取保持寄存器中的REAL值(功能码03)
  130. /// </summary>
  131. /// <param name="slaveId">从站ID</param>
  132. /// <param name="startAddress">起始地址</param>
  133. /// <param name="count">REAL值的数量</param>
  134. /// <returns>REAL值数组</returns>
  135. public float[] ReadHoldingRegistersAsReal(byte slaveId, ushort startAddress, ushort count)
  136. {
  137. if (_modbusMaster == null)
  138. {
  139. //FaultLog.RecordErrorMessage($"MainThreadClass-ReadHoldingRegistersAsReal failed:未连接到服务器");
  140. return null;
  141. }
  142. try
  143. {
  144. // 每个REAL值占用2个寄存器
  145. ushort[] registers = _modbusMaster.ReadHoldingRegisters(slaveId, startAddress, (ushort)(count * 2));
  146. float[] realValues = new float[count];
  147. for (int i = 0; i < count; i++)
  148. {
  149. // 获取两个连续的寄存器值
  150. ushort lowRegister = registers[i * 2];
  151. ushort highRegister = registers[i * 2 + 1];
  152. // 根据字节序组合成32位值
  153. byte[] bytes = new byte[4];
  154. bytes[0] = (byte)(lowRegister & 0xFF);
  155. bytes[1] = (byte)((lowRegister >> 8) & 0xFF);
  156. bytes[2] = (byte)(highRegister & 0xFF);
  157. bytes[3] = (byte)((highRegister >> 8) & 0xFF);
  158. // 转换为float
  159. realValues[i] = BitConverter.ToSingle(bytes, 0);
  160. }
  161. return realValues;
  162. }
  163. catch (Exception ex)
  164. {
  165. Console.WriteLine($"读取REAL值失败: {ex.Message}");
  166. //FaultLog.RecordErrorMessage($"MainThreadClass-ReadHoldingRegistersAsReal failed:{ex.Message}");
  167. return null;
  168. }
  169. }
  170. /// <summary>
  171. /// 读取保持寄存器中的REAL值(支持不同字节序)(功能码03)
  172. /// </summary>
  173. /// <param name="slaveId">从站ID</param>
  174. /// <param name="startAddress">起始地址</param>
  175. /// <param name="count">REAL值的数量</param>
  176. /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
  177. /// <returns>REAL值数组</returns>
  178. public float[] ReadHoldingRegistersAsReal(byte slaveId, ushort startAddress, ushort count, string byteOrder = "BADC")
  179. {
  180. if (_modbusMaster == null)
  181. {
  182. //FaultLog.RecordErrorMessage($"MainThreadClass-ReadHoldingRegistersAsReal failed:未连接到服务器");
  183. return null;
  184. }
  185. try
  186. {
  187. // 每个REAL值占用2个寄存器
  188. ushort[] registers = _modbusMaster.ReadHoldingRegisters(slaveId, startAddress, (ushort)(count * 2));
  189. float[] realValues = new float[count];
  190. for (int i = 0; i < count; i++)
  191. {
  192. ushort highRegister = registers[i * 2];
  193. ushort lowRegister = registers[i * 2 + 1];
  194. byte[] bytes = ConvertToByteArray(lowRegister, highRegister, byteOrder);
  195. realValues[i] = BitConverter.ToSingle(bytes, 0);
  196. }
  197. return realValues;
  198. }
  199. catch (Exception ex)
  200. {
  201. Console.WriteLine($"读取REAL值失败: {ex.Message}");
  202. //FaultLog.RecordErrorMessage($"MainThreadClass-ReadHoldingRegistersAsReal failed:{ex.Message}");
  203. return null;
  204. }
  205. }
  206. /// <summary>
  207. /// 读取保持寄存器中的REAL值(支持不同字节序)(功能码03)
  208. /// </summary>
  209. /// <param name="slaveId">从站ID</param>
  210. /// <param name="startAddress">起始地址</param>
  211. /// <param name="count">REAL值的数量</param>
  212. /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
  213. /// <returns>REAL值数组</returns>
  214. public double[] ReadHoldingRegistersAsLReal(byte slaveId, ushort startAddress, ushort count, string byteOrder = "BADC")
  215. {
  216. if (_modbusMaster == null)
  217. {
  218. //FaultLog.RecordErrorMessage($"MainThreadClass-ReadHoldingRegistersAsReal failed:未连接到服务器");
  219. return null;
  220. }
  221. try
  222. {
  223. // 每个LREAL值占用4个寄存器
  224. ushort[] registers = _modbusMaster.ReadHoldingRegisters(slaveId, startAddress, (ushort)(count * 4));
  225. double[] realValues = new double[count];
  226. for (int i = 0; i < count; i++)
  227. {
  228. ushort reg1 = registers[i * 4];
  229. ushort reg2 = registers[i * 4 + 1];
  230. ushort reg3 = registers[i * 4 + 2];
  231. ushort reg4 = registers[i * 4 + 3];
  232. byte[] bytes = ConvertToByteArray8Bytes(reg1, reg2, reg3, reg4, byteOrder);
  233. realValues[i] = BitConverter.ToDouble(bytes, 0);
  234. }
  235. return realValues;
  236. }
  237. catch (Exception ex)
  238. {
  239. Console.WriteLine($"读取LREAL值失败: {ex.Message}");
  240. //FaultLog.RecordErrorMessage($"MainThreadClass-ReadHoldingRegistersAsReal failed:{ex.Message}");
  241. return null;
  242. }
  243. }
  244. /// <summary>
  245. /// 读取保持寄存器中的Int32值(功能码03)
  246. /// </summary>
  247. /// <param name="slaveId">从站ID</param>
  248. /// <param name="startAddress">起始地址</param>
  249. /// <param name="count">REAL值的数量</param>
  250. /// <returns>REAL值数组</returns>
  251. public UInt32[] ReadHoldingRegistersAsInt32(byte slaveId, ushort startAddress, ushort count,string byteOrder = "BADC")
  252. {
  253. if (_modbusMaster == null)
  254. {
  255. //FaultLog.RecordErrorMessage($"MainThreadClass-ReadHoldingRegistersAsInt32 failed:未连接到服务器");
  256. return null;
  257. }
  258. try
  259. {
  260. // 每个REAL值占用2个寄存器
  261. ushort[] registers = _modbusMaster.ReadHoldingRegisters(slaveId, startAddress, (ushort)(count * 2));
  262. UInt32[] realValues = new UInt32[count];
  263. for (int i = 0; i < count; i++)
  264. {
  265. // 获取两个连续的寄存器值
  266. ushort highRegister = registers[i * 2];
  267. ushort lowRegister = registers[i * 2 + 1];
  268. byte[] bytes = ConvertToByteArray(lowRegister, highRegister, byteOrder);
  269. // 转换为float
  270. realValues[i] = (UInt32)BitConverter.ToInt32(bytes, 0);
  271. }
  272. return realValues;
  273. }
  274. catch (Exception ex)
  275. {
  276. Console.WriteLine($"读取Int32值失败: {ex.Message}");
  277. return null;
  278. }
  279. }
  280. /// <summary>
  281. /// 写入线圈(功能码05)
  282. /// </summary>
  283. /// <param name="slaveId">Slave编号</param>
  284. /// <param name="CoilsAddress">写入地址</param>
  285. /// <param name="values">写入值</param>
  286. /// <exception cref="InvalidOperationException"></exception>
  287. public bool WriteCoilsRegister(byte slaveId, ushort CoilsAddress, bool values)
  288. {
  289. bool result = false;
  290. if (_modbusMaster == null)
  291. {
  292. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteCoilsRegister failed:未连接到服务器");
  293. result = false;
  294. }
  295. try
  296. {
  297. _modbusMaster.WriteSingleCoil(slaveId, CoilsAddress, values);
  298. result = true;
  299. }
  300. catch (Exception ex)
  301. {
  302. Console.WriteLine($"写入线圈失败: {ex.Message}");
  303. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteCoilsRegister-WriteCoilsRegister failed:{ex.Message}");
  304. result = false;
  305. }
  306. return result;
  307. }
  308. /// <summary>
  309. /// 写入单个寄存器(功能码06)
  310. /// </summary>
  311. /// <param name="slaveId"></param>
  312. /// <param name="registerAddress"></param>
  313. /// <param name="value"></param>
  314. /// <exception cref="InvalidOperationException"></exception>
  315. public bool WriteSingleRegister(byte slaveId, ushort registerAddress, ushort value)
  316. {
  317. bool result = false;
  318. if (_modbusMaster == null)
  319. {
  320. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteSingleRegister failed:未连接到服务器");
  321. result = false;
  322. return result;
  323. }
  324. try
  325. {
  326. _modbusMaster.WriteSingleRegister(slaveId, registerAddress, value);
  327. result = true;
  328. }
  329. catch (Exception ex)
  330. {
  331. Console.WriteLine($"写入单个寄存器失败: {ex.Message}");
  332. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteSingleRegister-WriteSingleRegister failed:{ex.Message}");
  333. result = false;
  334. }
  335. return result;
  336. }
  337. public bool WriteSingleRegister(byte slaveId, ushort registerAddress, Int16 value)
  338. {
  339. bool result = false;
  340. if (_modbusMaster == null)
  341. {
  342. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteSingleRegister failed:未连接到服务器");
  343. result = false;
  344. return result;
  345. }
  346. try
  347. {
  348. _modbusMaster.WriteSingleRegister(slaveId, registerAddress, (ushort)value);
  349. result = true;
  350. }
  351. catch (Exception ex)
  352. {
  353. Console.WriteLine($"写入单个寄存器失败: {ex.Message}");
  354. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteSingleRegister-WriteSingleRegister failed:{ex.Message}");
  355. result = false;
  356. }
  357. return result;
  358. }
  359. /// <summary>
  360. /// 写入多个寄存器(功能码16)
  361. /// </summary>
  362. /// <param name="slaveId"></param>
  363. /// <param name="startAddress"></param>
  364. /// <param name="values"></param>
  365. /// <exception cref="InvalidOperationException"></exception>
  366. public bool WriteMultipleRegisters(byte slaveId, ushort startAddress, ushort[] values)
  367. {
  368. bool result = false;
  369. if (_modbusMaster == null)
  370. {
  371. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteMultipleRegisters failed:未连接到服务器");
  372. return false;
  373. }
  374. try
  375. {
  376. _modbusMaster.WriteMultipleRegisters(slaveId, startAddress, values);
  377. result = true;
  378. }
  379. catch (Exception ex)
  380. {
  381. Console.WriteLine($"写入多个寄存器失败: {ex.Message}");
  382. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteMultipleRegisters-WriteMultipleRegisters failed:{ex.Message}");
  383. result = false;
  384. }
  385. return result;
  386. }
  387. /// <summary>
  388. /// 写入单个REAL值到保持寄存器(功能码16)
  389. /// </summary>
  390. /// <param name="slaveId">从站ID</param>
  391. /// <param name="startAddress">起始地址</param>
  392. /// <param name="value">REAL值</param>
  393. /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
  394. public bool WriteSingleReal(byte slaveId, ushort startAddress, float value, string byteOrder = "BADC")
  395. {
  396. bool result = false;
  397. if (_modbusMaster == null)
  398. {
  399. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteSingleReal failed:未连接到服务器");
  400. return false;
  401. }
  402. try
  403. {
  404. // 将float转换为字节数组
  405. byte[] bytes = BitConverter.GetBytes(value);
  406. // 根据字节序重新排列字节
  407. ushort[] registers = ConvertBytesToRegisters(bytes, byteOrder);
  408. // 写入连续的寄存器
  409. result = WriteMultipleRegisters(slaveId, startAddress, registers);
  410. }
  411. catch (Exception ex)
  412. {
  413. Console.WriteLine($"写入REAL值失败: {ex.Message}");
  414. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteSingleReal failed:{ex.Message}");
  415. result = false;
  416. }
  417. return result;
  418. }
  419. /// <summary>
  420. /// 写入单个LREAL值到保持寄存器(功能码16)
  421. /// </summary>
  422. /// <param name="slaveId">从站ID</param>
  423. /// <param name="startAddress">起始地址</param>
  424. /// <param name="value">REAL值</param>
  425. /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
  426. public bool WriteSingleLReal(byte slaveId, ushort startAddress, double value, string byteOrder = "BADC")
  427. {
  428. bool result = false;
  429. if (_modbusMaster == null)
  430. {
  431. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteSingleReal failed:未连接到服务器");
  432. return false;
  433. }
  434. try
  435. {
  436. // 将float转换为字节数组
  437. byte[] bytes = BitConverter.GetBytes(value);
  438. // 根据字节序重新排列字节
  439. ushort[] registers = ConvertBytesTo8Registers(bytes, byteOrder);
  440. // 写入连续的寄存器
  441. result = WriteMultipleRegisters(slaveId, startAddress, registers);
  442. }
  443. catch (Exception ex)
  444. {
  445. Console.WriteLine($"写入LREAL值失败: {ex.Message}");
  446. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteSingleReal failed:{ex.Message}");
  447. result = false;
  448. }
  449. return result;
  450. }
  451. /// <summary>
  452. /// 写入多个REAL值到保持寄存器(功能码16)
  453. /// </summary>
  454. /// <param name="slaveId">从站ID</param>
  455. /// <param name="startAddress">起始地址</param>
  456. /// <param name="values">REAL值数组</param>
  457. /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
  458. public bool WriteMultipleReals(byte slaveId, ushort startAddress, float[] values, string byteOrder = "BADC")
  459. {
  460. bool result = false;
  461. if (_modbusMaster == null)
  462. {
  463. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteMultipleReals failed:未连接到服务器");
  464. return false;
  465. }
  466. if (values == null || values.Length == 0)
  467. {
  468. //FaultLog.RecordLogMessage("写入多个REAL值到保持寄存器-值数组不能为空",0);
  469. return false;
  470. }
  471. try
  472. {
  473. // 每个REAL值需要2个寄存器,所以总寄存器数是REAL值数量的2倍
  474. ushort[] registers = new ushort[values.Length * 2];
  475. for (int i = 0; i < values.Length; i++)
  476. {
  477. // 将每个float转换为字节数组
  478. byte[] bytes = BitConverter.GetBytes(values[i]);
  479. // 根据字节序转换为寄存器值
  480. ushort[] regPair = ConvertBytesToRegisters(bytes, byteOrder);
  481. // 将寄存器值放入数组
  482. registers[i * 2] = regPair[0];
  483. registers[i * 2 + 1] = regPair[1];
  484. }
  485. // 写入所有寄存器
  486. _modbusMaster.WriteMultipleRegisters(slaveId, startAddress, registers);
  487. result = true;
  488. }
  489. catch (Exception ex)
  490. {
  491. Console.WriteLine($"写入多个REAL值失败: {ex.Message}");
  492. //FaultLog.RecordErrorMessage($"MainThreadClass-WriteMultipleReals failed:{ex.Message}");
  493. result = false;
  494. }
  495. return result;
  496. }
  497. /// <summary>
  498. /// 写入单个Int32值到保持寄存器(功能码16)
  499. /// </summary>
  500. /// <param name="slaveId">从站ID</param>
  501. /// <param name="startAddress">起始地址</param>
  502. /// <param name="value">REAL值</param>
  503. /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
  504. public bool WriteSingleInt32(byte slaveId, ushort startAddress, UInt32 value, string byteOrder = "BADC")
  505. {
  506. // 将32位整数拆分为两个16位寄存器值
  507. byte[] bytes = BitConverter.GetBytes(value);
  508. ushort[] registers = new ushort[2];
  509. ushort[] regPair = ConvertBytesToRegisters(bytes, byteOrder);
  510. // 将寄存器值放入数组
  511. registers[0] = regPair[0];
  512. registers[1] = regPair[1];
  513. return WriteMultipleRegisters(slaveId, startAddress, registers);
  514. }
  515. private bool ReConnect()
  516. {
  517. bool result = false;
  518. if (LastIpAddress!=string.Empty&&LastPort!=0)
  519. {
  520. try
  521. {
  522. _tcpClient = new TcpClient(LastIpAddress, LastPort)
  523. {
  524. SendTimeout = 2000,
  525. ReceiveTimeout = 2000
  526. };
  527. // 使用 ModbusFactory 创建 Master(新版本 API)
  528. var factory = new ModbusFactory();
  529. _modbusMaster = factory.CreateMaster(_tcpClient);
  530. return true;
  531. }
  532. catch (Exception ex)
  533. {
  534. Console.WriteLine($"连接失败: {ex.Message}");
  535. return false;
  536. }
  537. }
  538. return result;
  539. }
  540. /// <summary>
  541. /// 将寄存器数组换为字节数组转(根据指定字节序)
  542. /// </summary>
  543. /// <param name="lowRegister">低位寄存器</param>
  544. /// <param name="highRegister">高位寄存器</param>
  545. /// <param name="byteOrder">字节序</param>
  546. /// <returns>字节数组</returns>
  547. private byte[] ConvertToByteArray(ushort lowRegister, ushort highRegister, string byteOrder)
  548. {
  549. byte[] bytes = new byte[4];
  550. switch (byteOrder.ToUpper())
  551. {
  552. case "ABCD": // 大端序
  553. bytes[0] = (byte)(highRegister >> 8);
  554. bytes[1] = (byte)(highRegister & 0xFF);
  555. bytes[2] = (byte)(lowRegister >> 8);
  556. bytes[3] = (byte)(lowRegister & 0xFF);
  557. break;
  558. case "CDAB": // 小端序
  559. bytes[0] = (byte)(lowRegister >> 8);
  560. bytes[1] = (byte)(lowRegister & 0xFF);
  561. bytes[2] = (byte)(highRegister >> 8);
  562. bytes[3] = (byte)(highRegister & 0xFF);
  563. break;
  564. case "BADC":
  565. bytes[0] = (byte)(highRegister & 0xFF);
  566. bytes[1] = (byte)(highRegister >> 8);
  567. bytes[2] = (byte)(lowRegister & 0xFF);
  568. bytes[3] = (byte)(lowRegister >> 8);
  569. break;
  570. case "DCBA":
  571. bytes[0] = (byte)(lowRegister & 0xFF);
  572. bytes[1] = (byte)(lowRegister >> 8);
  573. bytes[2] = (byte)(highRegister & 0xFF);
  574. bytes[3] = (byte)(highRegister >> 8);
  575. break;
  576. default:
  577. // 默认使用ABCD顺序
  578. bytes[0] = (byte)(highRegister >> 8);
  579. bytes[1] = (byte)(highRegister & 0xFF);
  580. bytes[2] = (byte)(lowRegister >> 8);
  581. bytes[3] = (byte)(lowRegister & 0xFF);
  582. break;
  583. }
  584. return bytes;
  585. }
  586. /// <summary>
  587. /// 将寄存器数组转换为字节数组(根据指定字节序,用于8字节double值)
  588. /// </summary>
  589. /// <param name="reg1">第1个寄存器(最高位寄存器)</param>
  590. /// <param name="reg2">第2个寄存器</param>
  591. /// <param name="reg3">第3个寄存器</param>
  592. /// <param name="reg4">第4个寄存器(最低位寄存器)</param>
  593. /// <param name="byteOrder">字节序</param>
  594. /// <returns>字节数组</returns>
  595. private byte[] ConvertToByteArray8Bytes(ushort reg1, ushort reg2, ushort reg3, ushort reg4, string byteOrder)
  596. {
  597. byte[] bytes = new byte[8];
  598. switch (byteOrder.ToUpper())
  599. {
  600. case "ABCD": // 大端序 - 寄存器顺序:reg1-reg2-reg3-reg4,字节顺序:0-1-2-3-4-5-6-7
  601. bytes[0] = (byte)(reg1 >> 8); // reg1高位字节
  602. bytes[1] = (byte)(reg1 & 0xFF); // reg1低位字节
  603. bytes[2] = (byte)(reg2 >> 8); // reg2高位字节
  604. bytes[3] = (byte)(reg2 & 0xFF); // reg2低位字节
  605. bytes[4] = (byte)(reg3 >> 8); // reg3高位字节
  606. bytes[5] = (byte)(reg3 & 0xFF); // reg3低位字节
  607. bytes[6] = (byte)(reg4 >> 8); // reg4高位字节
  608. bytes[7] = (byte)(reg4 & 0xFF); // reg4低位字节
  609. break;
  610. case "CDAB": // 交换32位字 - 寄存器顺序:reg3-reg4-reg1-reg2
  611. bytes[0] = (byte)(reg3 >> 8); // reg3高位字节
  612. bytes[1] = (byte)(reg3 & 0xFF); // reg3低位字节
  613. bytes[2] = (byte)(reg4 >> 8); // reg4高位字节
  614. bytes[3] = (byte)(reg4 & 0xFF); // reg4低位字节
  615. bytes[4] = (byte)(reg1 >> 8); // reg1高位字节
  616. bytes[5] = (byte)(reg1 & 0xFF); // reg1低位字节
  617. bytes[6] = (byte)(reg2 >> 8); // reg2高位字节
  618. bytes[7] = (byte)(reg2 & 0xFF); // reg2低位字节
  619. break;
  620. case "BADC": // 交换字内字节 - 高位字节在前,低位字节在后
  621. bytes[0] = (byte)(reg1 & 0xFF); // reg1低位字节
  622. bytes[1] = (byte)(reg1 >> 8); // reg1高位字节
  623. bytes[2] = (byte)(reg2 & 0xFF); // reg2低位字节
  624. bytes[3] = (byte)(reg2 >> 8); // reg2高位字节
  625. bytes[4] = (byte)(reg3 & 0xFF); // reg3低位字节
  626. bytes[5] = (byte)(reg3 >> 8); // reg3高位字节
  627. bytes[6] = (byte)(reg4 & 0xFF); // reg4低位字节
  628. bytes[7] = (byte)(reg4 >> 8); // reg4高位字节
  629. break;
  630. case "DCBA": // 完全反转 - 寄存器顺序:reg4-reg3-reg2-reg1
  631. bytes[0] = (byte)(reg4 & 0xFF); // reg4低位字节
  632. bytes[1] = (byte)(reg4 >> 8); // reg4高位字节
  633. bytes[2] = (byte)(reg3 & 0xFF); // reg3低位字节
  634. bytes[3] = (byte)(reg3 >> 8); // reg3高位字节
  635. bytes[4] = (byte)(reg2 & 0xFF); // reg2低位字节
  636. bytes[5] = (byte)(reg2 >> 8); // reg2高位字节
  637. bytes[6] = (byte)(reg1 & 0xFF); // reg1低位字节
  638. bytes[7] = (byte)(reg1 >> 8); // reg1高位字节
  639. break;
  640. default:
  641. // 默认使用ABCD顺序
  642. bytes[0] = (byte)(reg1 >> 8);
  643. bytes[1] = (byte)(reg1 & 0xFF);
  644. bytes[2] = (byte)(reg2 >> 8);
  645. bytes[3] = (byte)(reg2 & 0xFF);
  646. bytes[4] = (byte)(reg3 >> 8);
  647. bytes[5] = (byte)(reg3 & 0xFF);
  648. bytes[6] = (byte)(reg4 >> 8);
  649. bytes[7] = (byte)(reg4 & 0xFF);
  650. break;
  651. }
  652. return bytes;
  653. }
  654. /// <summary>
  655. /// 将字节数组转换为寄存器数组(根据指定字节序)
  656. /// </summary>
  657. /// <param name="bytes">字节数组(4字节)</param>
  658. /// <param name="byteOrder">字节序</param>
  659. /// <returns>寄存器数组(2个ushort)</returns>
  660. private ushort[] ConvertBytesToRegisters(byte[] bytes, string byteOrder)
  661. {
  662. if (bytes.Length != 4)
  663. throw new ArgumentException("字节数组必须包含4个字节用于REAL值转换");
  664. ushort[] registers = new ushort[2];
  665. switch (byteOrder.ToUpper())
  666. {
  667. case "ABCD": // 大端序
  668. registers[0] = (ushort)((bytes[0] << 8) | bytes[1]); // 高位寄存器
  669. registers[1] = (ushort)((bytes[2] << 8) | bytes[3]); // 低位寄存器
  670. break;
  671. case "CDAB": // 小端序
  672. registers[0] = (ushort)((bytes[2] << 8) | bytes[3]); // 高位寄存器
  673. registers[1] = (ushort)((bytes[0] << 8) | bytes[1]); // 低位寄存器
  674. break;
  675. case "BADC":
  676. registers[0] = (ushort)((bytes[1] << 8) | bytes[0]); // 高位寄存器
  677. registers[1] = (ushort)((bytes[3] << 8) | bytes[2]); // 低位寄存器
  678. break;
  679. case "DCBA":
  680. registers[0] = (ushort)((bytes[3] << 8) | bytes[2]); // 高位寄存器
  681. registers[1] = (ushort)((bytes[1] << 8) | bytes[0]); // 低位寄存器
  682. break;
  683. default:
  684. // 默认使用ABCD顺序
  685. registers[0] = (ushort)((bytes[0] << 8) | bytes[1]);
  686. registers[1] = (ushort)((bytes[2] << 8) | bytes[3]);
  687. break;
  688. }
  689. return registers;
  690. }
  691. /// <summary>
  692. /// 将字节数组转换为寄存器数组(根据指定字节序)
  693. /// </summary>
  694. /// <param name="bytes">字节数组(4字节)</param>
  695. /// <param name="byteOrder">字节序</param>
  696. /// <returns>寄存器数组(2个ushort)</returns>
  697. private ushort[] ConvertBytesTo8Registers(byte[] bytes, string byteOrder)
  698. {
  699. if (bytes.Length != 8)
  700. throw new ArgumentException("字节数组必须包含8个字节用于LREAL值转换");
  701. ushort[] registers = new ushort[4];
  702. switch (byteOrder.ToUpper())
  703. {
  704. case "ABCD": // 大端序 - 顺序:寄存器0-1-2-3,字节0-1-2-3-4-5-6-7
  705. registers[0] = (ushort)((bytes[0] << 8) | bytes[1]); // 最高字节寄存器
  706. registers[1] = (ushort)((bytes[2] << 8) | bytes[3]);
  707. registers[2] = (ushort)((bytes[4] << 8) | bytes[5]);
  708. registers[3] = (ushort)((bytes[6] << 8) | bytes[7]); // 最低字节寄存器
  709. break;
  710. case "CDAB": // 交换32位字节序
  711. registers[0] = (ushort)((bytes[4] << 8) | bytes[5]); // 高32位
  712. registers[1] = (ushort)((bytes[6] << 8) | bytes[7]);
  713. registers[2] = (ushort)((bytes[0] << 8) | bytes[1]); // 低32位
  714. registers[3] = (ushort)((bytes[2] << 8) | bytes[3]);
  715. break;
  716. case "BADC": // 交换字节内的高低位
  717. registers[0] = (ushort)((bytes[1] << 8) | bytes[0]);
  718. registers[1] = (ushort)((bytes[3] << 8) | bytes[2]);
  719. registers[2] = (ushort)((bytes[5] << 8) | bytes[4]);
  720. registers[3] = (ushort)((bytes[7] << 8) | bytes[6]);
  721. break;
  722. case "DCBA": // 完全反转字节序
  723. registers[0] = (ushort)((bytes[7] << 8) | bytes[6]); // 原始最低字节变最高
  724. registers[1] = (ushort)((bytes[5] << 8) | bytes[4]);
  725. registers[2] = (ushort)((bytes[3] << 8) | bytes[2]);
  726. registers[3] = (ushort)((bytes[1] << 8) | bytes[0]); // 原始最高字节变最低
  727. break;
  728. default:
  729. // 默认使用ABCD顺序
  730. registers[0] = (ushort)((bytes[0] << 8) | bytes[1]);
  731. registers[1] = (ushort)((bytes[2] << 8) | bytes[3]);
  732. registers[2] = (ushort)((bytes[4] << 8) | bytes[5]);
  733. registers[3] = (ushort)((bytes[6] << 8) | bytes[7]);
  734. break;
  735. }
  736. return registers;
  737. }
  738. }
  739. }