摘要:串口通信因?yàn)槠浜?jiǎn)單,靈活易用,在許多領(lǐng)域有著廣闊的應(yīng)用前景。本文在深入了解串口通訊技術(shù)的基礎(chǔ)上,結(jié)合自身的工程實(shí)踐經(jīng)驗(yàn),闡述了VB串口編程的技術(shù)要點(diǎn)。并結(jié)合一個(gè)通訊實(shí)例,分析通訊的具體實(shí)現(xiàn),給相關(guān)領(lǐng)域的研究人員提供值得參考的信息。
關(guān)鍵詞:串口;RS232;API;Pcomm;Mscomm;通信程序
中圖分類號(hào):TN911文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1000-8136(2009)27-0001-03
現(xiàn)在通訊方式越來(lái)越多,速度越來(lái)越快,但串行通訊由于自身價(jià)格低、協(xié)議透明、硬件投資少、軟件編程簡(jiǎn)單等諸多優(yōu)點(diǎn)在遠(yuǎn)程數(shù)據(jù)采集、監(jiān)視、通信及控制領(lǐng)域里一直占據(jù)著極其重要的地位。它不僅沒(méi)有因?yàn)闀r(shí)代的進(jìn)步而被淘汰,反而在規(guī)格上越來(lái)越完善、應(yīng)用越來(lái)越廣,長(zhǎng)久不衰。
1串口通信的通信機(jī)理
PC串行通信是指直接對(duì)串行端口的UART(PC機(jī)的通用異步收發(fā)器,也叫異步通信適配器,是PC機(jī)用于異步通信的接口)進(jìn)行編程實(shí)現(xiàn)的通信。PC機(jī)每個(gè)UART中的INS8250中有10個(gè)可編程的單字節(jié)寄存器,可用于控制、監(jiān)視操作串行端口,COM1的寄存器地址3F8H-3FEH,COM2的寄存器地址為2F8H-2FEH。10個(gè)寄存器由7個(gè)地址訪問(wèn),其中5個(gè)寄存器的訪問(wèn)條件是先設(shè)置3FBH線路控制寄存器的最高位為“1”,該位也稱為DLAB狀態(tài)位。[1]
一般說(shuō)來(lái),PC機(jī)都有一個(gè)或多個(gè)串行端口,它們依次為Com1、Com2……。這些串口提供了外部設(shè)備與PC進(jìn)行數(shù)據(jù)傳輸和通信的通道,在CPU和外設(shè)之間充當(dāng)了解釋器的角色。當(dāng)字符數(shù)據(jù)從CPU發(fā)送給外設(shè)時(shí),這些字符數(shù)據(jù)將被轉(zhuǎn)換成串行比特流數(shù)據(jù);而當(dāng)接受數(shù)據(jù)時(shí),從外界進(jìn)來(lái)的比特流數(shù)據(jù)被轉(zhuǎn)換成字符數(shù)據(jù)傳遞給CPU進(jìn)行處理。在操作系統(tǒng)方面,Windows用通信驅(qū)動(dòng)程序(COMM.DRV)調(diào)用API函數(shù)發(fā)送和接受數(shù)據(jù)。當(dāng)用通信控件或聲明調(diào)用API函數(shù)時(shí),它們由COMM.DRV解釋并傳遞給設(shè)備驅(qū)動(dòng)程序。
作為一個(gè)VB程序員,要編寫(xiě)串口通信程序,只需知道通信控件提供給Windows通信API函數(shù)的接口即可,換言之,只需設(shè)定和監(jiān)視通信控件的屬性和時(shí)間即可。
2串行通訊接口RS-232
前一章節(jié)討論了串口通訊的通信機(jī)理,但為了實(shí)現(xiàn)具體的數(shù)據(jù)采集、監(jiān)視、通信功能,必須了解具體的串口形式。目前使用最廣泛的串行接口有兩種:RS-232和RS-485。本文著重討論RS-232,RS- 485不作介紹。
RS-232C標(biāo)準(zhǔn)的全稱是EIA-RS-232C標(biāo)準(zhǔn),其中EIA代表美國(guó)電子工業(yè)協(xié)會(huì),RS代表推薦標(biāo)準(zhǔn),232是標(biāo)識(shí)號(hào),C代表RS232的最新一次修改(1969年),在這之前,有RS232A、RS232B協(xié)議。它規(guī)定連接電纜和機(jī)械、電氣特性、信號(hào)功能及傳送過(guò)程。EIA-RS-232C定義了按位串行傳輸?shù)臄?shù)據(jù)終端設(shè)備(DTE)和數(shù)據(jù)通訊設(shè)備(DCE)之間的接口信息。RS-232C是從DTE或計(jì)算機(jī)串行接口角度來(lái)定義引腳信號(hào)的。
目前RS-232是PC機(jī)與通信工業(yè)中應(yīng)用最廣泛的一種串行接口。RS232被定義為一種在低速率串行通訊中增加通訊距離的單端標(biāo)準(zhǔn)。RS232采取不平衡傳輸方式,即所謂的單端通訊。[2]
DB9(9針串口)的接線方式如下:1腳,數(shù)據(jù)載波檢測(cè)DCD;2腳,接收數(shù)據(jù)RXD;3腳,發(fā)送數(shù)據(jù)TXD;4腳,數(shù)據(jù)終端準(zhǔn)備DTR;5腳,信號(hào)地GND;6腳,數(shù)據(jù)設(shè)備就緒DSR;7腳,請(qǐng)求發(fā)送RTS;8腳,清除發(fā)送CTS;9腳,振鈴指示DELL。
DB25(25陣串口),常用的針腳也有9個(gè),且和DB9可以一一對(duì)應(yīng),具體接線方式為:8腳,數(shù)據(jù)載波檢測(cè)DCD;3腳,接收數(shù)據(jù)RXD;2腳,發(fā)送數(shù)據(jù)TXD;20腳,數(shù)據(jù)終端準(zhǔn)備DTR;7腳,信號(hào)地GND;6腳,數(shù)據(jù)設(shè)備就緒DSR;4腳,請(qǐng)求發(fā)送RTS;5腳,清除發(fā)送CTS;22腳,振鈴指示DELL。
一般來(lái)說(shuō),對(duì)于要求不太高的場(chǎng)合,使用接收數(shù)據(jù)RXD,發(fā)送數(shù)據(jù)TXD,信號(hào)地GND三個(gè)腳即可實(shí)現(xiàn)數(shù)據(jù)傳輸。如果要求有硬件流控制,則必須使用DTR、DSR、RTS和CTS這四個(gè)腳。
值得注意的是RS-232C是用正負(fù)電壓來(lái)表示邏輯狀態(tài),與TTL以高電平表示邏輯狀態(tài)的規(guī)定不同。因此,為了能夠與計(jì)算機(jī)接口或終端的TTL器件連接,必須在RS-232C與TTL電路之間進(jìn)行電平和邏輯關(guān)系的變換。目前較為廣泛地使用集成電路轉(zhuǎn)換器件,如MC1489、SN75150芯片可完成TTL電平到EIA電平的轉(zhuǎn)換,而MC1489、SN75154可實(shí)現(xiàn)EIA電平到TTL電平的轉(zhuǎn)換。
3三種讀取串口數(shù)據(jù)的方式
目前通用的串口通訊的軟件實(shí)現(xiàn)方式有3種,本文都進(jìn)行詳細(xì)的介紹,它們各有自身的優(yōu)缺點(diǎn),讀者在編程時(shí)可根據(jù)具體的情況選擇合適的方式。
3.1利用Mscomm控件
VB提供的這個(gè)通信控件“隱藏”了大部分串口通信的底層運(yùn)行過(guò)程,程序員只需編寫(xiě)少量的代碼就可以完成軟件的開(kāi)發(fā)過(guò)程。在通信數(shù)據(jù)量不大,通信要求不是很高的情況下建議采取此方式。
利用Mscomm控件實(shí)現(xiàn)通信最需要掌握的就是它的幾個(gè)主要屬性,下面選取其中重要的進(jìn)行介紹,其余的可以參考相關(guān)資料。[3]
(1)Settings屬性:以字符串的形式設(shè)置并返回波特率、 奇偶校驗(yàn)位、數(shù)據(jù)位、停止位。這個(gè)屬性很重要,針對(duì)不同的終端設(shè)備需要根據(jù)設(shè)備的具體情況進(jìn)行調(diào)整(比如日本的設(shè)備不同于美國(guó)的設(shè)備,通常會(huì)采用奇校驗(yàn))。
(2)InputMode屬性:設(shè)置接收數(shù)據(jù)的類型,0為文本格式,1為二進(jìn)制格式。
(3)Input屬性:讀取并刪除接收緩沖區(qū)中的數(shù)據(jù)流。
(4)Output屬性:向發(fā)送緩沖區(qū)傳送一數(shù)據(jù)流。
(5)Rthreshold屬性:該屬性為一閥值,它確定當(dāng)接收緩沖區(qū)內(nèi)的字節(jié)個(gè)數(shù)達(dá)到或超過(guò)該值后就產(chǎn)生代碼為ComEvReceive的OnComm事件。
(6)Handshaking屬性:設(shè)置和返回握手協(xié)議,即計(jì)算機(jī)內(nèi)部CPU與串口之間的通訊協(xié)議,保證在緩沖區(qū)過(guò)載時(shí)數(shù)據(jù)不會(huì)丟失。這個(gè)屬性在保證數(shù)據(jù)傳輸?shù)恼_性方面有很大的作用,共有四個(gè)選項(xiàng),分別表示:①無(wú)流控制;②軟件流控制;③硬件流控制;④軟硬件流控制。采用硬件流控時(shí),要求串口之間和電纜支持硬件握手,在自己制作串口通信線時(shí),有關(guān)硬件握手的線RTS、CTS、DSR、DTR要連接正確。
在正確設(shè)置這些屬性的基礎(chǔ)上,剩下的就是打開(kāi)串口,通過(guò)串口發(fā)送及接受數(shù)據(jù)了。本文后續(xù)章節(jié)利用一個(gè)實(shí)例詳細(xì)講解了這些屬性的設(shè)置及具體代碼。
3.2直接調(diào)用Win32 API通信函數(shù)
直接調(diào)用Windows API函數(shù),可以清楚地理解串口通信的機(jī)制,根據(jù)需要靈活地配置串口的各種參數(shù)和屬性,而且直接調(diào)用低層API函數(shù),通信效率比較高,但付出的代價(jià)就是程序較復(fù)雜,編程周期長(zhǎng),適合于大型通信程序及通訊質(zhì)量要求較高的場(chǎng)合。
在32位的Windows系統(tǒng)中,串口通信是作為文件處理的,串口操作一般為打開(kāi)、關(guān)閉、讀取、寫(xiě)入等操作,相應(yīng)的Windows API函數(shù)如下:[4]
(1)CreateFile()函數(shù):實(shí)現(xiàn)串口的初始化并打開(kāi)串口,返回串口句柄資源以供后續(xù)進(jìn)程調(diào)用。
(2)CloseFile()函數(shù):關(guān)閉串口,串口是非共享資源,應(yīng)用程序以獨(dú)占方式使用,通信結(jié)束應(yīng)立即關(guān)閉。
(3)ReadFile()函數(shù):從串口輸入緩沖區(qū)讀取數(shù)據(jù)流。
(4)WriteFile()函數(shù):向串口輸出緩沖區(qū)發(fā)送數(shù)據(jù)。
(5)GetCommState()函數(shù):獲取串口的當(dāng)前配置。
(6)SetCommState()函數(shù):重新分配串口資源的各個(gè)參數(shù)。
由于Windows API函數(shù)大部分是用C或C++編寫(xiě),所以在Visual Basic 6.0 中調(diào)用Windows API函數(shù)之前必須先在模塊級(jí)代碼上用Declare語(yǔ)句對(duì)所調(diào)用的函數(shù)和用到的數(shù)據(jù)結(jié)構(gòu)進(jìn)行聲明,具體的函數(shù)聲明及數(shù)據(jù)結(jié)構(gòu)請(qǐng)參考朱友芹編《新編Windows API參考大全》。
3.3調(diào)用第三方函數(shù)庫(kù)(如Pcomm函數(shù)庫(kù))
DLL(Dynamic Link Library)動(dòng)態(tài)鏈接庫(kù)是一種可以被VB語(yǔ)言調(diào)用的程序模塊。DLL中包含的可執(zhí)行代碼不能單獨(dú)執(zhí)行,而應(yīng)由Windows應(yīng)用程序調(diào)用執(zhí)行。一般數(shù)據(jù)采集卡的供應(yīng)商都會(huì)提供該采集卡的DLL庫(kù)函數(shù),使用這些DLL庫(kù)函數(shù),可以做到程序代碼共享,減少程序的編寫(xiě)工作量。用戶不需要知道這些代碼的實(shí)現(xiàn)細(xì)節(jié),只需要了解調(diào)用函數(shù)的參數(shù)和函數(shù)處理后的返回值。
Pcomm函數(shù)庫(kù)是由臺(tái)灣Moxa公司為開(kāi)發(fā)串口通信程序提供的一套函數(shù)庫(kù)。通過(guò)對(duì)Windows API函數(shù)的進(jìn)一步封裝,提供50多個(gè)串口操作函數(shù)。覆蓋了Windows操作系統(tǒng)下幾乎所有異步通信的問(wèn)題,可以簡(jiǎn)潔的開(kāi)發(fā)多線程通訊程序。采用該庫(kù),通信的可靠性與使用MSComm32控件比較有了明顯提高, 而相對(duì)直接使用Win32API函數(shù)編程則降低了程序開(kāi)發(fā)難度, 縮短了程序開(kāi)發(fā)周期。
這種方式上述直接調(diào)用Windows API函數(shù)有相似之處,但也有明顯的差異。API函數(shù)常采取的方法是在串口監(jiān)視線程中設(shè)置串口通信事件掩碼及重疊機(jī)制,允許程序在后臺(tái)等待串口通信事件。通過(guò)WaitCommEvent檢測(cè)特定的串行通信事件。而在Pcomm中,可以采用中斷處理的方式,為各種事件指定相應(yīng)的中斷處理函數(shù),如接收到一定數(shù)目的字符,接收到結(jié)束字符,接收到中止信號(hào)以及發(fā)送緩沖區(qū)為空等;同時(shí)還可以采用線程控制的方式,直接采用庫(kù)中的sio_read()和sio_write()函數(shù)讀寫(xiě)串口。
Pcomm..DLL中的函數(shù)按功能分為6項(xiàng):端口設(shè)置、數(shù)據(jù)發(fā)送與接收、串口狀態(tài)檢測(cè)、事件服務(wù)、文件傳輸、雜項(xiàng)。Pcomm..DLL中主要的函數(shù)介紹如下。[5]
sio_open:打開(kāi)端口;sio_close: 關(guān)閉端口。
sio_ioctl:設(shè)置端口參數(shù),如波特率等。
sio_read:從端口接收數(shù)據(jù);sio_write向端口發(fā)送數(shù)據(jù)。
sio_iqueue:得到接收緩沖區(qū)中的數(shù)據(jù)長(zhǎng)度。
sio_oqueue:得到發(fā)送緩沖區(qū)中的數(shù)據(jù)長(zhǎng)度。
Pcomm在串口通信中的功能十分強(qiáng)大,但基于篇幅的考慮,在此不便贅述,讀者可參考相關(guān)書(shū)籍或Pcomm自帶的幫助文檔。
4串口通訊的錯(cuò)誤及處理
由于外界干擾或電壓波動(dòng)等原因,串口通訊可能會(huì)出現(xiàn)錯(cuò)誤,如接受緩沖區(qū)溢出,奇偶校驗(yàn)錯(cuò)誤等。為了處理這些錯(cuò)誤,在Mscomm控件中就提供了一個(gè)OnComm事件,它可以捕獲通信時(shí)發(fā)生的串口事件和錯(cuò)誤信息,自動(dòng)轉(zhuǎn)入事件處理程序。在OnComm事件中,CommEvent屬性是OnComm事件的指示,下面簡(jiǎn)單介紹幾個(gè)重要的CommEvent屬性值。
ComEventBreak:表示收到一個(gè)中斷信號(hào);
ComEventFrame:表示硬件檢測(cè)到一個(gè)數(shù)據(jù)幀錯(cuò)誤;
ComEvenRxover:表示接收緩沖區(qū)溢出;
ComEventTxFull:表示輸出緩沖區(qū)已滿;
ComEvReceive:表示接手到了Rthreshold個(gè)字符;
ComEvEOF:表示接受到了EOF字符(ASCII字符26)。
編程時(shí)用SelectCase語(yǔ)句,根據(jù)不同的CommEvent屬性值,去執(zhí)行不同的處理程序。
除了以上所述的通訊錯(cuò)誤外,在串口通信時(shí),如果數(shù)據(jù)傳輸突然中斷,對(duì)串口的讀寫(xiě)操作可能會(huì)進(jìn)入無(wú)限期的等待狀態(tài), 為避免這種情況發(fā)生, 必須設(shè)置串口讀寫(xiě)操作的等待時(shí)間, 等待超時(shí)后,串口的讀寫(xiě)操作將被主動(dòng)放棄,這樣即使數(shù)據(jù)傳輸突然中斷程序也不會(huì)被掛起或阻塞??梢愿鶕?jù)具體要求規(guī)定串口讀寫(xiě)操作的最長(zhǎng)時(shí)間值,即串口讀寫(xiě)必須在這段時(shí)間內(nèi)完成,否則提示串口操作失敗。
5串口通訊實(shí)例
本實(shí)例是一個(gè)采集設(shè)備電流及功率的通訊程序,采集儀為橫河WT230數(shù)字功率計(jì),因?yàn)橐杉臄?shù)據(jù)量不大,且工程結(jié)構(gòu)簡(jiǎn)單,故采用Mscomm控件的形式進(jìn)行串口讀寫(xiě)操作。
具體實(shí)現(xiàn)步驟如下:
(1)在窗體Form上添加兩個(gè)重要的控件:Timer1和Mscomm1;
(2)在程序的Form_Load事件過(guò)程中添加如下代碼:
MSComm1.CommPort=1 ‘使用COM1端口
MSComm1.Setting=“9600,o,8,1” ‘設(shè)置通信口參數(shù),注意是奇校驗(yàn),具體的校驗(yàn)方式要視具體的儀器而定
MSComm1.InputMode=comInputModeBinary ‘設(shè)置接收模式為二進(jìn)制形式,注意一般對(duì)于數(shù)據(jù)采集這類設(shè)備通信,都應(yīng)該設(shè)置為二進(jìn)制形式
MSComm1.PortOpen=True ‘參數(shù)設(shè)置好后打開(kāi)端口
MSComm1.HandShaking=2-comRTS ‘設(shè)置為硬件流控制,可以有效避免數(shù)據(jù)丟失的情況發(fā)生
(3)程序開(kāi)始后在一定情況設(shè)置Timer1.Enabled屬性值為T(mén)rue 激活Timer1_Time事件,可以在固定的時(shí)間間隔下執(zhí)行Timer1_Timer過(guò)程中的代碼程序,完成數(shù)據(jù)采集。在Timer1_Timer過(guò)程中添加如下代碼:
MSComm1.Output = \"COMMUNICATE:WAIT 1\" + Chr(13) + Chr(10)
MSComm1.Output = \"MEASURE:NORMAL:VALUE?\" + Chr(13) + Chr(10)
上述語(yǔ)句是將讀取指令發(fā)送到串口輸出緩沖區(qū)(注意每個(gè)命令字符串后都要加上回車和換行符Chr(13) + Chr(10)),再由系統(tǒng)將其自動(dòng)發(fā)送給通過(guò)RS232通信線與計(jì)算機(jī)端口連接的WT230數(shù)字功率計(jì),功率計(jì)在接收到命令字符串后,經(jīng)過(guò)自身的單片機(jī)處理,就自動(dòng)地把它測(cè)到的電壓、電流、功率數(shù)據(jù)以固定的格式和字符形式通過(guò)RS232通信線傳回至計(jì)算機(jī),計(jì)算機(jī)程序從輸入緩沖區(qū)讀取這些字符數(shù)據(jù)并利用VB字符處理函數(shù)(如Val,InStr)進(jìn)行處理就得到了所要的數(shù)據(jù),下面是具體的程序代碼。
Dim bytinput() as byte ‘注意要將bytinput定義為不定長(zhǎng)數(shù)組
Dim strtem As String
Dim i as Integer
bytinput =MSComm1.Input ‘將輸入緩沖區(qū)數(shù)據(jù)讀入給字節(jié)型數(shù)組bytinput
For i = 0 To UBound(bytinput)
strtem = strtem + Chr(bytinput(i)) ‘字節(jié)數(shù)組中的ASCII碼值轉(zhuǎn)換成相應(yīng) Next 的字符
得到的strtem字符就形象的展示了電流、電壓和功率值。對(duì)于WT230而言,它的數(shù)據(jù)結(jié)構(gòu)是這樣的,每個(gè)數(shù)據(jù)之間由逗號(hào)字符“,”隔開(kāi),每個(gè)數(shù)據(jù)以用科學(xué)計(jì)數(shù)法表示,且每個(gè)數(shù)據(jù)以字符“E”分為前半部分和后半部分,前半部分為具體的數(shù)據(jù)(整數(shù)形式),后半部分為此數(shù)據(jù)的指數(shù),指數(shù)的底為10。
例如得到strtem的值為“23423E-2,00241E-3,05645E-2”這就表示電壓值為234.23 V,電流值為0.241 A,功率為56.45 W。
6結(jié)論
串口通訊的硬件投資少,軟件編程簡(jiǎn)單,在低速少量數(shù)據(jù)傳輸方面的應(yīng)用極其廣泛的應(yīng)用。本文詳細(xì)介紹了串口通訊的基本內(nèi)容及其具體實(shí)現(xiàn)方式,讀者可以根據(jù)具體情況進(jìn)行選擇。以上代碼是實(shí)現(xiàn)串口通信的核心部分,經(jīng)過(guò)筆者在多個(gè)數(shù)據(jù)采集系統(tǒng)開(kāi)發(fā)中的應(yīng)用,具有較強(qiáng)的實(shí)用價(jià)值。
參考文獻(xiàn)
1 李朝青.PC機(jī)及單片機(jī)數(shù)據(jù)通信技術(shù)[M].北京:國(guó)防工業(yè)出版社,2002
2 李長(zhǎng)林.Visual Basic串口通信技術(shù)與典型實(shí)例[M].北京:清華大學(xué)出版社,2006
3 [美] Microsoft公司著、北京希望電腦公司譯.Microsoft Visual Basic 6.0 控件參考手冊(cè)[M],1999
4 朱友芹.新編Windows API參考大全[M].電子工業(yè)出版社,2000
5 MOXA Crop.Pcomm Library Programming Guide,1998
6 范逸之.Visual Basic 與RS232串行通信控制.北京:中國(guó)青年出版社,2000
Serial communication and the program based on Visual Basic
Wen Cai, Zhang Xiaosong
Abstract:Serial communication has broad application in many fields because of its simple communication circuitry and flexibility. Based on deep comprehension of the technology of the serial communications, this article expounds important technology detail integrated with practice experience. An example of communication program is presented and analyzed, which gives other researchers valuable reference information.
Key words:serial; RS232; API; Pcomm; Mscomm; communication program