Winform串口编程---接收数据demo(VSPD虚拟串口)

参考地址:https://blog.csdn.net/memgxingfeixiang/article/details/52513970

     https://blog.csdn.net/kevin_iot/article/details/53926599

 

一、需求概述

     应用场景:winform中能接收到串口发送的数据。

   所需软件: Configure Virtual Serial Port Driver(虚拟串口模拟软件)、串口调试助手。

二、效果展示(很简陋,捂脸中......)

  

  说明:cmbPort是电脑上所有串口的列表,txtReciveData是每次该串口接收的数据,btnOpenOrClose按钮是控制打开/关闭串口。

三、具体实现:

 (1)先在Load事件里将comPort控件绑定电脑串口列表,代码如下:

 1             #region 初始化电脑上的串口列表
 2             foreach (string sPort in SerialPort.GetPortNames())
 3             {
 4                 cmbPort.Items.Add(sPort);
 5             }
 6 
 7             //串口设置默认选项
 8             if (cmbPort.Items.Count>0)
 9             {
10                 cmbPort.SelectedIndex = 0;
11             }
12             #endregion

     (2)编写btnOpenOrClose点击事件

 1         /// <summary>
 2         /// 打开/关闭串口
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         private void btnOpenOrClose_Click(object sender, EventArgs e)
 7         {
 8             try
 9             {
10                 if (btnOpenOrClose.Text == "打开串口")
11                 {
12                     btnOpenOrClose.Text = "关闭串口";
13                     //设置串口的基本属性
14                     serialPort.PortName = cmbPort.SelectedItem.ToString();
15                     serialPort.BaudRate = 9600;
16                     serialPort.Parity = Parity.None;
17                     serialPort.DataBits = 8;
18                     serialPort.StopBits = StopBits.One;
19                     serialPort.Open();
20                 }
21                 else
22                 {
23                     btnOpenOrClose.Text = "打开串口";
24                     serialPort.Close();
25                 }
26             }
27             catch (Exception ex)
28             {
29                 MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
30                 return;
31             }
32         }

(3)编写接收串口数据方法

 1         void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
 2         {
 3             try
 4             {
 5                 Byte[] InputBuf = new Byte[128];
 6                 serialPort.Read(InputBuf, 0, serialPort.BytesToRead);
 7 
 8                 ASCIIEncoding encoding = new ASCIIEncoding();
 9                 data = encoding.GetString(InputBuf);
10                 new Thread(SetReceiveData).Start();
11                 //直接调用会报错-------从不是创建控件”txtContent”的线程访问它
12                 //SetReceiveData();
13             }
14             catch (Exception ex)
15             {
16                 MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
17                 return;
18             }
19         }

    接收数据成功,调用下面的方法,将发送的数据显示到文本框中。

 1         /// <summary>
 2         /// (将接收的数据显示到文本框中)不懂这一块的实现逻辑,需要加深理解线程的相关概念
 3         /// </summary>
 4         public void SetReceiveData()
 5         {
 6             lock (this)
 7 
 8                 Invoke(new MethodInvoker(delegate ()
 9 
10                 {
11 
12                     this.txtReciveData.Text = data;
13 
14                 }));
15 
16         }

    在load事件中将订阅该事件

            //为串口加上数据接收事件
            serialPort.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);

四:模拟串口发送数据

       (1)打开vspd软件,虚拟出两个COM1和COM2两个串口

(2)打开串口调试助手,一个是COM1,另外一个是COM2,将两个串口的波特率设置为一样。

测试一下,两个串口是否能正常通讯。

 (3)关掉其中的一个串口调试助手,留下COM2的串口调试助手,我们在程序中用COM1口接收数据。(winform中要先点击“打开串口”按钮)

 五、完整代码

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Threading.Tasks;
  9 using System.Windows.Forms;
 10 using System.IO.Ports;
 11 using System.Threading;
 12 
 13 namespace ComDataTest
 14 {
 15     public partial class ComData : Form
 16     {
 17         private SerialPort serialPort=new SerialPort();
 18         string data = string.Empty;
 19         public ComData()
 20         {
 21             InitializeComponent();
 22         }
 23 
 24         private void ComData_Load(object sender, EventArgs e)
 25         {
 26             #region 初始化电脑上的串口列表
 27             foreach (string sPort in SerialPort.GetPortNames())
 28             {
 29                 cmbPort.Items.Add(sPort);
 30             }
 31 
 32             //串口设置默认选项
 33             if (cmbPort.Items.Count>0)
 34             {
 35                 cmbPort.SelectedIndex = 0;
 36             }
 37             #endregion
 38 
 39             //为串口加上数据接收事件
 40             serialPort.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
 41         }
 42 
 43         /// <summary>
 44         /// 打开/关闭串口
 45         /// </summary>
 46         /// <param name="sender"></param>
 47         /// <param name="e"></param>
 48         private void btnOpenOrClose_Click(object sender, EventArgs e)
 49         {
 50             try
 51             {
 52                 if (btnOpenOrClose.Text == "打开串口")
 53                 {
 54                     btnOpenOrClose.Text = "关闭串口";
 55                     //设置串口的基本属性
 56                     serialPort.PortName = cmbPort.SelectedItem.ToString();
 57                     serialPort.BaudRate = 9600;
 58                     serialPort.Parity = Parity.None;
 59                     serialPort.DataBits = 8;
 60                     serialPort.StopBits = StopBits.One;
 61                     serialPort.Open();
 62                 }
 63                 else
 64                 {
 65                     btnOpenOrClose.Text = "打开串口";
 66                     serialPort.Close();
 67                 }
 68             }
 69             catch (Exception ex)
 70             {
 71                 MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
 72                 return;
 73             }
 74         }
 75 
 76         /// <summary>
 77         /// (将接收的数据显示到文本框中)不懂这一块的实现逻辑,需要加深理解线程的相关概念
 78         /// </summary>
 79         public void SetReceiveData()
 80         {
 81             lock (this)
 82 
 83                 Invoke(new MethodInvoker(delegate ()
 84 
 85                 {
 86 
 87                     this.txtReciveData.Text = data;
 88 
 89                 }));
 90 
 91         }
 92 
 93         void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
 94         {
 95             try
 96             {
 97                 Byte[] InputBuf = new Byte[128];
 98                 serialPort.Read(InputBuf, 0, serialPort.BytesToRead);
 99 
100                 ASCIIEncoding encoding = new ASCIIEncoding();
101                 data = encoding.GetString(InputBuf);
102                 new Thread(SetReceiveData).Start();
103                 //直接调用会报错-------从不是创建控件”txtContent”的线程访问它
104                 //SetReceiveData();
105             }
106             catch (Exception ex)
107             {
108                 MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
109                 return;
110             }
111         }
112     }
113 }

六、写在后面的话:

       初次接触串口编程,作为码农多年,确实有些汗颜。从最初下载vspd和串口调试软件,根本不知如何用,到慢慢的了解一些,会简单的一些操作,着实也费了一点时间。目前对于串口编程,还是有一些云里雾里,似乎缺少一根主线把他们串起来一般,还是需要再进行摸索和探究,继续加油~

posted @ 2018-11-14 18:05  雪球茸茸  阅读(4441)  评论(0编辑  收藏  举报