C#實(shí)現(xiàn)串口通信的示例詳解
框架準(zhǔn)備
出于簡(jiǎn)單考慮,首先創(chuàng)建一個(gè)Winform項(xiàng)目,本文項(xiàng)目名稱為portTest。
串口通信,至少有兩個(gè)串口才能通信,所以拖動(dòng)兩個(gè)GroupBox,一左一右,里面分別放置一個(gè)Combobox、一個(gè)按鈕,以及兩個(gè)TextBox用于發(fā)送和接收內(nèi)容,第二個(gè)TextBox要點(diǎn)擊右上角的三角選擇多行。
布局結(jié)果為
其中,串口A和串口B中各控件的名稱為
串口A | 串口B | |
---|---|---|
combobox | cbA | cbB |
按鈕 | btnA | BtnB |
發(fā)送文本框 | tbSendA | tbSendB |
接收文本框 | tbRecvA | tbRecvB |
串口準(zhǔn)備
由于.Net6.0并不內(nèi)置串口通信模塊,所以需要額外下載,點(diǎn)擊菜單欄工具->NuGet包管理器->管理解決方案的NuGet包,點(diǎn)擊瀏覽選項(xiàng)卡,搜索Ports,選擇System.IO.Ports,在右側(cè)出現(xiàn)的詳細(xì)信息中,選中portTest項(xiàng)目,點(diǎn)擊安裝按鈕。
此外,如果沒(méi)有合適的用于串口測(cè)試的硬件設(shè)備,可以下載一個(gè)虛擬串口,這里推薦開源的com0com,下載之后根據(jù)自己電腦位數(shù)選擇一個(gè)進(jìn)行安裝,記住安裝路徑,安裝結(jié)束后,打開相應(yīng)路徑中的setupg.exe,如下圖所示,通過(guò)Add Pair可以添加串口對(duì)
在添加串口對(duì)之后,在右側(cè)最上方可以更改串口名字,例如改為COM4和COM5,然后點(diǎn)擊apply,串口名字就會(huì)在左側(cè)發(fā)生更改。根據(jù)右側(cè)線路圖可知,發(fā)給COM4的信息,會(huì)被轉(zhuǎn)發(fā)給COM5;發(fā)給COM5的信息則會(huì)轉(zhuǎn)發(fā)給COM4。
接、化、發(fā)
點(diǎn)擊F7進(jìn)入代碼頁(yè)面,開始串口開發(fā),主要分為一下流程。
本文基于.Net6.0在頂級(jí)語(yǔ)句中開發(fā),所以不需要額外using;否則的話需要添加using System.IO.Ports;,以確保串口可以調(diào)用。并聲明兩個(gè)全局變量,用于后續(xù)的串口通信。
SerialPort pA; SerialPort pB;
然后,確保combobox可以正確識(shí)別串口名稱,故而在 InitializeComponent();下方,添加如下循環(huán)
foreach (var item in SerialPort.GetPortNames()) { cbA.Items.Add(item); cbB.Items.Add(item); }
其中,GetPortNames函數(shù)可以獲取所有可用的串口名稱。
接下來(lái),雙擊連接按鈕,創(chuàng)建點(diǎn)擊命令,下面以按鈕A進(jìn)行示例,對(duì)按鈕B只需將所有的A換成B即可。
private void btnA_Click(object sender, EventArgs e) { if (btnA.Text=="連接"){ pA = new SerialPort(cbA.SelectedItem.ToString(), 115200, Parity.Odd, 7, StopBits.One); pA.Open(); pA.DataReceived += PA_DataReceived; btnA.Text = "斷開"; } else{ pA.Close(); btnA.Text = "連接"; } }
在SerialPort的構(gòu)造函數(shù)中,輸入?yún)?shù)分別是串口名稱、波特率、校驗(yàn)位、長(zhǎng)度、截止位。
PA_DataReceived是一個(gè)委托,為串口接收到數(shù)據(jù)時(shí)執(zhí)行的操作,一般寫完+=之后,點(diǎn)擊回車VS會(huì)自動(dòng)創(chuàng)建,其內(nèi)容為
private void PA_DataReceived(object sender, SerialDataReceivedEventArgs e) { byte[] data = new byte[pA.BytesToRead]; pA.Read(data, 0, data.Length);//從串口讀取數(shù)據(jù) string info = Encoding.UTF8.GetString(data); tbRecvA.BeginInvoke(new Action(() => { tbRecvA.Text += $"接收:{info}"; })); }
由于串口的接收函數(shù)是異步執(zhí)行的,并不屬于窗口主線程,所以當(dāng)串口接收到數(shù)據(jù)后,如果想在窗口中顯示,就必須用BeginInvoke來(lái)另開一個(gè)線程。
最后,編寫串口的發(fā)送程序,當(dāng)tbSend檢測(cè)到回車鍵時(shí),則發(fā)送文本框中的內(nèi)容。
代碼為
private void tbSendA_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode != Keys.Enter) return; var data = Encoding.UTF8.GetBytes(tbSendA.Text); tbRecvA.Text += $"發(fā)送:{tbSendA.Text}\n"; pA.Write(data, 0, data.Length); }
測(cè)試
上面只實(shí)現(xiàn)了A組串口,將B組串口用相同的方法實(shí)現(xiàn)后,就可以進(jìn)行測(cè)試了,效果如下
到此這篇關(guān)于C#實(shí)現(xiàn)串口通信的示例詳解的文章就介紹到這了,更多相關(guān)C#串口通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c#解析jobject的數(shù)據(jù)結(jié)構(gòu)
這篇文章介紹了c#解析jobject數(shù)據(jù)結(jié)構(gòu)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07Unity3D使用鼠標(biāo)旋轉(zhuǎn)縮放平移視角
這篇文章主要為大家詳細(xì)介紹了Unity3D使用鼠標(biāo)旋轉(zhuǎn)縮放平移視角,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07adonet基礎(chǔ)示例分享(adonet連接數(shù)據(jù)庫(kù))
這篇文章主要介紹了adonet基礎(chǔ)示例分享(adonet連接數(shù)據(jù)庫(kù)),需要的朋友可以參考下2014-04-04C#零基礎(chǔ)開發(fā)中最重要的概念總結(jié)
這篇文章主要為大家詳細(xì)介紹了C#零基礎(chǔ)開發(fā)中最重要的一些概念,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定的幫助,需要的可以參考一下2023-02-02unity中實(shí)現(xiàn)Edge瀏覽器鼠標(biāo)手勢(shì)的功能思路詳解
這篇文章主要介紹了unity中實(shí)現(xiàn)Edge瀏覽器鼠標(biāo)手勢(shì)的功能思路詳解,實(shí)現(xiàn)起來(lái)其實(shí)并不復(fù)雜,涉及的技術(shù)點(diǎn)有pc端和移動(dòng)端屏幕拖動(dòng)事件,二維向量的相關(guān)運(yùn)算,手勢(shì)匹配算法,事件系統(tǒng)設(shè)計(jì)模式,需要的朋友可以參考下2023-12-12C#實(shí)現(xiàn)數(shù)據(jù)包加密與解密實(shí)例詳解
這篇文章主要介紹了C#實(shí)現(xiàn)數(shù)據(jù)包加密與解密的方法,是一項(xiàng)很實(shí)用的技能,需要的朋友可以參考下2014-07-07Unity相機(jī)移動(dòng)之屏幕邊緣檢測(cè)
這篇文章主要為大家詳細(xì)介紹了Unity相機(jī)移動(dòng)之屏幕邊緣檢測(cè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02