c#串口通信并处理接收的多个参数

最近摸索做个上位机,简单记录一下关键的几个部分

c#做串口通信主要使用的是System.IO.Ports类,其实还是十分方便的
最终效果如下:
1394463-20190602012308496-1202593183.png
千万不要忘记了下面这个
1394463-20190602012611593-1419826339.png

填写串口相关配置

我们可以通过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);

            }
        }

那么下一步是为其添加上一个视频面板以及遥控手柄,加油继续学习

参考来源:https://www.cnblogs.com/Mculover666/p/9128906.html

转载于:https://www.cnblogs.com/yuyuan-bb/p/10961755.html

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#串口介绍以及简单串口通信程序设计实现 源代码和串口程序介绍连接:https://www.cnblogs.com/JiYF/p/6618696.html 本站积分太贵,自己变得。。直接到连接地址下载代码 周末,没事干,写个简单的串口通信工具,也算是本周末曾来过,废话不多,直接到主题 串口介绍   串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。(至于再详细,自己百度) 串口应用:   工业领域使用较多,比如:数据采集,设备控制等等,好多都是用串口通信来实现!你要是细心的话,你会发现,目前家用国网智能电能表就具备RS485通信总线(串行总线的一种)与RS232可以相互转化(当然一般,非专业的谁也不会闲的蛋疼,趴电表上瞎看,最多也就看看走了多少度电) RS232 DB9介绍: 1.示意图 2.针脚介绍: 载波检测(DCD) 接受数据(RXD) 发出数据(TXD) 数据终端准备好(DTR) 信号地线(SG) 数据准备好(DSR) 请求发送(RTS) 清除发送(CTS) 振铃指示(RI) 3.实物图: 以下是我购买XX公司的一个usb转串口线:这个头就是一个公头,另一端是一个usb口 笨小孩串口工具运行图: 1.开启程序 2.发送一行字符串HelloBenXH,直接将针脚的发送和接收链接起来就可以测试了(针脚2 接受数据(RXD) 和3 发出数据(TXD))直接链接, C#代码实现:采用SerialPort 1.实例化一个SerialPort [csharp] view plain copy 在CODE上查看代码片派生到我的代码片 private SerialPort ComDevice = new SerialPort(); 2.初始化参数绑定接收数据事件 [csharp] view plain copy 在CODE上查看代码片派生到我的代码片 public void init() { btnSend.Enabled = false; cbbComList.Items.AddRange(SerialPort.GetPortNames()); if (cbbComList.Items.Count > 0) { cbbComList.SelectedIndex = 0; } cbbBaudRate.SelectedIndex = 5; cbbDataBits.SelectedIndex = 0; cbbParity.SelectedIndex = 0; cbbStopBits.SelectedIndex = 0; pictureBox1.BackgroundImage = Properties.Resources.red; ComDevice.DataReceived += new SerialDataReceivedEventHandler(Com_DataReceived);//绑定事件 }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值