You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

248 lines
7.1 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO.Ports;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using HBLConsole.Model;
  8. using HBLConsole.Service;
  9. namespace HBLConsole.Communication
  10. {
  11. public class SerialPortClient
  12. {
  13. #region 变量属性
  14. private DataStorage<byte> dataStorage;
  15. public event SerialErrorReceivedEventHandler ErrorReceived;
  16. private SerialPort comPort = new SerialPort();
  17. private string portName = "COM1";//串口号,默认COM1
  18. private BaudRates baudRate = BaudRates.BR_9600;//波特率
  19. private Parity parity = Parity.None;//校验位
  20. private StopBits stopBits = StopBits.One;//停止位
  21. private DataBits dataBits = DataBits.Eight;//数据位
  22. /// <summary>
  23. /// 串口号
  24. /// </summary>
  25. public string PortName
  26. {
  27. get { return portName; }
  28. set { portName = value; }
  29. }
  30. /// <summary>
  31. /// 波特率
  32. /// </summary>
  33. public BaudRates BaudRate
  34. {
  35. get { return baudRate; }
  36. set { baudRate = value; }
  37. }
  38. #endregion
  39. #region 构造函数
  40. /// <summary>
  41. /// 无参构造函数
  42. /// </summary>
  43. public SerialPortClient(string name, BaudRates baud)
  44. {
  45. this.portName = name;
  46. this.baudRate = baud;
  47. BoundEvents();
  48. }
  49. void BoundEvents()
  50. {
  51. comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
  52. comPort.ErrorReceived += new SerialErrorReceivedEventHandler(comPort_ErrorReceived);
  53. }
  54. /// <summary>
  55. /// 参数构造函数(使用枚举参数构造)
  56. /// </summary>
  57. /// <param name="baud">波特率</param>
  58. /// <param name="par">奇偶校验位</param>
  59. /// <param name="sBits">停止位</param>
  60. /// <param name="dBits">数据位</param>
  61. /// <param name="name">串口号</param>
  62. public SerialPortClient(string name, BaudRates baud, Parity par, DataBits dBits, StopBits sBits)
  63. {
  64. this.portName = name;
  65. this.baudRate = baud;
  66. this.parity = par;
  67. this.dataBits = dBits;
  68. this.stopBits = sBits;
  69. BoundEvents();
  70. }
  71. /// <summary>
  72. /// 参数构造函数(使用字符串参数构造)
  73. /// </summary>
  74. /// <param name="baud">波特率</param>
  75. /// <param name="par">奇偶校验位</param>
  76. /// <param name="sBits">停止位</param>
  77. /// <param name="dBits">数据位</param>
  78. /// <param name="name">串口号</param>
  79. public SerialPortClient(string name, string baud, string par, string dBits, string sBits)
  80. {
  81. this.portName = name;
  82. this.baudRate = (BaudRates)Enum.Parse(typeof(BaudRates), baud);
  83. this.parity = (Parity)Enum.Parse(typeof(Parity), par);
  84. this.dataBits = (DataBits)Enum.Parse(typeof(DataBits), dBits);
  85. this.stopBits = (StopBits)Enum.Parse(typeof(StopBits), sBits);
  86. BoundEvents();
  87. }
  88. #endregion
  89. #region 事件处理函数
  90. /// <summary>
  91. /// 数据接收处理
  92. /// </summary>
  93. void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
  94. {
  95. if (comPort.IsOpen) //判断是否打开串口
  96. {
  97. byte[] receivedData = new byte[comPort.BytesToRead]; //创建接收字节数组
  98. comPort.Read(receivedData, 0, receivedData.Length); //读取数据
  99. //触发整条记录的处理
  100. if (dataStorage != null)
  101. {
  102. dataStorage.PutData(receivedData);
  103. }
  104. }
  105. else
  106. {
  107. Console.WriteLine("请打开某个串口", "Error");
  108. }
  109. }
  110. /// <summary>
  111. /// 错误处理函数
  112. /// </summary>
  113. void comPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
  114. {
  115. if (ErrorReceived != null)
  116. {
  117. ErrorReceived(sender, e);
  118. }
  119. }
  120. #endregion
  121. #region 串口关闭/打开
  122. /// <summary>
  123. /// 端口是否已经打开
  124. /// </summary>
  125. public bool IsOpen
  126. {
  127. get
  128. {
  129. return comPort.IsOpen;
  130. }
  131. }
  132. /// <summary>
  133. /// 判断是否有这个串口
  134. /// </summary>
  135. public bool IsHavePort => SerialPort.GetPortNames().Contains(PortName);
  136. /// <summary>
  137. /// 打开端口
  138. /// </summary>
  139. /// <returns></returns>
  140. public void Open()
  141. {
  142. lock (lck4Serial)
  143. {
  144. if (!IsHavePort) return;
  145. if (comPort.IsOpen) comPort.Close();
  146. comPort.PortName = portName;
  147. comPort.BaudRate = (int)baudRate;
  148. comPort.Parity = parity;
  149. comPort.DataBits = (int)dataBits;
  150. comPort.StopBits = stopBits;
  151. comPort.Open();
  152. }
  153. }
  154. /// <summary>
  155. /// 关闭端口
  156. /// </summary>
  157. public void Close()
  158. {
  159. if (!IsHavePort) return;
  160. if (comPort.IsOpen) comPort.Close();
  161. }
  162. /// <summary>
  163. /// 丢弃来自串行驱动程序的接收和发送缓冲区的数据
  164. /// </summary>
  165. public void DiscardBuffer()
  166. {
  167. comPort.DiscardInBuffer();
  168. comPort.DiscardOutBuffer();
  169. }
  170. #endregion
  171. private object lck4Serial = new object();
  172. #region 写入数据
  173. /// <summary>
  174. /// 写入数据
  175. /// </summary>
  176. /// <param name="buffer"></param>
  177. public void Write(byte[] buffer, int offset, int count)
  178. {
  179. lock (lck4Serial)
  180. {
  181. if (!IsHavePort) return;
  182. if (!(comPort.IsOpen)) comPort.Open();
  183. comPort.Write(buffer, offset, count);
  184. }
  185. }
  186. /// <summary>
  187. /// 读取数据
  188. /// </summary>
  189. /// <returns></returns>
  190. public byte[] Read()
  191. {
  192. lock (lck4Serial)
  193. {
  194. if (!IsHavePort) return new byte[0];
  195. if (!(comPort.IsOpen)) comPort.Open();
  196. byte[] buffer = new byte[1024];
  197. comPort.Read(buffer, 0, buffer.Length);
  198. return buffer;
  199. }
  200. }
  201. public void Start()
  202. {
  203. Open();
  204. }
  205. public void Stop()
  206. {
  207. Close();
  208. }
  209. /// <summary>
  210. /// 发送数据
  211. /// </summary>
  212. /// <param name="data">发送数据</param>
  213. public void SendData(byte[] data)
  214. {
  215. Write(data, 0, data.Length);
  216. }
  217. public void SetDataStorage(DataStorage<byte> dataStorage)
  218. {
  219. this.dataStorage = dataStorage;
  220. }
  221. #endregion
  222. }
  223. }