關(guān)鍵詞:串口;RS232;API;Pcomm;Mscomm;通信程序
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
現(xiàn)在通訊方式越來越多,速度越來越快,但串行通訊由于自身價(jià)格低、協(xié)議透明、硬件投資少、軟件編程簡單等諸多優(yōu)點(diǎn)在遠(yuǎn)程數(shù)據(jù)采集、監(jiān)視、 通信及控制領(lǐng)域里一直占據(jù)著極其重要的地位。它不僅沒有因?yàn)闀r(shí)代的進(jìn)步而被淘汰,反而在規(guī)格上越來越完善、應(yīng)用越來越廣,長久不衰。
1串口通信的通信機(jī)理
PC串行通信是指直接對串行端口的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è)地址訪問,其中5個(gè)寄存器的訪問條件是先設(shè) 置3FBH線路控制寄存器的最高位為“1”,該位也稱為DLAB狀態(tài)位。[1]
一般說來,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)來的比特流數(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程序員,要編寫串口通信程序,只需知道通信控件提供給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代表美國電子工業(yè)協(xié)會(huì),RS代表推薦標(biāo)準(zhǔn),232是標(biāo)識(shí)號(hào),C代表RS232的 最新一次修改(1969年),在這之前,有RS232A、RS232B協(xié)議。它規(guī)定連接電纜和機(jī)械、電氣特性、信號(hào)功能及傳送過程。EIA-RS- 232C定義了按位串行傳輸?shù)臄?shù)據(jù)終端設(shè)備(DTE)和數(shù)據(jù)通訊設(shè)備(DCE)之間的接口信息。RS-232C是從DTE或計(jì)算機(jī)串行接口角度來定義引腳信號(hào)的。
目前RS-232是PC 機(jī)與通信工業(yè)中應(yīng)用最廣泛的一種串行接口。RS232被定義為一種在低速率串行通訊中增加通訊距離的單端標(biāo)準(zhǔn)。RS232采取不平衡傳輸方式,即所謂的單 端通訊。[2]
DB9(9針串口)的接線方式如下:1腳,數(shù)據(jù)載波檢測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腳,請求發(fā)送RTS;8腳,清除發(fā)送CTS;9腳,振鈴指示DELL。
DB25(25陣串口),常用的針腳也有9個(gè),且和DB9可以一一對應(yīng),具體接線方式為:8腳,數(shù)據(jù)載波檢測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腳,請求發(fā)送RTS;5腳,清除發(fā)送CTS;22腳,振鈴指示 DELL。
一般來說,對于要求不太高的場合,使用接收數(shù)據(jù)RXD,發(fā)送數(shù)據(jù)TXD,信號(hào)地GND三個(gè)腳即可實(shí)現(xiàn)數(shù)據(jù)傳輸。如果要求有硬件流 控制,則必須使用DTR、DSR、RTS和CTS這四個(gè)腳。
值得注意的是RS-232C是用正負(fù)電壓來表示邏輯狀態(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)行過程,程序員只需編寫少量的代碼就可以完成軟件的開發(fā)過程。在通信數(shù)據(jù)量不大,通信要求不是很高的情況 下建議采取此方式。
利用Mscomm控件實(shí)現(xiàn)通信最需要掌握的就是它的幾個(gè)主要屬性,下面選取其中重要的進(jìn)行介紹,其余的可以參考相關(guān)資 料。[3]
(1)Settings屬性:以字符串的形式設(shè)置并返回波特率、 奇偶校驗(yàn)位、數(shù)據(jù)位、停止位。這個(gè)屬性很重要,針對不同的終端設(shè)備需要根據(jù)設(shè)備的具體情況進(jìn)行調(diào)整(比如日本的設(shè)備不同于美國的設(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á)到或超過該值后就產(chǎn)生代碼為ComEvReceive的OnComm事件。
(6)Handshaking屬性:設(shè)置和返回握手協(xié)議,即計(jì)算機(jī)內(nèi)部CPU與串口之間的通訊協(xié)議,保證在緩沖區(qū)過載時(shí)數(shù)據(jù)不會(huì)丟失。這個(gè)屬性在保證數(shù)據(jù) 傳輸?shù)恼_性方面有很大的作用,共有四個(gè)選項(xiàng),分別表示:①無流控制;②軟件流控制;③硬件流控制;④軟硬件流控制。采用硬件流控時(shí),要求串口之間和電纜 支持硬件握手,在自己制作串口通信線時(shí),有關(guān)硬件握手的線RTS、CTS、DSR、DTR要連接正確。
在正確設(shè)置這些屬性的基礎(chǔ)上,剩下的 就是打開串口,通過串口發(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ì)量要求較高的場合。
在32位的Windows系統(tǒng)中,串口通信是作為文件處理的,串口操 作一般為打開、關(guān)閉、讀取、寫入等操作,相應(yīng)的Windows API函數(shù)如下:[4]
(1) CreateFile()函數(shù):實(shí)現(xiàn)串口的初始化并打開串口,返回串口句柄資源以供后續(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++編寫,所以在Visual Basic 6.0 中調(diào)用Windows API函數(shù)之前必須先在模塊級代碼上用Declare語句對所調(diào)用的函數(shù)和用到的數(shù)據(jù)結(jié)構(gòu)進(jìn)行聲明,具體的函數(shù)聲明及數(shù)據(jù)結(jié)構(gòu)請參考朱友芹編《新編Windows API參考大全》。
3.3調(diào)用第 三方函數(shù)庫(如Pcomm函數(shù)庫)
DLL(Dynamic Link Library)動(dòng)態(tài)鏈接庫是一種可以被VB語言調(diào)用的程序模塊。DLL中包含的可執(zhí)行代碼不能單獨(dú)執(zhí)行,而應(yīng)由Windows應(yīng)用程序調(diào)用執(zhí)行。一般數(shù) 據(jù)采集卡的供應(yīng)商都會(huì)提供該采集卡的DLL庫函數(shù),使用這些DLL庫函數(shù),可以做到程序代碼共享,減少程序的編寫工作量。用戶不需要知道這些代碼的實(shí)現(xiàn)細(xì) 節(jié),只需要了解調(diào)用函數(shù)的參數(shù)和函數(shù)處理后的返回值。
Pcomm函數(shù)庫是由臺(tái)灣Moxa公司為開發(fā)串口通信程序提供的一套函數(shù)庫。通過對 Windows API函數(shù)的進(jìn)一步封裝,提供50多個(gè)串口操作函數(shù)。覆蓋了Windows操作系統(tǒng)下幾乎所有異步通信的問題,可以簡潔的開發(fā)多線程通訊程序。采用該庫, 通信的可靠性與使用MSComm32控件比較有了明顯提高, 而相對直接使用Win32API函數(shù)編程則降低了程序開發(fā)難度, 縮短了程序開發(fā)周期。
這種方式上述直接調(diào)用Windows API函數(shù)有相似之處,但也有明顯的差異。API函數(shù)常采取的方法是在串口監(jiān)視線程中設(shè)置串口通信事件掩碼及重疊機(jī)制,允許程序在后臺(tái)等待串口通信事件。 通過WaitCommEvent檢測特定的串行通信事件。而在Pcomm中,可以采用中斷處理的方式,為各種事件指定相應(yīng)的中斷處理函數(shù),如接收到一定數(shù) 目的字符,接收到結(jié)束字符,接收到中止信號(hào)以及發(fā)送緩沖區(qū)為空等;同時(shí)還可以采用線程控制的方式,直接采用庫中的sio_read()和 sio_write()函數(shù)讀寫串口。
Pcomm..DLL中的函數(shù)按功能分為6項(xiàng):端口設(shè)置、數(shù)據(jù)發(fā)送與接收、串口狀態(tài)檢測、事件服務(wù)、 文件傳輸、雜項(xiàng)。Pcomm..DLL中主要的函數(shù)介紹如下。[5]
sio_open:打開端口;sio_close: 關(guān)閉端口。
sio_ioctl:設(shè)置端口參數(shù),如波特率等。
sio_read:從端口接收數(shù)據(jù);sio_write向端口發(fā)送數(shù)據(jù)。
sio_iqueue:得到接收緩沖區(qū)中的數(shù)據(jù)長度。
sio_oqueue:得到發(fā)送緩沖區(qū)中的數(shù)據(jù)長度。
Pcomm在串口 通信中的功能十分強(qiáng)大,但基于篇幅的考慮,在此不便贅述,讀者可參考相關(guān)書籍或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事件的指示,下面簡單介紹幾個(gè)重要的CommEvent屬性值。
ComEventBreak:表 示收到一個(gè)中斷信號(hào);
ComEventFrame:表示硬件檢測到一個(gè)數(shù)據(jù)幀錯(cuò)誤;
ComEvenRxover:表示接收緩 沖區(qū)溢出;
ComEventTxFull:表示輸出緩沖區(qū)已滿;
ComEvReceive:表示接手到了 Rthreshold個(gè)字符;
ComEvEOF:表示接受到了EOF字符(ASCII字符26)。
編程時(shí)用 SelectCase語句,根據(jù)不同的CommEvent屬性值,去執(zhí)行不同的處理程序。
除了以上所述的通訊錯(cuò)誤外,在串口通信時(shí),如果數(shù) 據(jù)傳輸突然中斷,對串口的讀寫操作可能會(huì)進(jìn)入無限期的等待狀態(tài), 為避免這種情況發(fā)生, 必須設(shè)置串口讀寫操作的等待時(shí)間, 等待超時(shí)后,串口的讀寫操作將被主動(dòng)放棄,這樣即使數(shù)據(jù)傳輸突然中斷程序也不會(huì)被掛起或阻塞。可以根據(jù)具體要求規(guī)定串口讀寫操作的最長時(shí)間值,即串口讀寫 必須在這段時(shí)間內(nèi)完成,否則提示串口操作失敗。
5串口通訊實(shí)例
本實(shí)例是一個(gè)采集設(shè)備電流及功率 的通訊程序,采集儀為橫河WT230數(shù)字功率計(jì),因?yàn)橐杉臄?shù)據(jù)量不大,且工程結(jié)構(gòu)簡單,故采用Mscomm控件的形式進(jìn)行串口讀寫操作。
具體實(shí)現(xiàn)步驟如下:
(1) 在窗體Form上添加兩個(gè)重要的控件:Timer1和Mscomm1;
(2) 在程序的Form_Load事件過程中添加如下代碼:
MSComm1.CommPort=1 ‘使用COM1端口
MSComm1.Setting=“9600,o,8,1” ‘設(shè)置通信口參數(shù),注意是奇校驗(yàn),具體的校驗(yàn)方式要視具體的儀器而定
MSComm1.InputMode=comInputModeBinary ‘設(shè)置接收模式為二進(jìn)制形式,注意一般對于數(shù)據(jù)采集這類設(shè)備通信,都應(yīng)該設(shè)置為二進(jìn)制形式
MSComm1.PortOpen=True ‘參數(shù)設(shè)置好后打開端口
MSComm1.HandShaking=2-comRTS ‘設(shè)置為硬件流控制,可以有效避免數(shù)據(jù)丟失的情況發(fā)生
(3) 程序開始后在一定情況設(shè)置Timer1.Enabled屬性值為True 激活Timer1_Time事件,可以在固定的時(shí)間間隔下執(zhí)行Timer1_Timer過程中的代碼程序,完成數(shù)據(jù)采集。在Timer1_Timer過程 中添加如下代碼:
MSComm1.Output = "COMMUNICATE:WAIT 1" + Chr(13) + Chr(10)
MSComm1.Output = "MEASURE:NORMAL:VALUE?" + Chr(13) + Chr(10)
上述語句是將讀取指令發(fā)送到串口輸出緩沖區(qū)(注意每個(gè)命令字符串后都要加上回車和換行符Chr(13) + Chr(10)),再由系統(tǒng)將其自動(dòng)發(fā)送給通過RS232通信線與計(jì)算機(jī) 端口連接的WT230數(shù)字功率計(jì),功率計(jì)在接收到命令字符串后,經(jīng)過自身的單片機(jī)處理,就自動(dòng)地把它測到的電壓、電流、功率數(shù)據(jù)以固定的格式和字符形式通 過RS232通信線傳回至計(jì)算機(jī),計(jì)算機(jī)程序從輸入緩沖區(qū)讀取這些字符數(shù)據(jù)并利用VB字符處理函數(shù)(如Val,InStr)進(jìn)行處理就得到了所要的數(shù)據(jù), 下面是具體的程序代碼。
Dim bytinput() as byte ‘注意要將bytinput定義為不定長數(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字符就形象的展示了電流、電壓和功率值。對于WT230而言,它的數(shù)據(jù)結(jié)構(gòu)是這樣的,每個(gè)數(shù)據(jù)之間由逗號(hào)字符“,”隔開,每個(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é)論
串口通訊的硬件投資少,軟件編程簡單,在低速少量數(shù)據(jù)傳輸方 面的應(yīng)用極其廣泛的應(yīng)用。本文詳細(xì)介紹了串口通訊的基本內(nèi)容及其具體實(shí)現(xiàn)方式,讀者可以根據(jù)具體情況進(jìn)行選擇。以上代碼是實(shí)現(xiàn)串口通信的核心部分,經(jīng)過筆 者在多個(gè)數(shù)據(jù)采集系統(tǒng)開發(fā)中的應(yīng)用,具有較強(qiáng)的實(shí)用價(jià)值。
參 考文獻(xiàn)
1 李朝青.PC機(jī)及單片機(jī)數(shù)據(jù)通信技術(shù)[M].北京:國防工業(yè)出 版社,2002
2 李長林.Visual Basic串口通信技術(shù)與典型實(shí)例[M].北京:清華大學(xué)出版社,2006
3 [美] Microsoft公司著、北京希望電腦公司譯.Microsoft Visual Basic 6.0 控件參考手冊[M],1999
4 朱友芹.新編Windows API參考大全[M].電 子工業(yè)出版社,2000
5 MOXA Crop.Pcomm Library Programming Guide,1998
6 范逸之.Visual Basic 與RS232串行通信控制.北京:中國青年出版社,2000
本站論文資源均為來自網(wǎng)絡(luò)轉(zhuǎn)載,免費(fèi)提供給廣大作者參考,不進(jìn)行任何贏利,如有版權(quán)問題,請聯(lián)系管理員刪除! 快速論文發(fā)表網(wǎng)(www.6scc.cn)本中心和國內(nèi)數(shù)百家期刊雜志社有良好的合作關(guān)系,可以幫客戶代發(fā)論文投稿.
投稿郵箱:ksfbw@126.com
客服Q Q:
82702382
聯(lián)系電話:15295038833
本站論文資源均為來自網(wǎng)絡(luò)轉(zhuǎn)載,免費(fèi)提供給廣大作者參考,不進(jìn)行任何贏利,如有版權(quán)問題,請聯(lián)系管理員刪除!