终端一体化运控平台
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ModbusRTU.cs 7.5 KiB

2 年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. using NModbus;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO.Ports;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace BPASmartClient.Modbus
  9. {
  10. public class ModbusRTU
  11. {
  12. #region 参数配置
  13. private static IModbusMaster master;
  14. private static IModbusSerialMaster serialMaster;
  15. private static ModbusFactory factory;
  16. private static SerialPort port;
  17. //写线圈或写寄存器数组
  18. private bool[] coilsBuffer;
  19. private ushort[] registerBuffer;
  20. //功能码
  21. private string functionCode;
  22. //串口参数
  23. private string portName;
  24. private int baudRate;
  25. private Parity parity;
  26. private int dataBits;
  27. private StopBits stopBits;
  28. #endregion
  29. #region 串口配置
  30. /// <summary>
  31. /// 串口参数获取
  32. /// </summary>
  33. /// <returns></返回串口配置参数>
  34. public void InitSerialPortParameter(string protName, int bauRate, string currentParity, int dataBits, string currentStopBits)
  35. {
  36. switch (currentParity)
  37. {
  38. case "奇":
  39. parity = Parity.Odd;
  40. break;
  41. case "偶":
  42. parity = Parity.Even;
  43. break;
  44. case "无":
  45. parity = Parity.None;
  46. break;
  47. default:
  48. break;
  49. }
  50. switch (currentStopBits)
  51. {
  52. case "1":
  53. stopBits = StopBits.One;
  54. break;
  55. case "2":
  56. stopBits = StopBits.Two;
  57. break;
  58. default:
  59. break;
  60. }
  61. port = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
  62. //master = factory.CreateMaster()
  63. }
  64. #endregion
  65. #region 串口收/发
  66. public async void ExecuteFunctionRecive(string functionCode, byte slaveAddress, ushort startAddress, ushort numberOfPoints)
  67. {
  68. try
  69. {
  70. if (port.IsOpen == false)
  71. {
  72. port.Open();
  73. }
  74. if (functionCode != null)
  75. {
  76. switch (functionCode)
  77. {
  78. case "01 Read Coils"://读取单个线圈
  79. try
  80. {
  81. coilsBuffer = master.ReadCoils(slaveAddress, startAddress, numberOfPoints);
  82. }
  83. catch (Exception)
  84. {
  85. //MessageBox.Show(e.Message);
  86. break;
  87. }
  88. break;
  89. case "02 Read DisCrete Inputs"://读取输入线圈/离散量线圈
  90. try
  91. {
  92. coilsBuffer = master.ReadInputs(slaveAddress, startAddress, numberOfPoints);
  93. }
  94. catch (Exception)
  95. {
  96. break;
  97. }
  98. break;
  99. case "03 Read Holding Registers"://读取保持寄存
  100. try
  101. {
  102. registerBuffer = master.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints);
  103. }
  104. catch (Exception)
  105. {
  106. break;
  107. }
  108. break;
  109. case "04 Read Input Registers"://读取输入寄存器
  110. try
  111. {
  112. registerBuffer = master.ReadInputRegisters(slaveAddress, startAddress, numberOfPoints);
  113. }
  114. catch (Exception)
  115. {
  116. break;
  117. }
  118. break;
  119. default:
  120. break;
  121. }
  122. }
  123. port.Close();
  124. }
  125. catch (Exception ex)
  126. {
  127. port.Close();
  128. }
  129. }
  130. public async void ExecuteFunctionSend(string data, byte slaveAddress, ushort startAddress)
  131. {
  132. try
  133. {
  134. if (port.IsOpen == false)
  135. {
  136. port.Open();
  137. }
  138. if (functionCode != null)
  139. {
  140. switch (functionCode)
  141. {
  142. case "05 Write Single Coil"://写单个线圈
  143. SetWriteParametes(data,true);
  144. await master.WriteSingleCoilAsync(slaveAddress, startAddress, coilsBuffer[0]);
  145. break;
  146. case "06 Write Single Registers"://写单个输入线圈/离散量线圈
  147. SetWriteParametes(data,true);
  148. await master.WriteSingleRegisterAsync(slaveAddress, startAddress, registerBuffer[0]);
  149. break;
  150. case "0F Write Multiple Coils"://写一组线圈
  151. SetWriteParametes(data);
  152. await master.WriteMultipleCoilsAsync(slaveAddress, startAddress, coilsBuffer);
  153. break;
  154. case "10 Write Multiple Registers"://写一组保持寄存器
  155. SetWriteParametes(data);
  156. await master.WriteMultipleRegistersAsync(slaveAddress, startAddress, registerBuffer);
  157. break;
  158. default:
  159. break;
  160. }
  161. }
  162. port.Close();
  163. }
  164. catch (Exception ex)
  165. {
  166. port.Close();
  167. }
  168. }
  169. #endregion
  170. /// <summary>
  171. /// 设置写参数
  172. /// </summary>
  173. private void SetWriteParametes(string data,bool isParametes =false)
  174. {
  175. //判断是否写线圈
  176. if (isParametes)
  177. {
  178. string[] strarr = data.Split(' ');
  179. coilsBuffer = new bool[strarr.Length];
  180. //转化为bool数组
  181. for (int i = 0; i < strarr.Length; i++)
  182. {
  183. // strarr[i] == "0" ? coilsBuffer[i] = false : coilsBuffer[i] = true;
  184. if (strarr[i] == "0")
  185. {
  186. coilsBuffer[i] = false;
  187. }
  188. else
  189. {
  190. coilsBuffer[i] = true;
  191. }
  192. }
  193. }
  194. else
  195. {
  196. //转化ushort数组
  197. string[] strarr = data.Split(' ');
  198. registerBuffer = new ushort[strarr.Length];
  199. for (int i = 0; i < strarr.Length; i++)
  200. {
  201. registerBuffer[i] = ushort.Parse(strarr[i]);
  202. }
  203. }
  204. }
  205. }
  206. }