版博士V2.0程序
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 

214 rindas
6.2 KiB

  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.IO.Ports;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9. namespace ProductionControl.Utils
  10. {
  11. public class SSerialPort
  12. {
  13. private SerialPort _serialPort;
  14. private readonly ConcurrentQueue<byte[]> _messageQueue;
  15. private readonly EventWaitHandle _messageWaitHandle;
  16. private int _receiveCount, _sendCount;
  17. private readonly object _lock;
  18. private int queueSize;
  19. public int ReceiveCount
  20. {
  21. get => _receiveCount;
  22. }
  23. public int SendCount
  24. {
  25. get => _sendCount;
  26. }
  27. /// <summary>
  28. ///
  29. /// </summary>
  30. /// <param name="com"></param>
  31. /// <param name="baud"></param>
  32. /// <param name="size">队列最大容量</param>
  33. public SSerialPort(string com, int baud,int size=-1)
  34. {
  35. // initialized
  36. _lock = new object();
  37. _receiveCount = 0;
  38. _sendCount = 0;
  39. _messageQueue = new ConcurrentQueue<byte[]>();
  40. _messageWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
  41. queueSize = size;
  42. // Open Com
  43. openCom(com.ToUpper(), baud);
  44. // Receive byte
  45. pushMessage();
  46. }
  47. private void openCom(string com, int baud)
  48. {
  49. // Open Com
  50. _serialPort = new SerialPort(com, baud);
  51. if (_serialPort.IsOpen) _serialPort.Close();
  52. // Set the read / write timeouts
  53. _serialPort.ReadTimeout = 500;
  54. _serialPort.WriteTimeout = 500;
  55. // Set read / write buffer Size,the default of value is 1MB
  56. _serialPort.ReadBufferSize = 1024 * 1024;
  57. _serialPort.WriteBufferSize = 1024 * 1024;
  58. _serialPort.Open();
  59. // Discard Buffer
  60. _serialPort.DiscardInBuffer();
  61. _serialPort.DiscardOutBuffer();
  62. }
  63. #region Static
  64. /// <summary>
  65. /// 获取当前计算机的串行端口名的数组
  66. /// </summary>
  67. /// <returns></returns>
  68. public static string[] getPortNames()
  69. {
  70. return SerialPort.GetPortNames();
  71. }
  72. /// <summary>
  73. /// 波特率
  74. /// </summary>
  75. /// <returns></returns>
  76. public static List<string> getBaudrateList()
  77. {
  78. return new List<string>()
  79. {
  80. "300",
  81. "600",
  82. "1200",
  83. "2400",
  84. "4800",
  85. "9600",
  86. "19200",
  87. "38400",
  88. "57600",
  89. "115200",
  90. "230400",
  91. "460800",
  92. "921600"
  93. };
  94. }
  95. #endregion
  96. #region Receive
  97. private void pushMessage()
  98. {
  99. _serialPort.DataReceived += (sender, e) =>
  100. {
  101. lock (_lock)
  102. {
  103. if (_serialPort.IsOpen == false) return;
  104. int length = _serialPort.BytesToRead;
  105. byte[] buffer = new byte[length];
  106. int readLen = _serialPort.Read(buffer, 0, length);
  107. API.OutputDebugString($"serialPort 缓存中长度:{length},实际读取长度:{readLen}.");
  108. if (readLen > 0)
  109. {
  110. _receiveCount += length;
  111. _messageQueue.Enqueue(buffer);
  112. byte[] outObj;
  113. while (queueSize > 0 && _messageQueue.Count > queueSize)
  114. {
  115. API.OutputDebugString($"serialPort 删除队列1项,队列中数量:{_messageQueue.Count},队列大小:{queueSize}");
  116. _messageQueue.TryDequeue(out outObj);
  117. }
  118. _messageWaitHandle.Set();
  119. }
  120. }
  121. };
  122. }
  123. /// <summary>
  124. /// 获取串口接受到的内容
  125. /// </summary>
  126. /// <param name="millisecondsToTimeout">取消息的超时时间</param>
  127. /// <returns>返回byte数组</returns>
  128. public byte[] getMessage(int millisecondsToTimeout = -1)
  129. {
  130. if (_messageQueue.TryDequeue(out var message))
  131. {
  132. return message;
  133. }
  134. if (_messageWaitHandle.WaitOne(millisecondsToTimeout))
  135. {
  136. if (_messageQueue.TryDequeue(out message))
  137. {
  138. return message;
  139. }
  140. }
  141. return default;
  142. }
  143. #endregion
  144. #region Send
  145. /// <summary>
  146. /// 发送消息(byte数组)
  147. /// </summary>
  148. /// <param name="buffer"></param>
  149. /// <param name="offset"></param>
  150. /// <param name="count"></param>
  151. public void send(byte[] buffer, int offset, int count)
  152. {
  153. lock (_lock)
  154. {
  155. _serialPort.Write(buffer, offset, count);
  156. //_sendCount += (count - offset);
  157. _sendCount += count;
  158. }
  159. }
  160. /// <summary>
  161. /// 发送消息(字符串)
  162. /// </summary>
  163. /// <param name="encoding">字符串编码方式,具体方式见<see cref="Encoding"/></param>
  164. /// <param name="message"></param>
  165. public void send(Encoding encoding, string message)
  166. {
  167. lock (_lock)
  168. {
  169. var buffer = encoding.GetBytes(message);
  170. _serialPort.Write(buffer, 0, buffer.Length);
  171. _sendCount += buffer.Length;
  172. }
  173. }
  174. #endregion
  175. /// <summary>
  176. /// 清空接受/发送总数统计
  177. /// </summary>
  178. public void clearCount()
  179. {
  180. lock (_lock)
  181. {
  182. _sendCount = 0;
  183. _receiveCount = 0;
  184. }
  185. }
  186. /// <summary>
  187. /// 关闭串口
  188. /// </summary>
  189. public void close()
  190. {
  191. _serialPort.Close();
  192. }
  193. }
  194. }