C# 串口类SerialPort的使用方法
序言:最近做了一个智能体育项目——跆拳道积分系统,硬件部分会向软件传入振动值等数据,链接方式为串口,所以用到SerialPort类。
值得注意的是:
DataReceived 方法,当串口缓冲区有数据时执行该方法。
ReceivedBytesThreshold属性决定了当串口读缓存中数据多少个时才触发DataReceived事件,默认为1。串口接收的指令可能是错误值,所以这块根据自己需求进行设置。
首先需要引用SerialPort
using System.IO.Ports;
创建全局串口对象
SerialPort com;
SerialPort配置,并打开端口进行接收数据
private void Form1_Load(object sender, EventArgs e) { com = new SerialPort("COM5"); //实例化SerialPort并设置COM口 com.BaudRate = 115200;//波特率 com.Parity = Parity.None;//无奇偶校验位 com.StopBits = StopBits.Two;//两个停止位 com.Handshake = Handshake.RequestToSend;//控制协议 com.ReceivedBytesThreshold = 13;//设置 DataReceived 事件发生前内部输入缓冲区中的字节数,我这里是13字节为一组 com.Open(); //打开串口 com.DataReceived += new SerialDataReceivedEventHandler(Com_DataReceived); //接受数据线程 }
/// <summary> /// 监听串口数据线程 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Com_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { if (com.IsOpen) { byte[] readBuffer = new byte[com.ReadBufferSize + 1]; try { int count = com.Read(readBuffer, 0, com.ReadBufferSize); //读取串口数据(监听) //String SerialIn = System.Text.Encoding.ASCII.GetString(readBuffer, 0, count); if (count != 0) { //将返回值byte数组转换为string类型数据 String result = bytesToHexString(readBuffer); //这里强调一下,线程里不可以直接对UI进行赋值 this.BeginInvoke(new System.Threading.ThreadStart(delegate () { textBox1.Text = result; //对控件进行赋值 })); } } catch (TimeoutException) { } } else { TimeSpan waitTime = new TimeSpan(0, 0, 0, 0, 50); Thread.Sleep(waitTime); } } catch (Exception ex) { } }
Byte数组转换成16进制方法
/// <summary> /// Byte数组转换成16进制 /// </summary> /// <param name="bArr"></param> /// <returns></returns> String bytesToHexString(byte[] bArr) { string result = string.Empty; for (int i = 0; i < 13; i++)//逐字节变为16进制字符,以%隔开 { result += Convert.ToString(bArr[i], 16).ToUpper().PadLeft(2, '0') + " "; } return result; }
发送数据
/// <summary> /// 发送数据 /// </summary> void SendData() { Byte[] TxData = { 1, 2, 3, 4, 5, 6, 7, 8 }; com.Write(TxData, 0, 8); }
续补:串口数据接受不完整处理方法
/// <summary> /// 监听串口数据线程 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Com_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { if (com.IsOpen) { try { int byteNumber = com.BytesToRead; Thread.Sleep(20); //延时等待数据接收完毕。 while ((byteNumber < com.BytesToRead) && (com.BytesToRead < 4800)) { byteNumber = com.BytesToRead; Thread.Sleep(20); } int n = com.BytesToRead; //记录下缓冲区的字节个数 byte[] buf = new byte[n]; //声明一个临时数组存储当前来的串口数据 com.Read(buf, 0, n); //读取缓冲数据到buf中,同时将这串数据从缓冲区移除 //设置文字显示 Control.CheckForIllegalCrossThreadCalls = false; StringBuilder sb = new StringBuilder(); for (int i = 0; i < n; i++) { string s; if (buf[i] < 16) s = "0" + Convert.ToString(buf[i], 16).ToUpper() + " "; else s = Convert.ToString(buf[i], 16).ToUpper() + " "; sb.Append(s); } textBox3.Text += sb.ToString() +"\r\n"; } catch (Exception ee) { } } else { TimeSpan waitTime = new TimeSpan(0, 0, 0, 0, 50); Thread.Sleep(waitTime); } Thread.Sleep(200); } catch (Exception ex) { } }
到这里就结束了,网上也有一些测试串口数据的程序,我这也有一个但是不记得在哪里下载的了,如果有需要跟我吱一声~