1. 程式人生 > >Winform串列埠程式設計---接收資料demo(VSPD虛擬串列埠)

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