最近摸索作个上位机,简单记录一下关键的几个部分html
c#作串口通讯主要使用的是System.IO.Ports类,其实仍是十分方便的
最终效果以下:
千万不要忘记了下面这个
c#
咱们能够经过GetPortNames方法获取本机的端口列表,注意:不一样设备链接电脑后端口不必定相同后端
string[] sps = SerialPort.GetPortNames();
配置其余串口相关
例如波特率列表数组
string[] baud = { "300", "1200", "2400", "4800", "9600", "19200", "38400", "57600" }; comboBox2.Items.AddRange(baud); //添加波特率列表
其实主要就是用当前串口属性判断是不是打开状态缓存
private void Button1_Click(object sender, EventArgs e) { //trycatcj处理串口打开过程当中的异常 try { //将可能产生异常的代码放置在try块中 //根据当前串口属性来判断是否打开 if (serialPort1.IsOpen) { //串口已经处于打开状态 serialPort1.Close(); //关闭串口 button1.Text = "打开串口"; button1.BackColor = Color.ForestGreen; comboBox1.Enabled = true; comboBox2.Enabled = true; comboBox3.Enabled = true; comboBox4.Enabled = true; comboBox5.Enabled = true; ReceptTb.Text = ""; //清空接收区 SendTb.Text = ""; //清空发送区 } else { //串口已经处于关闭状态,则设置好串口属性后打开 comboBox1.Enabled = false; comboBox2.Enabled = false; comboBox3.Enabled = false; comboBox4.Enabled = false; comboBox5.Enabled = false; serialPort1.PortName = comboBox1.Text; serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text); serialPort1.DataBits = Convert.ToInt16(comboBox3.Text); if (comboBox4.Text.Equals("None")) serialPort1.Parity = System.IO.Ports.Parity.None; else if (comboBox4.Text.Equals("Odd")) serialPort1.Parity = System.IO.Ports.Parity.Odd; else if (comboBox4.Text.Equals("Even")) serialPort1.Parity = System.IO.Ports.Parity.Even; else if (comboBox4.Text.Equals("Mark")) serialPort1.Parity = System.IO.Ports.Parity.Mark; else if (comboBox4.Text.Equals("Space")) serialPort1.Parity = System.IO.Ports.Parity.Space; if (comboBox5.Text.Equals("1")) serialPort1.StopBits = System.IO.Ports.StopBits.One; else if (comboBox5.Text.Equals("1.5")) serialPort1.StopBits = System.IO.Ports.StopBits.OnePointFive; else if (comboBox5.Text.Equals("2")) serialPort1.StopBits = System.IO.Ports.StopBits.Two; serialPort1.Open(); //打开串口 button1.Text = "关闭串口"; button1.BackColor = Color.Firebrick; this.Activate(); } } catch (Exception ex) { //捕获可能发生的异常并进行处理 //捕获到异常,建立一个新的对象,以前的不能够再用 serialPort1 = new System.IO.Ports.SerialPort(); //刷新COM口选项 comboBox1.Items.Clear(); comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames()); //响铃并显示异常给用户 System.Media.SystemSounds.Beep.Play(); button1.Text = "打开串口"; button1.BackColor = Color.ForestGreen; MessageBox.Show(ex.Message); comboBox1.Enabled = true; comboBox2.Enabled = true; comboBox3.Enabled = true; comboBox4.Enabled = true; comboBox5.Enabled = true; } }
这个也没有太多特别的,只要调用Write方法便可学习
private void SendBtn_Click(object sender, EventArgs e) { try { Console.WriteLine(serialPort1.IsOpen); //首先判断串口是否开启 if (serialPort1.IsOpen) { //串口处于开启状态,将发送区文本发送 serialPort1.Write(SendTb.Text); SendTb.Text = ""; } } catch (Exception ex) { //捕获到异常,建立一个新的对象,以前的不能够再用 serialPort1 = new System.IO.Ports.SerialPort(); //刷新COM口选项 comboBox1.Items.Clear(); comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames()); //响铃并显示异常给用户 System.Media.SystemSounds.Beep.Play(); button1.Text = "打开串口"; button1.BackColor = Color.ForestGreen; MessageBox.Show(ex.Message); comboBox1.Enabled = true; comboBox2.Enabled = true; comboBox3.Enabled = true; comboBox4.Enabled = true; comboBox5.Enabled = true; } }
以上的几个基本功能其实只要调用方法再加上处理异常便可ui
这个接收消息就很是灵活了,说简单简单,说难也有点难,若是要求不高,只是为了展现出接收的消息,的确能够有很简单的方法this
这是最简单的方法,只是单纯的将缓存区获得的字符拼接在一块儿,可是若是传进来的数据不仅一类,咱们须要将其中每一种分离出来,这种及时从缓存区取出来并拼接在一块儿就不太适用了,由于从缓存区取出的字符不必定是完整的搜索引擎
String str = serialPort1.ReadExisting();
所以,我求助于搜索引擎,了解到要解决这个问题,咱们须要先将获得的字符放在缓存区中,等缓存区积攒了必定的字符再进行读取,每次提取必定的字符后,清空缓存区,将我拿到的这一串字符,转换为数组,我这个例子中有三个参数x y z,我就是将三个参数从下位机中按顺序传入,而后接收的时候以逗号做为分隔符进行拆分(我在单片机上发送消息的时候就用逗号分隔参数了),那么按顺序咱们获得的数据就是x1,x2,x3···那么咱们只要记录下如今处理的是哪一个参数就能够按需处理了。
可是依然有不能解决的问题,就是若频率太高,处理的速度就跟不上了,可是现实状况中并非每几毫米调用一次,因此我以为这个问题也能够忽略不计rest
private void SerialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { try { //由于要访问UI资源,因此须要使用invoke方式同步ui this.Invoke((EventHandler)(delegate { int byteNumber = serialPort1.BytesToRead; Thread.Sleep(20); //延时等待数据接收完毕。 while ((byteNumber < serialPort1.BytesToRead) && (serialPort1.BytesToRead < 77)) { byteNumber = serialPort1.BytesToRead; Thread.Sleep(20); } int n = serialPort1.BytesToRead; //记录下缓冲区的字节个数 //Console.WriteLine("n" + n); byte[] buf = new byte[n]; //声明一个临时数组存储当前来的串口数据 serialPort1.Read(buf, 0, n); //读取缓冲数据到buf中,同时将这串数据从缓冲区移除 string str = System.Text.Encoding.Default.GetString(buf); string[] strArray = str.Split(','); int count = 0; for (int i = 0; i < strArray.Length; i++) { if(count == 0) { textBox1.Text = strArray[i]; }else if(count == 1) { textBox2.Text = strArray[i]; }else if(count == 2) { textBox3.Text = strArray[i]; } count++; if(count == 3) { count = 0; } } } ) ); } catch (Exception ex) { //响铃并显示异常给用户 System.Media.SystemSounds.Beep.Play(); MessageBox.Show(ex.Message); } }
那么下一步是为其添加上一个视频面板以及遥控手柄,加油继续学习