c#串口通信并处理接收的多个参数
最近摸索做个上位机,简单记录一下关键的几个部分
c#做串口通信主要使用的是System.IO.Ports类,其实还是十分方便的
最终效果如下:

千万不要忘记了下面这个

填写串口相关配置
我们可以通过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;
            }
        }
以上的几个基本功能其实只要调用方法再加上处理异常即可
接收消息
这个接收消息就非常灵活了,说简单简单,说难也有点难,如果要求不高,只是为了展示出接收的消息,的确可以有很简单的方法
这是最简单的方法,只是单纯的将缓存区得到的字符拼接在一起,但是如果传进来的数据不只一类,我们需要将其中每一种分离出来,这种及时从缓存区取出来并拼接在一起就不太适用了,因为从缓存区取出的字符不一定是完整的
String str = serialPort1.ReadExisting();
因此,我求助于搜索引擎,了解到要解决这个问题,我们需要先将得到的字符放在缓存区中,等缓存区积攒了一定的字符再进行读取,每次提取一定的字符后,清空缓存区,将我拿到的这一串字符,转换为数组,我这个例子中有三个参数x y z,我就是将三个参数从下位机中按顺序传入,然后接收的时候以逗号作为分隔符进行拆分(我在单片机上发送消息的时候就用逗号分隔参数了),那么按顺序我们得到的数据就是x1,x2,x3···那么我们只要记录下现在处理的是哪个参数就可以按需处理了。
但是依然有不能解决的问题,就是若频率过高,处理的速度就跟不上了,但是现实情况中并不是每几毫米调用一次,所以我觉得这个问题也可以忽略不计
        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);
            }
        }
那么下一步是为其添加上一个视频面板以及遥控手柄,加油继续学习
c#串口通信并处理接收的多个参数的更多相关文章
- .NET 串口通信中断接收,包含0X1A(作为EOF)
		
.NET串口通信中将`0X1A`当做EOF处理,.NET接收到EOF会触发一次接收中断,此时事件形参`SerialDataReceivedEventArgs`值为枚举 `Eof`,其他为`Chars` ...
 - C#串口通信—向串口发送数据,同步接收返回数据
		
最近写C#串口通信程序,系统是B/S架构.SerialPort类有一个DataReceived事件,用来接收串口返回的数据,但这种方式在C/S架构下很好用,但B/S就不好处理了.所以写了一个同步模式接 ...
 - Qt串口通信接收数据不完整的解决方法
		
在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况.因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不 ...
 - Qt串口通信接收数据不完整的解决方法(传输图片)
		
在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况.因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不 ...
 - System.IO.Ports.SerialPort串口通信接收完整数据
		
C#中使用System.IO.Ports.SerialPort进行串口通信网上资料也很多,但都没有提及一些细节: 比如 串口有时候并不会一次性把你想要的数据全部传输给你,可能会分为1次,2次,3次分别 ...
 - Java实现RS485串口通信,发送和接收数据进行解析
		
最近项目有一个空气检测仪,需要得到空气检测仪的实时数据,保存到数据库当中.根据了解得到,硬件是通过rs485进行串口通讯的,需要发送16进制命令给仪器,然后通过轮询来得到数据. 需要先要下载RXTX的 ...
 - .NET 串口通信
		
这段时间做了一个和硬件设备通信的小项目,涉及到扫描头.输送线.称重机.贴标机等硬件.和各设备之间通信使用的是串口或网络(Socket)的方式.扫描头和贴标机使用的网络通信,输送线和称重机使用的是串口通 ...
 - BluetoothChat用于蓝牙串口通信的修改方法
		
本人最近在研究嵌入式的串口通信,任务是要写一个手机端的遥控器用来遥控双轮平衡小车.界面只用了一个小时就写好了,重要的问题是如何与板子所带的SPP-CA蓝牙模块进行通信. SPP-CA模块自带代码,在这 ...
 - Win10 IoT C#开发 4 - UART 串口通信
		
Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,既可以开发设备UI与用户交互式操作,又可以控制GPIO等接口,使得原来嵌入式繁琐的开发变得简单.通过Remote Debug ...
 
随机推荐
- NRF51802蓝牙4.0BLE
			
今天给大家介绍一款NRF51802的芯片 它是NRF51822的COSTDOWN精简版 本质上跟NRF51822是一致的,原厂为了给大客户节省成本而定制的一个版本 可以跟NRF51822软件硬件完全兼 ...
 - windows下RocketMQ下载安装教程
			
一.下载(原文链接:http://www.studyshare.cn/software/details/1183/0 ) 1.官网下载:下载地址 2.百度网盘下载:下载地址 提取码:0g5a ja ...
 - Springboot结合Redis
			
安装 Redis 安装 gcc Yum install gcc-c++ 解压 redis.3.0.0.tar.gz 压缩包 tar -zxvf redis-3.0.0.tar.gz 进入解压后的目 ...
 - 数据库Oracle  数字,字符,日期之间的相互转换
			
数据类型转换分为俩种 . 隐式数据类型转换:当源数据的类型和目标数据的类型不同的时候,如果没有转换函数,就会发生隐式转换,也称自动转换. 对于直接赋值转换: 对于表达式赋值: 隐式转换的问题: 性能 ...
 - [TimLinux] systemd 精通CentOS7系统启动systemd
			
1. 介绍 systemd: 在12种不同类型的实体单元(entity unit)间提供了一个依赖关系系统. 2. 几个概念 实体单元:为系统的启动和维护封装多种对象(object).主体单元在单元配 ...
 - CodeForces1000A- Codehorses T-shirts
			
A. Codehorses T-shirts time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
 - ARTS-S docker安装miniconda
			
FROM centos:centos7.3.1611 MAINTAINER zhouyang3 <aaa@qq.com> WORKDIR /usr/local ADD ./ /usr/lo ...
 - FPGA_VIP_V101 视频开发板 深入调试小结
			
FPGA_VIP_V101 推出已经有半年有余,各项功能例程已移植完毕,主要参考crazybingo例程进行移植和结合开发板设计了几个实例例程 主要包含: 硬件配置: FPGA:EP4CE6E22C8 ...
 - nginx代理grafana
			
希望通过Nginx为服务器上的grafana进行代理,实现通过在当前域名后加/grafana在公网进行访问,开始按照百度的方法弄了几个小时都不行,后面仔细看了官方的文档才弄好,Mark一下. Ngin ...
 - Ubuntu系统下arm-linux-gcc交叉编译环境搭建过程
			
搭建所需环境Linux版本:Ubuntu 14.10 交叉编译器版本:arm-linux-gcc-4.4.3资源链接 何为交叉编译环境搭建交叉编译环境,即安装.配置交叉编译工具链.在Ubuntu环境下 ...