SerialPortManager.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. using BaseLibRWFile;
  2. using HardwareConfig;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO.Ports;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Windows.Forms;
  9. namespace BaseLibComm
  10. {
  11. public class StSerialPort
  12. {
  13. public int Index;
  14. public bool Enable;
  15. public string Name;
  16. public SerialPort serialPort;//= new SerialPort();
  17. public byte[] byteReceiveData;
  18. public string strReceivCommandData;
  19. public string strSendCommandData;
  20. public string strRecv;
  21. public int CurrentAddr = 0;
  22. public bool[,] BitVaueArray = new bool[16, 256];
  23. public bool[] bComRunNomalFlag = new bool[16];
  24. public short[,] WordValueArray = new short[16, 256];
  25. public bool comBusying;
  26. public bool isOpen = false;
  27. public SeriesTypeEnum SeriesType;
  28. public Action<byte[]> RevDataAction;
  29. }
  30. public class SerialPortManager
  31. {
  32. public static SerialPortManager Ins = new SerialPortManager();
  33. public static Dictionary<string, StSerialPort> DicSerialPort { set; get; } = new Dictionary<string, StSerialPort> { };
  34. //private bool bCommWell;
  35. private readonly System.Timers.Timer tmrTimeOut = new System.Timers.Timer(500);//实例化Timer类,设置间隔时间为10000毫秒;
  36. public SerialPortManager()
  37. {
  38. }
  39. public void LoadSerialProt()
  40. {
  41. //StSerialPort st = new StSerialPort();
  42. foreach (var p in HardConfigManager.Ins.HardwareList)
  43. {
  44. if (p.Enable)
  45. {
  46. switch (p.HardwareName)
  47. {
  48. case HardwareNameEnum.串口:
  49. SeriesAtti series = (SeriesAtti)p;
  50. StSerialPort st = new StSerialPort
  51. {
  52. Index = series.编号,
  53. Enable = true,
  54. Name = series.串口名称,
  55. SeriesType = series.串口类型,
  56. serialPort = new SerialPort
  57. {
  58. BaudRate = Convert.ToInt32(series.波特率.ToString().Remove(0, 1)),//B115200
  59. PortName = series.端口号.ToString(),
  60. DataBits = series.数据位,
  61. Parity = series.校验位,
  62. StopBits = series.停止位
  63. }
  64. };
  65. DicSerialPort.Add(st.serialPort.PortName, st);
  66. break;
  67. default:
  68. break;
  69. }
  70. }
  71. }
  72. }
  73. public bool OpenSerialPort(StSerialPort st)
  74. {
  75. bool bResult = false;
  76. switch (st.SeriesType)
  77. {
  78. case SeriesTypeEnum.RS232:
  79. bResult = OpenGeneralSerialPort(st);
  80. break;
  81. case SeriesTypeEnum.RS485:
  82. bResult = OpenGeneralSerialPort(st);
  83. break;
  84. case SeriesTypeEnum.ModbusRTU:
  85. bResult = ModbusRTU.Ins.OpenMyCom(st);
  86. break;
  87. case SeriesTypeEnum.ModbusACSII:
  88. bResult = ModbusRTU.Ins.OpenMyCom(st);
  89. break;
  90. }
  91. return bResult;
  92. }
  93. private bool OpenGeneralSerialPort(StSerialPort st)
  94. {
  95. try
  96. {
  97. //先关闭已经打开的串口
  98. if (st.serialPort.IsOpen)
  99. {
  100. st.serialPort.Close();
  101. }
  102. st.serialPort.ReceivedBytesThreshold = 1;
  103. st.serialPort.DataReceived += new SerialDataReceivedEventHandler(ReceiveData);//DataReceived事件委托
  104. //打开串口
  105. st.serialPort.Open();
  106. //设置超时定时器属性
  107. tmrTimeOut.Elapsed += new System.Timers.ElapsedEventHandler(SerialPortTimeOut);//到达时间的时候执行事件;
  108. tmrTimeOut.AutoReset = true;//设置超时是执行一次(false)还是一直执行(true);
  109. tmrTimeOut.Enabled = false;//是否执行System.Timers.Timer.Elapsed事件;
  110. //comBusying = false;
  111. //bCommWell = false;
  112. st.isOpen = true;// ;st.serialPort.IsOpen
  113. return true;
  114. }
  115. catch (Exception ex)
  116. {
  117. string str = $"{st.serialPort.PortName}串口打开失败:";
  118. Msg.Show($"{str}\r\n{ex}", $"{str}\r\nFailed to open the serial port:\r\n{ex}", "Error", msgicon: MessageBoxIcon.Error);
  119. //MessageBox.Show($"{st.serialPort.PortName}串口打开失败\r\nFailed to open the serial port\r\n{ex.Message }", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
  120. return false;
  121. }
  122. finally
  123. {
  124. }
  125. }
  126. public void CloseSerialPort(StSerialPort st)
  127. {
  128. try
  129. {
  130. st.isOpen = false;
  131. st.serialPort.Close();
  132. }
  133. catch (Exception)
  134. {
  135. throw;
  136. }
  137. }
  138. //DataReceived事件委托方法 每个协议都需重写DataReceived
  139. public void ReceiveData(object sender, SerialDataReceivedEventArgs e)
  140. {
  141. SerialPort sp = sender as SerialPort;
  142. try
  143. {
  144. if (DicSerialPort[sp.PortName].serialPort.BytesToRead > 0)
  145. {
  146. DicSerialPort[sp.PortName].strRecv = string.Empty;
  147. Thread.Sleep(50);
  148. DicSerialPort[sp.PortName].byteReceiveData = new byte[DicSerialPort[sp.PortName].serialPort.BytesToRead];
  149. DicSerialPort[sp.PortName].serialPort.Read(DicSerialPort[sp.PortName].byteReceiveData, 0, DicSerialPort[sp.PortName].byteReceiveData.Length);
  150. DicSerialPort[sp.PortName].RevDataAction?.Invoke(DicSerialPort[sp.PortName].byteReceiveData);
  151. DicSerialPort[sp.PortName].strRecv = Encoding.ASCII.GetString(DicSerialPort[sp.PortName].byteReceiveData,0, DicSerialPort[sp.PortName].byteReceiveData.Length);
  152. }
  153. }
  154. catch (Exception ex)
  155. {
  156. MessageBox.Show($"{DicSerialPort[sp.PortName].serialPort.PortName}串口接收数据错误\r\nSerial port received data error\r\n{ex.Message }", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
  157. }
  158. }
  159. public bool SendData(StSerialPort st, string strData)
  160. {
  161. try
  162. {
  163. if (st.serialPort.IsOpen)
  164. {
  165. st.serialPort.DiscardOutBuffer();//清除缓冲区里的内容
  166. st.serialPort.DiscardInBuffer();
  167. st.serialPort.Write(strData);
  168. return true;
  169. }
  170. else
  171. {
  172. return false;
  173. }
  174. }
  175. catch (Exception ex)
  176. {
  177. MessageBox.Show($"{st.serialPort.PortName}发送数据失败\r\nFailed to send data\r\n{ex.Message}", "Error");
  178. return false;
  179. }
  180. }
  181. public bool SendData(StSerialPort st, byte[] strData)
  182. {
  183. try
  184. {
  185. if (st.serialPort.IsOpen)
  186. {
  187. st.serialPort.DiscardOutBuffer();//清除缓冲区里的内容
  188. st.serialPort.DiscardInBuffer();
  189. st.serialPort.Write(strData,0, strData.Length);
  190. return true;
  191. }
  192. else
  193. {
  194. return false;
  195. }
  196. }
  197. catch (Exception ex)
  198. {
  199. MessageBox.Show($"{st.serialPort.PortName}发送数据失败\r\nFailed to send data\r\n{ex.Message}", "Error");
  200. return false;
  201. }
  202. }
  203. //定时器超时事件
  204. public void SerialPortTimeOut(object source, System.Timers.ElapsedEventArgs e)
  205. {
  206. //if (bCommWell == false)
  207. //{
  208. // //bComRunNomalFlag[CurrentAddr] = true;//设置本地址通讯故障
  209. // //strReceivCommandData = "";
  210. //}
  211. //tmrTimeOut.Enabled = false;
  212. //comBusying = false;//设置串口忙标志
  213. }
  214. }
  215. }