SerialPortHelper.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. using ProjectBase.Data.Logs;
  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;
  8. using System.Threading.Tasks;
  9. namespace SIMDP.Device
  10. {
  11. public class SerialPortHelper
  12. {
  13. public event EventSerialDataReceiveHandler serialDataReceived;
  14. /// <summary>
  15. /// 串口连接反馈事件
  16. /// </summary>
  17. /// <param name="isOpen"></param>
  18. public delegate void EventSerialOpenHandler(bool isOpen);
  19. /// <summary>
  20. /// 串口连接反馈事件
  21. /// </summary>
  22. /// <param name="isOpen"></param>
  23. public event EventSerialOpenHandler serialOpen;
  24. private int interval = 1000;
  25. private System.Timers.Timer timer = null;
  26. private SerialPort serialPort;
  27. private Thread thread;
  28. volatile bool _keepReading;
  29. // 串口是否打开
  30. public bool IsOpen
  31. {
  32. get
  33. {
  34. return serialPort.IsOpen;
  35. }
  36. }
  37. public SerialPortHelper()
  38. {
  39. }
  40. /// <summary>
  41. /// 串口通信
  42. /// </summary>
  43. /// <param name="PortNumber">端口号</param>
  44. /// <param name="baudRate">波特率</param>
  45. /// <param name="DataBits">数据位</param>
  46. public SerialPortHelper(string PortNumber, int baudRate, int DataBits)
  47. {
  48. serialPort = new SerialPort();
  49. thread = null;
  50. serialPort.PortName = PortNumber;
  51. // 波特率
  52. serialPort.BaudRate = baudRate;
  53. // 数据位
  54. serialPort.DataBits = DataBits;
  55. // 两个停止位
  56. serialPort.StopBits = System.IO.Ports.StopBits.One;
  57. // 无奇偶校验位
  58. serialPort.Parity = System.IO.Ports.Parity.None;
  59. serialPort.ReadTimeout = 100;
  60. serialPort.WriteTimeout = -1;
  61. //timer = new System.Timers.Timer(interval);
  62. //timer.Elapsed += Refresh_Elapsed;
  63. //timer.Start();
  64. Open();
  65. }
  66. /// <summary>
  67. /// 开启定时器
  68. /// </summary>
  69. //public void TimerStart()
  70. //{
  71. // timer = new System.Timers.Timer(interval);
  72. // timer.Elapsed += Refresh_Elapsed;
  73. // if (!timer.Enabled)
  74. // {
  75. // timer.Start();
  76. // }
  77. // Open();
  78. //}
  79. /// <summary>
  80. /// 定时刷新
  81. /// </summary>
  82. /// <param name="sender"></param>
  83. /// <param name="e"></param>
  84. //private void Refresh_Elapsed(object sender, ElapsedEventArgs e)
  85. //{
  86. // if (!IsOpen)
  87. // {
  88. // LogHelper.log.Debug("重新打开串口程序");
  89. // Open();
  90. // }
  91. //}
  92. /// <summary>
  93. /// 开始接收数据
  94. /// </summary>
  95. private void StartReading()
  96. {
  97. if (!_keepReading)
  98. {
  99. _keepReading = true;
  100. thread = new Thread(new ThreadStart(ReadPort));
  101. thread.IsBackground = true;
  102. thread.Start();
  103. }
  104. }
  105. /// <summary>
  106. /// 停止读取数据
  107. /// </summary>
  108. public void StopReading()
  109. {
  110. if (_keepReading)
  111. {
  112. timer.Stop();
  113. _keepReading = false;
  114. thread.Abort();
  115. thread.Join();
  116. thread = null;
  117. LogHelper.log.Debug("关闭接收线程。");
  118. }
  119. }
  120. /// <summary>
  121. /// 数据接收
  122. /// </summary>
  123. private void ReadPort()
  124. {
  125. LogHelper.log.Debug("开始接收数据。");
  126. //START:
  127. while (_keepReading)
  128. {
  129. int offset = 0;
  130. int timeout = 0;
  131. byte[] readBuffer = new byte[1024 * 8];
  132. while (IsOpen)
  133. {
  134. int count = serialPort.BytesToRead;
  135. if (count > 0)
  136. {
  137. if ((offset + count) > 1024 * 8)
  138. {
  139. break;
  140. }
  141. int readCount = serialPort.Read(readBuffer, offset, count);
  142. offset += readCount;
  143. timeout = 0;
  144. }
  145. else
  146. {
  147. break;
  148. }
  149. if (timeout > 100)
  150. {
  151. break;
  152. }
  153. timeout++;
  154. }
  155. string strData = System.Text.Encoding.Default.GetString(readBuffer).TrimEnd('\0');
  156. if (!string.IsNullOrEmpty(strData))
  157. {
  158. if (serialDataReceived != null)
  159. {
  160. SerialPortDataReceiveEventArgs receive = new SerialPortDataReceiveEventArgs(strData);
  161. serialDataReceived(receive);
  162. }
  163. LogHelper.log.Debug("接收数据完成 。");
  164. }
  165. }
  166. }
  167. /// <summary>
  168. /// 串口打开
  169. /// </summary>
  170. private void Open()
  171. {
  172. try
  173. {
  174. serialPort.Open();
  175. if (IsOpen)
  176. {
  177. _keepReading = false;
  178. StartReading();
  179. }
  180. else
  181. {
  182. LogHelper.log.Error("串口打开失败, 重新打开");
  183. serialPort.Close();
  184. Open();
  185. }
  186. if (serialOpen != null)
  187. {
  188. serialOpen(IsOpen);
  189. }
  190. }
  191. catch (Exception ex)
  192. {
  193. LogHelper.log.Error("打开串口时出现错误,错误为", ex);
  194. }
  195. }
  196. /// <summary>
  197. /// 串口关闭
  198. /// </summary>
  199. public void Close()
  200. {
  201. StopReading();
  202. serialPort.Close();
  203. if (serialOpen != null)
  204. {
  205. serialOpen(IsOpen);
  206. }
  207. }
  208. /// <summary>
  209. /// 串口写入数据
  210. /// </summary>
  211. /// <param name="send"></param>
  212. /// <param name="offSet"></param>
  213. /// <param name="count"></param>
  214. public void WritePort(byte[] send, int offSet, int count)
  215. {
  216. if (IsOpen)
  217. {
  218. LogHelper.log.Debug("开始写入数据。");
  219. serialPort.Write(send, offSet, count);
  220. }
  221. }
  222. }
  223. /// <summary>
  224. /// 串口接收数据
  225. /// </summary>
  226. public delegate void EventSerialDataReceiveHandler(SerialPortDataReceiveEventArgs e);
  227. public class SerialPortDataReceiveEventArgs : EventArgs
  228. {
  229. public string Value { get; set; }
  230. public SerialPortDataReceiveEventArgs(string value)
  231. {
  232. this.Value = value;
  233. }
  234. }
  235. }