serialport控件的詳細(xì)用法
1。簡(jiǎn)介
隨著USB的流行,串口通訊已經(jīng)應(yīng)用到日常生活的很多方面了,USB是一種高速的串口通訊協(xié)議,USB接口非常復(fù)雜,通常被用在需要傳輸大量數(shù)據(jù)數(shù)據(jù)的地方,如U盤、相機(jī)、打印機(jī)等。除了USB這種較為奢侈的串口外,在工控和嵌入式行業(yè),大量被使用的是另一種古老的串口協(xié)議,RS-232串口。RS-232是一種非常簡(jiǎn)潔的低速串口通訊接口,它可以同時(shí)進(jìn)行數(shù)據(jù)接收和發(fā)送的工作。
2。.NET 2.0對(duì)串口的支持
.NET 2.0提供了對(duì)串口通信功能的支持,有關(guān)類可以在命名空間System.IO.Ports下找到,這其中最為重要的是SerialPort類。
通過(guò)創(chuàng)建一個(gè)新的SerialPort 對(duì)象,我們就可以在.NET程序中控制串口通訊的全過(guò)程。
3。使用 SerialPort 設(shè)置串口屬性
進(jìn)行串口通訊時(shí),需要設(shè)置一些相關(guān)參數(shù),可以通過(guò)設(shè)置SerialPort 類的屬性來(lái)進(jìn)行。串口屬性主要包括
.PortName 串口名稱,COM1, COM2等。
.BaudRate 波特率,也就是串口通訊的速度,進(jìn)行串口通訊的雙方其波特率需要相同,如果用PC連接其他非PC系統(tǒng),一般地,波特率由非PC系統(tǒng)決定。
.Parity 奇偶校驗(yàn)。可以選取枚舉Parity中的值
.DataBits 數(shù)據(jù)位
.StopBits 停止位,可以選取枚舉StopBits中的值
.Handshake 握手方式,也就是數(shù)據(jù)流控制方式,可以選取枚舉Handshake中的值
4。打開(kāi)與關(guān)閉串口
在創(chuàng)建一個(gè)SerialPort 對(duì)象,設(shè)置串口屬性后,可以通過(guò) Open()方法打開(kāi)串口。數(shù)據(jù)讀寫完成后,可以通過(guò)Close()方法關(guān)閉串口。
根據(jù)經(jīng)驗(yàn),對(duì)于有些系統(tǒng),在打開(kāi)串口后,還需要將RtsEnable設(shè)置為True,這樣才能讀寫數(shù)據(jù),否則不能正常讀寫數(shù)據(jù)。
5。讀寫行數(shù)據(jù)
雙方通訊時(shí),一般都需要定義通訊協(xié)議,即使最簡(jiǎn)單的通過(guò)串口發(fā)送文本聊天的程序。
通常是在當(dāng)一方按下回車時(shí),將其所數(shù)據(jù)的文本連同換行符發(fā)給另一方。在這個(gè)通訊事例中,協(xié)議楨是通過(guò)換行符界定的,每一楨數(shù)據(jù)都被換行符隔開(kāi),這樣就很容易識(shí)別出通訊雙發(fā)發(fā)送的信息。
在以上的例子中,可以用WriteLine()來(lái)發(fā)送數(shù)據(jù),用ReadLine()來(lái)讀取數(shù)據(jù)。WriteLine發(fā)送完數(shù)據(jù)后,會(huì)將換行符作為數(shù)據(jù)也發(fā)送給對(duì)方。ReadLine()讀取數(shù)據(jù)時(shí),直至遇到一個(gè)換行符,然后返回一個(gè)字符串代表一行信息。換行符可以通過(guò)SerialPort 的屬性NewLine來(lái)設(shè)置。一般地,Windows將CrLn作為換行符,而在Linux下,換行符則只用一個(gè)Ln表示。
ReadLine()方法是阻塞的,直至遇到一個(gè)換行符后返回。在讀取數(shù)據(jù)時(shí),如果一直沒(méi)有遇到換行符,那么在等待ReadTimeout時(shí)間后,拋出一個(gè)TimeoutException。默認(rèn)情況下,ReadTimeout為InfiniteTimeout。這樣,ReadLine一直處于阻塞狀態(tài),直至有新一行數(shù)據(jù)到達(dá)。
WriteLine()方法也是阻塞的,如果另一方不能及時(shí)接收數(shù)據(jù),就會(huì)引起TimeoutException異常。
由于ReadLine()和WriteLine()方法都是阻塞式的,在程序使用SerialPort 進(jìn)行串口通訊時(shí),一般應(yīng)該把讀寫操作交由其他線程處理,避免因?yàn)樽枞鴮?dǎo)致程序不響應(yīng)。
6。讀寫字節(jié)或字符數(shù)據(jù)
對(duì)于字節(jié)或字符數(shù)據(jù),用Read()方法來(lái)讀數(shù)據(jù),該方法需要一個(gè)字節(jié)或字符數(shù)組作為參數(shù)來(lái)保存讀取的數(shù)據(jù),結(jié)果返回實(shí)際讀取的字節(jié)或字符數(shù)。寫數(shù)據(jù)使用Write()方法,該方法可以將字節(jié)數(shù)組、字符數(shù)據(jù)或字符串發(fā)送給另一方。
如果通訊雙方交換的數(shù)據(jù)位字節(jié)流數(shù)據(jù),要構(gòu)建一個(gè)使用的串口通訊程序,那么雙方應(yīng)該定義數(shù)據(jù)楨格式。通常數(shù)據(jù)楨由楨頭和楨尾來(lái)界定。
發(fā)送數(shù)據(jù)比較簡(jiǎn)單,只需要將構(gòu)造好的數(shù)據(jù)用Write()方法發(fā)送出去即可。
接收數(shù)據(jù)則比較復(fù)雜,通訊是以字節(jié)流的形式到達(dá)的,通過(guò)調(diào)用一次Read()方法并不能確保所讀取的數(shù)據(jù)就是完整一楨。因此需要將每次讀取的數(shù)據(jù)整合在一起,對(duì)整合后的數(shù)據(jù)進(jìn)行分析,按照定義的楨格式,通過(guò)楨頭和楨尾,將楨信息從字節(jié)流中抽取出來(lái),這樣才能獲取有意義的信息。
除了利用Read()方法來(lái)讀數(shù)據(jù),還可以使用ReadExisting()方法來(lái)讀取數(shù)據(jù)。該方法讀取當(dāng)前所能讀到的數(shù)據(jù),以字符串的形式返回。
7。事件
SerialPort 提供了DataReceived事件。當(dāng)有數(shù)據(jù)進(jìn)入時(shí),該事件被觸發(fā)。該事件的觸發(fā)由操作系統(tǒng)決定,當(dāng)有數(shù)據(jù)到達(dá)時(shí),該事件在輔助線程中被觸發(fā)。輔助線程的優(yōu)先級(jí)比較低,因此并不能確保每個(gè)字節(jié)的數(shù)據(jù)到達(dá)時(shí),該事件都被觸發(fā)。
在使用該事件接收數(shù)據(jù)時(shí),最好對(duì)定義通訊協(xié)議格式,添加楨頭和楨尾。在DataReceived事件中接收數(shù)據(jù)時(shí),把數(shù)據(jù)放在數(shù)組中或字符串中緩沖起來(lái),當(dāng)接收的包含楨頭和楨尾的完整數(shù)據(jù)時(shí),在進(jìn)行處理,另外,為了有效地接收數(shù)據(jù),可以在每次讀取數(shù)據(jù)后,加入System.Threading.Thread.Sleep方法進(jìn)行演示。
8。其他
???????用跳線使串口的第2、3針連接,可以在本地計(jì)算機(jī)上實(shí)現(xiàn)串口通信,所以,通過(guò)串口的第2、3針的連接可以對(duì)程序進(jìn)行檢測(cè)。

