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和串口調試軟件,根本不知如何用,到慢慢的了解一些,會簡單的一些操作,着實也費了一點時間。目前對於串口編程,還是有一些雲里霧里,似乎缺少一根主線把他們串起來一般,還是需要再進行摸索和探究,繼續加油~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM