C#上位機(jī)系列教程零基礎(chǔ)入門-串口操作
歡迎來到C#上位機(jī)教程的零基礎(chǔ)入門!本教程將幫助你從零開始學(xué)習(xí)C#編程,并使用C#構(gòu)建上位機(jī)應(yīng)用程序,本教程將以經(jīng)典的串口工具開發(fā)為Demo,講述一個(gè)項(xiàng)目如何去實(shí)現(xiàn),本節(jié)內(nèi)容將講述串口的操作。
首先簡單介紹下串口通訊中一個(gè)重要的類庫SerialPort,SerialPort 類是用于在計(jì)算機(jī)上通過串行端口與外部設(shè)備進(jìn)行通信的類。串行端口是一種用于在計(jì)算機(jī)和外部設(shè)備之間傳輸數(shù)據(jù)的物理接口,例如用于連接調(diào)制解調(diào)器、打印機(jī)、傳感器等設(shè)備。在 .NET Framework 和 .NET Core(現(xiàn)在稱為 .NET 5+)等平臺中,System.IO.Ports.SerialPort 類提供了與串行端口進(jìn)行通信的功能。通過此類,您可以打開、關(guān)閉串行端口,發(fā)送和接收數(shù)據(jù),配置通信參數(shù)等。以下是 SerialPort 類的一些重要方法和屬性:
構(gòu)造函數(shù):
SerialPort(string portName): 通過指定的串行端口名稱創(chuàng)建一個(gè) SerialPort 實(shí)例。
重要屬性:
PortName: 獲取或設(shè)置要使用的串行端口的名稱。
BaudRate: 獲取或設(shè)置波特率(數(shù)據(jù)傳輸速率)。
DataBits: 獲取或設(shè)置數(shù)據(jù)位數(shù)。
Parity: 獲取或設(shè)置奇偶校驗(yàn)位。
StopBits: 獲取或設(shè)置停止位的數(shù)量。
ReadTimeout 和 WriteTimeout: 獲取或設(shè)置讀取和寫入操作的超時(shí)時(shí)間。
方法:
Open(): 打開串行端口以進(jìn)行通信。
Close(): 關(guān)閉串行端口。
Write(byte[] buffer, int offset, int count): 將指定數(shù)量的字節(jié)寫入串行端口。
Read(byte[] buffer, int offset, int count): 從串行端口讀取指定數(shù)量的字節(jié)。
DataReceived 事件:當(dāng)接收到數(shù)據(jù)時(shí)觸發(fā)的事件。
使用 SerialPort 類,您可以創(chuàng)建串行端口通信的應(yīng)用程序,如與硬件設(shè)備通信、數(shù)據(jù)采集、傳感器數(shù)據(jù)讀取等。需要注意的是,在使用此類時(shí),要小心處理異常情況,如端口不可用、數(shù)據(jù)傳輸錯(cuò)誤等。
我們緊接上一節(jié)的教程,在Form窗體中通過拖放的方式加載SerialPort組件如下圖所示
注意,在.Net6中serialPort類庫需要通過NuGet的方式引入。
雙擊Form查看代碼,使用“using”引入“System.IO.Ports”這個(gè)命名空間
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports; //引入命名空間
using System.Text;
using System.Windows.Forms;
System.IO.Ports包含用于控制串行端口的類。最重要的類 SerialPort 為同步和事件驅(qū)動 I/O 提供框架,提供對插針和中斷狀態(tài)的訪問,以及對串行驅(qū)動程序?qū)傩缘脑L問。它可用于包裝 Stream 對象,允許使用流的類訪問串行端口。
雙擊"打開串口"系統(tǒng)自動根據(jù)button按鈕的"Name"屬性生成一個(gè)產(chǎn)生雙擊"打開串口"的事件后調(diào)用的方法,完整代碼如下:
private void OpenPortBtn_Click(object sender, EventArgs e)
{
try
{
if (!portOpenFlag)
{
//串口號
serialPort1.PortName = portCbb.Text;
// 波特率
serialPort1.BaudRate = Convert.ToInt32(baudCbb.Text);
//檢驗(yàn)位 從枚舉中獲取相應(yīng)的值 FaceType aaa = (FaceType)Enum.Parse(typeof(FaceType), cbFace.Text)
serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity),checkCbb .Text);
//數(shù)據(jù)位
serialPort1.DataBits = Convert.ToInt32(dataBitsCbb.Text);
//停止位
serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits),stopBitsCbb.Text);
serialPort1.Open();
portOpenFlag = true;
this.OpenPortBtn.Text = "關(guān)閉串口";
}
else
{
portOpenFlag = false;
serialPort1.Close();
this.OpenPortBtn.Text = "打開串口";
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message+serialPort1.PortName.ToString());
}
}
代碼解析:先建立一個(gè)bool類型的串口打開狀態(tài)標(biāo)志位初始狀態(tài)為false:portOpenFlag,如果串口沒有打開。我們初始化配置參數(shù),主要包括端口號,波特率,數(shù)據(jù)位,停止位,校驗(yàn)位,并且調(diào)用串口打開函數(shù),將portOpenFlag置位為true,按鈕文本改為'關(guān)閉串口',如果串口已經(jīng)打開。 portOpenFlag 置位為 false;并且調(diào)用串口關(guān)閉函數(shù),將portOpenFlag置位為true,按鈕文本改為'打開串口',在串口打開或者關(guān)閉的過程中有很多因素導(dǎo)致操作失敗,所以我們用try`````catch捕捉異常,及時(shí)將錯(cuò)誤拋出,避免程序的奔潰
在代碼調(diào)試的過程中,我們需要用虛擬串口工具百度網(wǎng)盤鏈接如下:鏈接:https://pan.baidu.com/s/1S0XXsXIXE-hQQd9AoCgnFA?pwd=m42i 提取碼:m42i
安裝好虛擬串口工具以后,我們添加兩個(gè)虛擬串口COM2和COM3
同時(shí)我們在電腦的設(shè)備管理器也能看到COM2和COM3.
下面通過代碼獲取到設(shè)備管理器中的COM2和COM3,并且將串口通訊參數(shù)的值設(shè)置為我們想要的默認(rèn)值
首先綁定波特率,數(shù)據(jù)位,停止位,校驗(yàn)位,的數(shù)據(jù)集合
具體操作如下圖:
波特率
檢驗(yàn)位
數(shù)據(jù)位
停止位
新建一個(gè)SerialPortInit方法,專門用于通訊參數(shù)combox的text值的初始化
private void SerialPortInit()
{
//獲取設(shè)備管理器的串口號
string[] ports = SerialPort.GetPortNames();
//將ports數(shù)組綁定奧串口號comobox 的數(shù)據(jù)源上
this.portCbb.DataSource = ports;
this.portCbb.SelectedIndex = 0;
//波特率
this.baudCbb.SelectedIndex = 3;
//校驗(yàn)位
this.checkCbb.SelectedIndex = 0;
//數(shù)據(jù)位
this.dataBitsCbb.SelectedIndex = 0;
//停止位
this.stopBitsCbb.SelectedIndex = 1;
}
然后再窗體初始化時(shí)調(diào)用此函數(shù)
private void Form1_Load(object sender, EventArgs e)
{
this.SerialPortInit();
}
最終通訊參數(shù)默認(rèn)值如下:
當(dāng)我們選擇打開“COM2”時(shí),虛擬串口COM2顯示的通訊參數(shù)能夠和串口工具的通訊設(shè)定值對應(yīng)上。