ClsSerialPort.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Threading;
  7. using System.IO.Ports;
  8. using System.Windows.Forms;
  9. namespace ns_Comm
  10. {
  11. public class ClsSerialPort
  12. {
  13. #region normal serialPort
  14. public static Dictionary<string, SerialPort> dictSerialPort = new Dictionary<string, SerialPort>();
  15. public static int iSerialPortNo = 0;
  16. public static string[] arrStrPortList;
  17. public ClsSerialPort()
  18. {
  19. for(int i = 0;i < PortNameList().Length;i++)
  20. {
  21. CreatSerialPort(arrStrPortList[i], "9600", "8", "NONE", "1");
  22. }
  23. }
  24. public static string[] PortNameList()//获取当前计算机串口名称数组
  25. {
  26. string[] arrStrPortList = SerialPort.GetPortNames();//获取当前计算机串口名称数组
  27. if (arrStrPortList.Length < 1)
  28. {
  29. MessageBox.Show("本机没有串口!", "Error");
  30. return null;
  31. }
  32. else
  33. {
  34. return arrStrPortList;
  35. }
  36. }
  37. public static bool CreatSerialPort(string portName, string baudRate, string dataBit, string parity, string stopBit)
  38. {
  39. try
  40. {
  41. SerialPort serialPort = new SerialPort();
  42. serialPort.PortName = portName;
  43. serialPort.BaudRate = Convert.ToInt32(baudRate);
  44. serialPort.DataBits = Convert.ToInt32(dataBit);
  45. switch (parity)
  46. {
  47. case "NONE":
  48. serialPort.Parity = Parity.None;
  49. break;
  50. case "ODD":
  51. serialPort.Parity = Parity.Odd;
  52. break;
  53. case "EVEN":
  54. serialPort.Parity = Parity.Even;
  55. break;
  56. case "Space":
  57. serialPort.Parity = Parity.Space;
  58. break;
  59. case "Mark":
  60. serialPort.Parity = Parity.Mark;
  61. break;
  62. }
  63. switch (stopBit)
  64. {
  65. case "1":
  66. serialPort.StopBits = StopBits.One;
  67. break;
  68. case "1.5":
  69. serialPort.StopBits = StopBits.OnePointFive;
  70. break;
  71. case "2":
  72. serialPort.StopBits = StopBits.Two;
  73. break;
  74. }
  75. //if (!listSerialPort.Contains(serialPort))
  76. //{
  77. // listSerialPort.Add(serialPort);
  78. //}
  79. //serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
  80. if(dictSerialPort.ContainsKey(portName))
  81. {
  82. if (serialPort.IsOpen) return true;
  83. dictSerialPort.Remove(portName);
  84. Thread.Sleep(100);
  85. }
  86. dictSerialPort.Add(portName, serialPort);
  87. return true;
  88. }
  89. catch (Exception exx)
  90. {
  91. MessageBox.Show(exx.ToString());
  92. return false;
  93. }
  94. }
  95. private static void DataReceived(object sender, SerialDataReceivedEventArgs e)
  96. {
  97. SerialPort sp = (SerialPort)sender;
  98. if (dictSerialPort.ContainsValue(sp))
  99. {
  100. }
  101. }
  102. public static void SerialOpen(SerialPort sp)
  103. {
  104. if (!sp.IsOpen)
  105. {
  106. try
  107. {
  108. sp.Open();
  109. }
  110. catch (Exception ex)
  111. {
  112. MessageBox.Show(ex.ToString());
  113. }
  114. }
  115. else
  116. {
  117. MessageBox.Show("当前串口已打开\r\nThe serial port is currently open");
  118. }
  119. }
  120. /// <summary>
  121. /// 创建并打开指定串口
  122. /// </summary>
  123. /// <param name="portName"></param>
  124. /// <param name="baudRate"></param>
  125. /// <param name="dataBit"></param>
  126. /// <param name="parity"></param>
  127. /// <param name="stopBit"></param>
  128. /// <returns></returns>
  129. public SerialPort CreatSerialPort1(string portName, string baudRate, string dataBit, string parity, string stopBit)
  130. {
  131. SerialPort serialPort = new SerialPort();
  132. try
  133. {
  134. serialPort.PortName = portName;
  135. serialPort.BaudRate = Convert.ToInt32(baudRate);
  136. serialPort.DataBits = Convert.ToInt32(dataBit);
  137. switch (parity)
  138. {
  139. case "NONE":
  140. serialPort.Parity = System.IO.Ports.Parity.None;
  141. break;
  142. case "ODD":
  143. serialPort.Parity = System.IO.Ports.Parity.Odd;
  144. break;
  145. case "EVEN":
  146. serialPort.Parity = System.IO.Ports.Parity.Even;
  147. break;
  148. }
  149. switch (stopBit)
  150. {
  151. case "1":
  152. serialPort.StopBits = System.IO.Ports.StopBits.One;
  153. break;
  154. case "1.5":
  155. serialPort.StopBits = System.IO.Ports.StopBits.OnePointFive;
  156. break;
  157. case "2":
  158. serialPort.StopBits = System.IO.Ports.StopBits.Two;
  159. break;
  160. }
  161. if (!serialPort.IsOpen)
  162. {
  163. try
  164. {
  165. serialPort.Open();
  166. }
  167. catch (Exception ex)
  168. {
  169. MessageBox.Show(ex.ToString());
  170. }
  171. }
  172. return serialPort;
  173. }
  174. catch (Exception exx)
  175. {
  176. MessageBox.Show(exx.ToString());
  177. return null;
  178. }
  179. }
  180. public static void SerialPortSendData(SerialPort sp, string strData)
  181. {
  182. try
  183. {
  184. if (!sp.IsOpen)
  185. {
  186. MessageBox.Show("当前串口未打开\r\nThe serial port is not open");
  187. return;
  188. }
  189. byte[] sendBuffer;
  190. sendBuffer = Encoding.ASCII.GetBytes(strData + "\r\n");//将字符串中的所有字符编码为一个字节序列
  191. //(txtSend.Text+"\r\n").ToCharArray();//将字符复制到Unicode字符数组,将字符串转换为字符数组
  192. sp.DiscardOutBuffer();//清除缓冲区里的内容
  193. sp.DiscardInBuffer();
  194. sp.Write(sendBuffer, 0, sendBuffer.Length);//发送数据
  195. }
  196. catch (Exception ex)
  197. {
  198. MessageBox.Show(ex.ToString());
  199. }
  200. }
  201. public static void SerialPortSendData(SerialPort sp, byte[] byteArrayData) //Modbus发送
  202. {
  203. try
  204. {
  205. if (!sp.IsOpen)
  206. {
  207. MessageBox.Show("当前串口未打开\r\nThe serial port is not open");
  208. return;
  209. }
  210. sp.DiscardOutBuffer();//清除缓冲区里的内容
  211. sp.DiscardInBuffer();
  212. sp.Write(byteArrayData, 0, byteArrayData.Length);//发送数据
  213. }
  214. catch (Exception ex)
  215. {
  216. MessageBox.Show(ex.ToString());
  217. }
  218. }
  219. public static object lockRecv = new object();
  220. public static string SerialPortReceiveData(SerialPort sp)
  221. {
  222. lock (lockRecv)
  223. {
  224. byte[] readBuffer;
  225. int length = 0;
  226. string strReceive;
  227. if (!sp.IsOpen)
  228. {
  229. MessageBox.Show("请打开串口", "Error");
  230. return "error";
  231. }
  232. try
  233. {
  234. int i = 0;
  235. do
  236. {
  237. i++;
  238. Thread.Sleep(10);
  239. if (i > 500) break;
  240. } while (sp.BytesToRead < 5 );//等待读到所有数据设定读取时间
  241. length = sp.BytesToRead;//获取接收缓冲区中数据的字节数
  242. if (length <= 0) return string.Empty;
  243. readBuffer = new byte[length];//创建字节数组
  244. sp.Read(readBuffer, 0, length);
  245. strReceive = Encoding.ASCII.GetString(readBuffer, 0, readBuffer.Length);
  246. if (i >= 500)
  247. {
  248. // MessageBox.Show($"读取串口{sp.PortName}超时--2秒!");
  249. }
  250. i = 0;
  251. return strReceive;
  252. }
  253. catch (Exception ex)
  254. {
  255. MessageBox.Show(ex.ToString());
  256. return "error";
  257. }
  258. }
  259. }
  260. /// <summary>
  261. /// 发送数据并接收数据
  262. /// </summary>
  263. /// <param name="sp"></param>
  264. /// <param name="sendCommand"></param>
  265. /// <returns></returns>
  266. public string SerialSendAndReceive(SerialPort sp, string sendCommand)
  267. {
  268. try
  269. {
  270. byte[] sendBuffer;
  271. byte[] readBuffer;
  272. int length = 0;
  273. sendBuffer = Encoding.ASCII.GetBytes(sendCommand + "\r\n");//将字符串中的所有字符编码为一个字节序列
  274. //(txtSend.Text+"\r\n").ToCharArray();//将字符复制到Unicode字符数组,将字符串转换为字符数组
  275. sp.DiscardOutBuffer();//清除缓冲区里的内容
  276. sp.Write(sendBuffer, 0, sendBuffer.Length);//发送数据
  277. int i = 0;
  278. do
  279. {
  280. i++;
  281. Thread.Sleep(50);
  282. } while (sp.BytesToRead < 10 && i < 200);//等待读到所有数据设定读取时间
  283. string strReceive;
  284. length = sp.BytesToRead;//获取接收缓冲区中数据的字节数
  285. readBuffer = new byte[length];
  286. sp.Read(readBuffer, 0, length);
  287. strReceive = Encoding.ASCII.GetString(readBuffer, 0, readBuffer.Length);
  288. i = 0;
  289. return strReceive;
  290. }
  291. catch (Exception ex)
  292. {
  293. MessageBox.Show(ex.ToString());
  294. return ex.ToString();
  295. }
  296. }
  297. public static void SerialClose(SerialPort sp)
  298. {
  299. try
  300. {
  301. sp.Close();
  302. }
  303. catch { }
  304. }
  305. #endregion
  306. }
  307. }