方 法 名 稱? ? ? ? ??說(shuō) 明
Close? ? ? ? ? ? ? ? ?關(guān)閉端口連接,將 IsOpen 屬性設(shè)置為False,并釋放內(nèi)部 Stream 對(duì)象
Open??????????????????打開(kāi)一個(gè)新的串行端口連接
Read????????????????????從 SerialPort 輸入緩沖區(qū)中讀取數(shù)據(jù)字節(jié)數(shù)
ReadByte????????????從 SerialPort 輸入緩沖區(qū)中同步讀取一個(gè)字節(jié)
ReadChar????????????從 SerialPort 輸入緩沖區(qū)中同步讀取一個(gè)字符
ReadLine????????????一直讀取到輸入緩沖區(qū)中的 NewLine 值
ReadTo????????????一直讀取到輸入緩沖區(qū)中指定 value 的字符串
Write????????????????已重載。將數(shù)據(jù)寫入串行端口輸出緩沖區(qū)
WriteLine????????????將指定的字符串和 NewLine 值寫入輸出緩沖區(qū)
DiscardInBuffer????清空接收緩沖區(qū)數(shù)據(jù)
DiscardOutBuffer????清空輸出緩沖去數(shù)據(jù)

屬性說(shuō)明
名 稱????????????????說(shuō) 明
BaseStream????????????獲取 SerialPort 對(duì)象的基礎(chǔ) Stream 對(duì)象
BaudRate????????????????獲取或設(shè)置串行波特率
BreakState????????????獲取或設(shè)置中斷信號(hào)狀態(tài)
BytesToRead????????獲取接收緩沖區(qū)中數(shù)據(jù)的字節(jié)數(shù)
BytesToWrite????????獲取發(fā)送緩沖區(qū)中數(shù)據(jù)的字節(jié)數(shù)
CDHolding???????????獲取端口的載波檢測(cè)行的狀態(tài)
CtsHolding????????????獲取“可以發(fā)送”行的狀態(tài)
DataBits????????????????獲取或設(shè)置每個(gè)字節(jié)的標(biāo)準(zhǔn)數(shù)據(jù)位長(zhǎng)度
DiscardNull????????????獲取或設(shè)置一個(gè)值,該值指示 Null 字節(jié)在端口和接收緩沖區(qū)之間傳輸時(shí)是否被忽略
DsrHolding????????????獲取數(shù)據(jù)設(shè)置就緒 (DSR) 信號(hào)的狀態(tài)
DtrEnable????????????獲取或設(shè)置一個(gè)值,該值在串行通信過(guò)程中啟用數(shù)據(jù)終端就緒 (DTR) 信號(hào)
Encoding????????????獲取或設(shè)置傳輸前后文本轉(zhuǎn)換的字節(jié)編碼
Handshake????????獲取或設(shè)置串行端口數(shù)據(jù)傳輸?shù)奈帐謪f(xié)議
IsOpen????????????獲取一個(gè)值,該值指示 SerialPort 對(duì)象的打開(kāi)或關(guān)閉狀態(tài)
NewLine????????????獲取或設(shè)置用于解釋 ReadLine( )和WriteLine( )方法調(diào)用結(jié)束的值
Parity????????????????獲取或設(shè)置奇偶校驗(yàn)檢查協(xié)議
ParityReplace????????獲取或設(shè)置一個(gè)字節(jié),該字節(jié)在發(fā)生奇偶校驗(yàn)錯(cuò)誤時(shí)替換數(shù)據(jù)流中的無(wú)效字節(jié)
PortName????????獲取或設(shè)置通信端口,包括但不限于所有可用的 COM 端口
ReadBufferSize????????獲取或設(shè)置 SerialPort 輸入緩沖區(qū)的大小
ReadTimeout????????獲取或設(shè)置讀取操作未完成時(shí)發(fā)生超時(shí)之前的毫秒數(shù)
ReceivedBytesThreshold????????獲取或設(shè)置 DataReceived 事件發(fā)生前內(nèi)部輸入緩沖區(qū)中的字節(jié)數(shù)
RtsEnable????????獲取或設(shè)置一個(gè)值,該值指示在串行通信中是否啟用請(qǐng)求發(fā)送 (RTS) 信號(hào)
StopBits????????獲取或設(shè)置每個(gè)字節(jié)的標(biāo)準(zhǔn)停止位數(shù)
WriteBufferSize????????獲取或設(shè)置串行端口輸出緩沖區(qū)的大小
WriteTimeout????????獲取或設(shè)置寫入操作未完成時(shí)發(fā)生超時(shí)之前的毫秒數(shù)