開發(fā)在WINDOWS下的串口異步通信程序-免費(fèi)畢業(yè)設(shè)計(jì)論文_第1頁(yè)
開發(fā)在WINDOWS下的串口異步通信程序-免費(fèi)畢業(yè)設(shè)計(jì)論文_第2頁(yè)
開發(fā)在WINDOWS下的串口異步通信程序-免費(fèi)畢業(yè)設(shè)計(jì)論文_第3頁(yè)
開發(fā)在WINDOWS下的串口異步通信程序-免費(fèi)畢業(yè)設(shè)計(jì)論文_第4頁(yè)
開發(fā)在WINDOWS下的串口異步通信程序-免費(fèi)畢業(yè)設(shè)計(jì)論文_第5頁(yè)
已閱讀5頁(yè),還剩42頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

PAGEPAGE47用VC開發(fā)在Windows下的串口異步通信程序?qū)W生:指導(dǎo)老師:用VC開發(fā)在Windows下的串口異步通信程序摘要異步串行通信在現(xiàn)在的生產(chǎn)生活中被得到廣泛的應(yīng)用,在PC機(jī)上一般至少有兩個(gè)串行口COM1和COM2,常用的串行外設(shè)有電傳打字機(jī)、CRT終端設(shè)備、傳真機(jī)以及遠(yuǎn)程數(shù)據(jù)采集設(shè)備、通信設(shè)備等。串行通信接口標(biāo)準(zhǔn)經(jīng)過使用和發(fā)展,目前已經(jīng)有多種。但都是在RS-232標(biāo)準(zhǔn)的基礎(chǔ)上經(jīng)過改進(jìn)而形成的。如何在Windows平臺(tái)下實(shí)現(xiàn)串口通信,也越來(lái)越來(lái)越多地被得到研究,實(shí)現(xiàn)的方法重要有利用MSComm控件和直接用WindowsAPI編程。利用MSComm控件編程相對(duì)來(lái)說更簡(jiǎn)單一些,而直接使用WindowsAPI編程更靈活一些。本文主要討論了使用MSComm控件來(lái)開發(fā)串口通信程序,而界面是利用VC++6.0MFC來(lái)做的,這樣編程靈活性大,并且能夠?qū)⒅饕ぷ骷性诖诰幊谭矫?。程序可以?shí)現(xiàn)利用PC機(jī)的兩個(gè)COM口實(shí)現(xiàn)異步通信,并能根據(jù)設(shè)置調(diào)整異步傳行通信參數(shù)?!娟P(guān)鍵詞】串口通信、異步通信、終端、句柄

Abstract

Serialcommunicationisusedmoreandmoreinourjobandlivings.TherearetwoserialcommunicationportatleastinthePC,COM1andCOM2.Typewriter,CRTterminaldevice,electrograph,remotedadareceiver,andcommunicationdevicearedependedonserialport.Withthedevelopmentofserialcommunicationportstandard,therearemanykindsofportstandard,buttheyaredevelopedfromtheRS-232standard.HowtoprogramserialcommunicationbasedontheWindowsplatformisstudiedmoreandmore.Therearetwomethodsofprogramming,usingWindowsAPIandusingMSCcomm.UsingMSCcommtoprogramisdiscussedinthearticle,thegraphicalinterfaceiscarriedoutusingMFC.Sothismethodisflexibleandwecansetfocusinprogrammingserialcommunication.TwoPCcancommunicatetoeachotherbyCOMportandyoucanchangetheserialportparameterwiththeprogram.Keywords:serialportcommunication,asynchronouscommunication,terminaldevice,HANDLE

目錄TOC\o"1-3"\h\z摘要 2Abstract 3引言 2第1章緒論 31.1 問題的提出 31.2 研究的意義 3第2章相關(guān)技術(shù)簡(jiǎn)介 62.1

串行接口標(biāo)準(zhǔn) 62.2

RS-232串行接口標(biāo)準(zhǔn) 82.3

其他EIA標(biāo)準(zhǔn)接口 132.4VC++的串口通訊 152.4.1MicrosoftCommunicationsControl 162.4.2直接用VC++訪問串口。 182.5MSComm控件介紹 242.5.1MSComm控件的通訊的方式 242.5.2MSComm控件的屬性 25第3章系統(tǒng)設(shè)計(jì) 313.1系統(tǒng)功能設(shè)計(jì) 313.2算法分析 33第4章系統(tǒng)調(diào)試與運(yùn)行 384.1系統(tǒng)調(diào)試 384.2系統(tǒng)測(cè)試與運(yùn)行 384.2.1測(cè)試方法 384.2.2測(cè)試內(nèi)容 394.2.3測(cè)試結(jié)果 39第5章結(jié)論 40致謝 41參考文獻(xiàn) 42

引言在Windows應(yīng)用程序的開發(fā)過程中,相互之間常常需要通信。而串口是工業(yè)控制中計(jì)算機(jī)與外部串行設(shè)備之間常用的數(shù)據(jù)傳輸通道,由于串行通信方便易行,其應(yīng)用非常廣泛。本文將介紹串行通信的基本原理、在Windows平臺(tái)下的工作機(jī)制和用VC實(shí)現(xiàn)串行通信的方法。串口是工業(yè)控制中計(jì)算機(jī)與外部設(shè)備之間常用的數(shù)據(jù)傳輸通道。但在Windows環(huán)境下,計(jì)算機(jī)系統(tǒng)完全接管了各種硬件資源,不允許用戶直接控制串口的中斷管理,用戶只能通過一些Windows開發(fā)軟件,如VisualBasic、VisualC++等才能控制計(jì)算機(jī)的底層資源。VisualC++因其高性能編譯技術(shù)、面向?qū)ο笤O(shè)計(jì)方法、可視化開發(fā)環(huán)境等特點(diǎn)得到廣泛的應(yīng)用,它包含了豐富的編程工具,具有很高的代碼效率,提供了與Windows系統(tǒng)更緊密的接口,易于進(jìn)行硬件訪問,是一個(gè)靈活度和集成化都很高的軟件開發(fā)環(huán)境,非常適合開發(fā)Windows應(yīng)用程序。本文以Windows環(huán)境下串口的通信為基礎(chǔ),主要介紹串行通信的基本原理,并探討用VisualC++6.0開發(fā)串口通信程序的幾種方法。

第1章緒論問題的提出在Windows應(yīng)用程序的開發(fā)中,我們常常需要面臨與外圍數(shù)據(jù)源設(shè)備通信的問題。計(jì)算機(jī)和單片機(jī)(如MCS-51)都具有串行通信口,可以設(shè)計(jì)相應(yīng)的串口通信程序,完成二者之間的數(shù)據(jù)通信任務(wù)。串口是計(jì)算機(jī)上一種非常通用設(shè)備通信的協(xié)議(不要與通用串行總線UniversalSerialBus或者USB混淆)。大多數(shù)計(jì)算機(jī)包含兩個(gè)基于RS232的串口。串口同時(shí)也是儀器儀表設(shè)備通用的通信協(xié)議;很多GPIB兼容的設(shè)備也帶有RS-232口。同時(shí),串口通信協(xié)議也可以用于獲取遠(yuǎn)程采集設(shè)備的數(shù)據(jù)。研究的意義串口通信的概念非常簡(jiǎn)單,串口按位(bit)發(fā)送和接收字節(jié)。盡管比按字節(jié)(byte)的并行通信慢,但是串口可以在使用一根線發(fā)送數(shù)據(jù)的同時(shí)用另一根線接收數(shù)據(jù)。它很簡(jiǎn)單并且能夠?qū)崿F(xiàn)遠(yuǎn)距離通信。比如IEEE488定義并行通行狀態(tài)時(shí),規(guī)定設(shè)備線總長(zhǎng)不得超過20米,并且任意兩個(gè)設(shè)備間的長(zhǎng)度不得超過2米;而對(duì)于串口而言,長(zhǎng)度可達(dá)1200米。典型地,串口用于ASCII碼字符的傳輸。通信使用3根線完成:(1)地線,(2)發(fā)送,(3)接收。由于串口通信是異步的,端口能夠在一根線上發(fā)送數(shù)據(jù)同時(shí)在另一根線上接收數(shù)據(jù)。其他線用于握手,但是不是必須的。串口通信最重要的參數(shù)是波特率、數(shù)據(jù)位、停止位和奇偶校驗(yàn)。對(duì)于兩個(gè)進(jìn)行通行的端口,這些參數(shù)必須匹配:a,波特率:這是一個(gè)衡量通信速度的參數(shù)。它表示每秒鐘傳送的bit的個(gè)數(shù)。例如300波特表示每秒鐘發(fā)送300個(gè)bit。當(dāng)我們提到時(shí)鐘周期時(shí),我們就是指波特率例如如果協(xié)議需要4800波特率,那么時(shí)鐘是4800Hz。這意味著串口通信在數(shù)據(jù)線上的采樣率為4800Hz。通常電話線的波特率為14400,28800和36600。波特率可以遠(yuǎn)遠(yuǎn)大于這些值,但是波特率和距離成反比。高波特率常常用于放置的很近的儀器間的通信,典型的例子就是GPIB設(shè)備的通信。b,數(shù)據(jù)位:這是衡量通信中實(shí)際數(shù)據(jù)位的參數(shù)。當(dāng)計(jì)算機(jī)發(fā)送一個(gè)信息包,實(shí)際的數(shù)據(jù)不會(huì)是8位的,標(biāo)準(zhǔn)的值是5、7和8位。如何設(shè)置取決于你想傳送的信息。比如,標(biāo)準(zhǔn)的ASCII碼是0~127(7位)。擴(kuò)展的ASCII碼是0~255(8位)。如果數(shù)據(jù)使用簡(jiǎn)單的文本(標(biāo)準(zhǔn)ASCII碼),那么每個(gè)數(shù)據(jù)包使用7位數(shù)據(jù)。每個(gè)包是指一個(gè)字節(jié),包括開始/停止位,數(shù)據(jù)位和奇偶校驗(yàn)位。由于實(shí)際數(shù)據(jù)位取決于通信協(xié)議的選取,術(shù)語(yǔ)“包”指任何通信的情況。c,停止位:用于表示單個(gè)包的最后一位。典型的值為1,1.5和2位。由于數(shù)據(jù)是在傳輸線上定時(shí)的,并且每一個(gè)設(shè)備有其自己的時(shí)鐘,很可能在通信中兩臺(tái)設(shè)備間出現(xiàn)了小小的不同步。因此停止位不僅僅是表示傳輸?shù)慕Y(jié)束,并且提供計(jì)算機(jī)校正時(shí)鐘同步的機(jī)會(huì)。適用于停止位的位數(shù)越多,不同時(shí)鐘同步的容忍程度越大,但是數(shù)據(jù)傳輸率同時(shí)也越慢。d,奇偶校驗(yàn)位:在串口通信中一種簡(jiǎn)單的檢錯(cuò)方式。有四種檢錯(cuò)方式:偶、奇、高和低。當(dāng)然沒有校驗(yàn)位也是可以的。對(duì)于偶和奇校驗(yàn)的情況,串口會(huì)設(shè)置校驗(yàn)位(數(shù)據(jù)位后面的一位),用一個(gè)值確保傳輸?shù)臄?shù)據(jù)有偶個(gè)或者奇?zhèn)€邏輯高位。例如,如果數(shù)據(jù)是011,那么對(duì)于偶校驗(yàn),校驗(yàn)位為0,保證邏輯高的位數(shù)是偶數(shù)個(gè)。如果是奇校驗(yàn),校驗(yàn)位位1,這樣就有3個(gè)邏輯高位。高位和低位不真正的檢查數(shù)據(jù),簡(jiǎn)單置位邏輯高或者邏輯低校驗(yàn)。這樣使得接收設(shè)備能夠知道一個(gè)位的狀態(tài),有機(jī)會(huì)判斷是否有噪聲干擾了通信或者是否傳輸和接收數(shù)據(jù)是否不同步。

第2章相關(guān)技術(shù)簡(jiǎn)介2.1

串行接口標(biāo)準(zhǔn)在計(jì)算機(jī)網(wǎng)絡(luò)數(shù)據(jù)通信中,有幾個(gè)接口標(biāo)準(zhǔn)是經(jīng)常見到和用到的,那就是通常所說的RS-232、RS-422與RS-485標(biāo)準(zhǔn)。它們都是串行數(shù)據(jù)接口標(biāo)準(zhǔn),最初都是由電子工業(yè)協(xié)會(huì)(EIA)制定并發(fā)布的。RS-232接口(又稱EIARS-232)是目前最常用的一種串行通信接口。它是在1970年由美國(guó)電子工業(yè)協(xié)會(huì)(EIA)聯(lián)合貝爾系統(tǒng)公司、調(diào)制解調(diào)器廠家及計(jì)算機(jī)終端生產(chǎn)廠家共同制定的用于串行通信的標(biāo)準(zhǔn)。它的全名是“數(shù)據(jù)終端設(shè)備(DTE)和數(shù)據(jù)通信設(shè)備(DCE)之間串行二進(jìn)制數(shù)據(jù)交換接口技術(shù)標(biāo)準(zhǔn)”。該標(biāo)準(zhǔn)規(guī)定采用一個(gè)25腳的DB25連接器,對(duì)連接器的每個(gè)引腳的信號(hào)內(nèi)容加以規(guī)定,還對(duì)各種信號(hào)的電平加以規(guī)定。RS-422由RS-232發(fā)展而來(lái),它是為彌補(bǔ)RS-232之不足而提出的。為改進(jìn)RS-232通信距離短、速率低的缺點(diǎn),RS-422定義了一種平衡通信接口,將傳輸速率提高到10Mb/s,傳輸距離延長(zhǎng)到4000英尺(速率低于100Kb/s時(shí)),并允許在一條平衡總線上連接最多10個(gè)接收器。RS-422是一種單機(jī)發(fā)送、多機(jī)接收的單向、平衡傳輸規(guī)范,后來(lái)被命名為TIA/EIA-422A標(biāo)準(zhǔn)。為擴(kuò)展應(yīng)用范圍,EIA又于1983年在RS-422基礎(chǔ)上制定了RS-485標(biāo)準(zhǔn),增加了多點(diǎn)、雙向通信能力,即允許多個(gè)發(fā)送器連接到同一條總線上,同時(shí)增加了發(fā)送器的驅(qū)動(dòng)能力和沖突保護(hù)特性,擴(kuò)展了總線共模范圍,后命名為TIA/EIA-485A標(biāo)準(zhǔn)。由于EIA提出的建議標(biāo)準(zhǔn)都是以“RS”作為前綴的,所以在通信工業(yè)領(lǐng)域,仍然習(xí)慣將上述標(biāo)準(zhǔn)以RS作前綴稱謂,也就是上面說到的3個(gè)串行接口標(biāo)準(zhǔn)。RS-232、RS-422與RS-485標(biāo)準(zhǔn)只對(duì)接口的電氣特性作出規(guī)定,而不涉及接插件、電纜或協(xié)議,在此基礎(chǔ)上用戶可以建立自己的高層通信協(xié)議。因此在視頻界的應(yīng)用,許多廠家都建立了一套高層通信協(xié)議,或公開或廠家獨(dú)家使用。表2-1是以上3種串行接口電氣性能參數(shù)的綜合比較。表2-1

RS-232、RS-422與RS-485串行接口電氣性能參數(shù)綜合比較性能參數(shù)RS232RS422R485工作方式單端差分差分節(jié)點(diǎn)數(shù)1收1發(fā)1發(fā)10收1發(fā)32收最大傳輸電纜長(zhǎng)度50英尺400英尺400英尺最大傳輸速率20Kb/s10Mb/s10Mb/s最大驅(qū)動(dòng)輸出電壓+/-25V-0.25V~+6V-7V~+12V驅(qū)動(dòng)器輸出信號(hào)電平(負(fù)載最小值)+/-5~+/-15V+/-2.0V+/-1.5V驅(qū)動(dòng)器輸出信號(hào)電平(空載最大值)+/-25V+/-6V+/-6V驅(qū)動(dòng)器負(fù)載阻抗(W)3k~7k10054擺率(最大值)30V/μsN/AN/A接收器輸入電壓范圍+/-15V-10V~+10V-7V~+12V接收器輸入門限+/-3V+/-200mV+/-200mV接收器輸入電阻(W)3k~7k4k(最?。?2k驅(qū)動(dòng)器共模電壓-3V~+3V-1V~+3V接收器共模電壓-7V~+7V-7V~+12V2.2

RS-232串行接口標(biāo)準(zhǔn)目前RS-232是PC與通信工業(yè)中應(yīng)用最廣泛的一種串行接口,其中EIA(ElectronicIndustryAssociation)代表美國(guó)電子工業(yè)協(xié)會(huì),RS代表推薦標(biāo)準(zhǔn),232是標(biāo)識(shí)號(hào)。RS-232被定義為一種在低速率串行通信中增加通信距離的單端標(biāo)準(zhǔn)。RS-232采取不平衡傳輸方式,即所謂單端通信。一個(gè)完整的RS-232接口有22根線,采用標(biāo)準(zhǔn)的25芯插頭座(DB-25)。除此之處,目前廣泛應(yīng)用的還有一種9芯的RS-232接口(DB-9)。它們的外觀都是一個(gè)D形的,不過,對(duì)接的兩個(gè)接口又分為針式的“公頭”和孔式的“母頭”兩種,DB-9“母頭”和“公頭”與DB-25的“母頭”和“公頭”分別如圖2-1所示。圖2-1

DB-9/DB-25的“公頭”和“母頭”在RS-232標(biāo)準(zhǔn)中定義了邏輯1和邏輯0電壓級(jí)數(shù),以及標(biāo)準(zhǔn)的傳輸速率和連接器類型。信號(hào)大小在正的和負(fù)的3~15V之間。RS-232規(guī)定接近0的電平是無(wú)效的,邏輯1規(guī)定為負(fù)電平,有效負(fù)電平的信號(hào)狀態(tài)稱為傳號(hào)(Marking),它的功能意義為OFF;邏輯0規(guī)定為正電平,有效正電平的信號(hào)狀態(tài)稱為空號(hào)(Spacing),它的功能意義為ON。根據(jù)設(shè)備供電電源的不同,正負(fù)5、正負(fù)10、正負(fù)12和正負(fù)15這樣的電平都是可能的。在RS-232標(biāo)準(zhǔn)中規(guī)定的設(shè)備可以分為數(shù)據(jù)終端設(shè)備(DTE)和數(shù)據(jù)通信設(shè)備(DCE)兩類,這種分類定義了不同的線路用來(lái)發(fā)送和接收信號(hào)。一般來(lái)說,計(jì)算機(jī)和終端設(shè)備有DTE連接器,調(diào)制解調(diào)器和打印機(jī)有DCE連接器。RS-232標(biāo)準(zhǔn)中指定了20個(gè)不同的信號(hào)連接,由25個(gè)D-sub(微型D類)管腳構(gòu)成的DB-25連接器。但很多設(shè)備只用了其中的一小部分管腳,出于節(jié)省資金和空間的考慮不少機(jī)器采用較小的連接器,特別是9管腳的D-sub或者是DB-9型連接器被廣泛使用。因?yàn)镽S-232到目前為止經(jīng)歷了好多個(gè)不同版本,最近的版本號(hào)為E,它相對(duì)目前廣泛應(yīng)用的C版本來(lái)說,電氣性能改進(jìn)了不少,也對(duì)連接器中的25個(gè)管腳進(jìn)行了充分利用(只有2個(gè)予以保留)。表2-2列出的是25芯RS-232E接口的信號(hào)和管腳分配,而表2-3所示的則是在PC機(jī)、調(diào)制解調(diào)器和路由器等網(wǎng)絡(luò)設(shè)備中使用的9芯RS-232接口的信號(hào)和管腳分配。表2-2

25芯RS-232接口的信號(hào)和管腳分配引

號(hào)縮

符信號(hào)方向說

明1PE公共端連接器外殼2TXD輸出發(fā)送數(shù)據(jù)3RXD輸入接收數(shù)據(jù)4RTS輸出請(qǐng)示發(fā)送5CTS輸入清除發(fā)送6DSR輸入數(shù)據(jù)設(shè)備準(zhǔn)備好7SG公共端信號(hào)地8DCD輸入載波檢測(cè)9——保留10——保留11STF輸出選擇傳送通道12DCD輸入載波檢測(cè)13CTS輸入清除發(fā)送14TXD輸出發(fā)送數(shù)據(jù)15TCK輸入發(fā)送時(shí)鐘16RXD輸入接收數(shù)據(jù)17RCK輸入接收器定時(shí)18LL輸出本地回路控制19RTS輸出請(qǐng)示發(fā)送20DTR輸出數(shù)據(jù)終端準(zhǔn)備好21RL輸出遠(yuǎn)程回路控制22RI輸入振鈴指示器23DSR輸入數(shù)據(jù)裝置準(zhǔn)備好24XCK輸出發(fā)送器定時(shí)25TI輸入測(cè)試指示器表2-3

9芯RS-232接口的信號(hào)和管腳分配引

號(hào)縮

符信號(hào)方向說

明1DCD輸入載波檢測(cè)2RXD輸入接收數(shù)據(jù)3TXD輸出發(fā)送數(shù)據(jù)4DTR輸出數(shù)據(jù)終端準(zhǔn)備好5GND公共端信號(hào)地6DSR輸入數(shù)據(jù)裝置準(zhǔn)備好7RTS輸出請(qǐng)示發(fā)送8CTS輸入清除發(fā)送9RI輸入振鈴指示在RS-232C版本中,DB-25的25個(gè)引腳(4個(gè)數(shù)據(jù)引腳、11個(gè)控制信號(hào)引腳、3個(gè)定時(shí)引腳、7個(gè)備用和未定義引腳)實(shí)際上只用了表2-2中的9個(gè),分別是:1、2、3、4、5、6、8、20、22腳。它們的作用分別如下。(1)控制信號(hào)引腳(4、5、6、8、20和22號(hào)6個(gè)引腳)

數(shù)據(jù)裝置準(zhǔn)備好(DataSetReady,DSR):有效時(shí)(ON)狀態(tài),表明接口處于可以使用的狀態(tài)。

數(shù)據(jù)終端準(zhǔn)備好(DataTerminalReady,DTR):有效時(shí)(ON)狀態(tài),表明數(shù)據(jù)終端可以使用。這兩個(gè)信號(hào)有時(shí)連到電源上,一上電就立即有效。但這兩個(gè)設(shè)備狀態(tài)信號(hào)有效,只表示設(shè)備本身可用,并不說明通信鏈路可以開始進(jìn)行通信了,能否開始進(jìn)行通信要由下面的控制信號(hào)決定。

請(qǐng)求發(fā)送(RequestToSend,RTS):用來(lái)表示DTE請(qǐng)求DCE發(fā)送數(shù)據(jù),即當(dāng)終端要發(fā)送數(shù)據(jù)時(shí),使該信號(hào)有效(ON狀態(tài)),向DTE設(shè)備請(qǐng)求發(fā)送。

允許發(fā)送(ClearToSend,CTS):用來(lái)表示DCE準(zhǔn)備好接收DTE發(fā)來(lái)的數(shù)據(jù),是對(duì)請(qǐng)求發(fā)送信號(hào)RTS的響應(yīng)信號(hào)。當(dāng)MODEM之類設(shè)備已準(zhǔn)備好接收終端傳來(lái)的數(shù)據(jù)并向前發(fā)送時(shí),使該信號(hào)有效,通知終端開始沿發(fā)送數(shù)據(jù)線TxD發(fā)送數(shù)據(jù)。這對(duì)RTS/CTS請(qǐng)求應(yīng)答聯(lián)絡(luò)信號(hào)是用于半雙工MODEM系統(tǒng)中發(fā)送方式和接收方式之間的切換。在全雙工系統(tǒng)中作發(fā)送方式和接收方式之間的切換。在全雙工系統(tǒng)中,因配置雙向通道,故不需要RTS/CTS聯(lián)絡(luò)信號(hào)使其變高。

數(shù)據(jù)載波檢出(DataCarrierDectection,DCD):也叫“接收線信號(hào)檢出”(ReceivedLineDectection,RLSD),用來(lái)表示DCE已接通通信鏈路,告知DTE準(zhǔn)備接收數(shù)據(jù)。當(dāng)本地的MODEM收到由通信鏈路另一端(遠(yuǎn)地)的MODEM送來(lái)的載波信號(hào)時(shí),使RLSD信號(hào)有效,通知終端準(zhǔn)備接收,并且由MODEM將接收下來(lái)的載波信號(hào)解調(diào)成數(shù)字?jǐn)?shù)據(jù)后,沿接收數(shù)據(jù)線RxD送到終端。

振鈴指示(Ringing,RI):當(dāng)MODEM收到交換臺(tái)送來(lái)的振鈴呼叫信號(hào)時(shí),使該信號(hào)有效(ON狀態(tài)),通知終端,已被呼叫。(2)數(shù)據(jù)發(fā)送與接收線(2和3號(hào)2個(gè)引腳)

發(fā)送數(shù)據(jù)(TransmittedData,TxD):通過TxD終端將串行數(shù)據(jù)發(fā)送到MODEM,(DTE→DCE)。

接收數(shù)據(jù)(ReceivedData,RxD):通過RxD線終端接收從MODEM發(fā)來(lái)的串行數(shù)據(jù),(DCE→DTE)。(3)地線SG(7腳)、PE(1腳)分別用來(lái)接信號(hào)地和保護(hù)地信號(hào)線,無(wú)方向。上述控制信號(hào)線何時(shí)有效,何時(shí)無(wú)效的順序表示了接口信號(hào)的傳送過程。例如,只有當(dāng)DSR和DTR都處于有效(ON)狀態(tài)時(shí),才能在DTE和DCE之間進(jìn)行傳送操作。若DTE要發(fā)送數(shù)據(jù),則預(yù)先將DTR線置成有效(ON)狀態(tài),等CTS線上收到有效(ON)狀態(tài)的回答后,才能在TxD線上發(fā)送串行數(shù)據(jù)。這種順序的規(guī)定對(duì)半雙工的通信線路特別有用,因?yàn)橹挥邪腚p工的通信能確定DCE已由接收方向改為發(fā)送方向,這時(shí)線路才能開始發(fā)送。使用DB-9連接器,作為提供多功能I/O卡或主板上COM1和COM2兩個(gè)串行接口的連接器,它只提供異步通信的9個(gè)信號(hào)。DB-25型連接器的引腳分配與DB-25型引腳信號(hào)完全不同。因此,若與配接DB-25型連接器的DCE設(shè)備連接,必須使用專門的電纜線。在連接距離上,如果通信速率低于20Kbit/s時(shí),RS-232C所直接連接的最大物理距離為15m。2.3

其他EIA標(biāo)準(zhǔn)接口除了前面介紹的EIA-232接口外,在EIA接口標(biāo)準(zhǔn)中,常見的串行接口協(xié)議還有諸如EIA-422、EIA-449、EIA-485、EIA-530等,本節(jié)予以簡(jiǎn)單介紹。EIA-422(過去稱為RS-422)是采用4線、全雙工、差分傳輸、多點(diǎn)通信的數(shù)據(jù)傳輸接口協(xié)議。與下面將要介紹的EIA-485不同的是EIA-422不允許出現(xiàn)多個(gè)發(fā)送端,而只能有多個(gè)接收端(EIA-232接口也可以有多個(gè)接收端)。如EIA-232型可以有兩端口、四端口和八端口等幾種型號(hào),而EIA-422型接口可以有四端口、八端口,甚至十端口等幾種型號(hào)。EIA-422解決方案?jìng)鬏斝盘?hào)的距離和速度比標(biāo)準(zhǔn)EIA-232通信更遠(yuǎn)、更快,并且一般都能抗電子干擾和電涌。當(dāng)電纜線的長(zhǎng)度為12m(40碼)時(shí)傳輸速率可以達(dá)到10Mb/s。由于EIA-422解決方案具有上述優(yōu)點(diǎn),因此成為工業(yè)和制造應(yīng)用及分布廣泛的銷售經(jīng)營(yíng)企業(yè)的首選產(chǎn)品。EIA-422的通常用途是作為RS-232的擴(kuò)展,曾在蘋果麥金托什(MAC)上大量使用。EIA-422接口的機(jī)械特性由EIA-530或EIA-449規(guī)定,然而設(shè)備僅有在發(fā)送方和接收方成對(duì)出現(xiàn)時(shí)才存在。電纜的最高傳輸速率為在1.2m時(shí)為10Mb/s,1200m時(shí)100Kb/s。EIA-422不能實(shí)現(xiàn)像EIA-485那樣的真正的多點(diǎn)通信,盡管一個(gè)發(fā)送端就可連接最多10個(gè)接收端。EIA-449(過去也稱RS-449)接口協(xié)議是于1992年9月制定的。它規(guī)定了數(shù)據(jù)終端設(shè)備和數(shù)據(jù)通信設(shè)備之間的接口的功能特性和機(jī)械特性。規(guī)定RS-449采用平衡傳輸時(shí)的電氣特性協(xié)議是RS-422。規(guī)定非平衡傳輸時(shí)的電氣特性協(xié)議是RS-423,數(shù)據(jù)的傳輸率可達(dá)200Kbit/s。協(xié)議規(guī)定了兩個(gè)D-sub連接時(shí)第一個(gè)為37腳,第二個(gè)為9腳。盡管這種協(xié)議沒有在個(gè)人電腦上使用,這種接口在大型數(shù)據(jù)交換服務(wù)器上還是很常見的。EIA-485(過去叫做RS-485或者RS485)接口協(xié)議是電力特性規(guī)定為2線、全雙工、多點(diǎn)通信的標(biāo)準(zhǔn),它的電力特性和RS-232大不一樣,用纜線兩端的電壓差值來(lái)表示傳遞信號(hào)。1端的電壓標(biāo)識(shí)為邏輯1,另一端標(biāo)識(shí)為邏輯0。兩端的電壓差最小為0.2V以上時(shí)有效,任何不大于12V或者不小于–7V的差值對(duì)接收端都被認(rèn)為是正確的。EIA-485僅僅規(guī)定了接收端和發(fā)送端的電力特性,沒有規(guī)定或推薦任何數(shù)據(jù)協(xié)議。EIA-485可以應(yīng)用于配置便宜的廣域網(wǎng)和采用單機(jī)發(fā)送,多機(jī)接收通信連接,可提供高速的數(shù)據(jù)通信速率(10m時(shí)35Mb/s,1200m時(shí)100Kb/s)。EIA-485和EIA-422一樣使用雙絞線進(jìn)行高電壓差分平衡傳輸,可以進(jìn)行大面積長(zhǎng)距離傳輸(最長(zhǎng)為1200m)。與EIA-422不同的是,EIA-422采用不可轉(zhuǎn)換的單發(fā)送端,EIA-485的發(fā)送端需要設(shè)置為發(fā)送模式,這使得EIA-485可以使用雙線模式實(shí)現(xiàn)真正的多點(diǎn)雙向通信。EIA-485推薦使用在點(diǎn)對(duì)點(diǎn)網(wǎng)絡(luò)中,線型是總線型,不能是星型和環(huán)型網(wǎng)絡(luò)。在理想情況下EIA-485需要2個(gè)終接電阻,其阻值要求等于傳輸電纜的特性阻抗。沒有特性阻抗的話,當(dāng)所有的設(shè)備都靜止或者沒有能量的時(shí)候就會(huì)產(chǎn)生噪聲。沒有終接電阻的話,會(huì)使得較快速的發(fā)送端產(chǎn)生多個(gè)數(shù)據(jù)信號(hào)的邊緣,這其中的一些是不正確的。EIA-485不能使用星型或者環(huán)型的拓?fù)浣Y(jié)構(gòu),主要是由于在這些結(jié)構(gòu)中,EIA-485接口過低或者過高的終接電阻可以產(chǎn)生電磁干擾。EIA-485在使用4線時(shí)可以和EIA-422一樣實(shí)現(xiàn)全雙工,還可實(shí)現(xiàn)真正的多點(diǎn)通信。在某些限制條件下EIA-485和EIA-422可以實(shí)現(xiàn)相互的連接。如SCSI-2和SCSI-3控制卡通常使用這種標(biāo)準(zhǔn)的設(shè)備來(lái)作為物理層。EIA-485接口同樣可以在一些工廠的項(xiàng)目控制機(jī)器上看到,來(lái)實(shí)現(xiàn)工廠不同樓層之間的數(shù)據(jù)通信。它可以抵抗機(jī)械設(shè)備和焊接設(shè)備的電磁干擾。EIA-485還可以在大型音頻系統(tǒng)中使用,如在音樂廳或劇院中通過這種接口設(shè)備就可以使用普通的計(jì)算機(jī)來(lái)運(yùn)行一些特殊的軟件,實(shí)現(xiàn)遠(yuǎn)距離音頻設(shè)備的控制。EIA-485通過XLR標(biāo)準(zhǔn)的線纜連接設(shè)備大量用于麥克風(fēng)上,從而實(shí)現(xiàn)舞臺(tái)和控制臺(tái)之間的連接而不需要預(yù)設(shè)線路。表2-4列出了EIA-485的一些特性和引腳的分配及和RS-232的比較。表2-4

EIA-485的一些特性和引腳的分配及和RS-232的比較EIA-485RS-232DB-25DE-9CommonGroundCarrierDetect(DCD)81ClearToSend+(CTS+)ReceivedData(RD)32ReadyToSend+(RTS+)TransmittedData(TD)23ReceivedData+(RxD+)DataTerminalReady(DTR)204ReceivedData-(RxD-)CommonGround75ClearToSend-(CTS-)DataSetReady(DSR)66ReadyToSend-(RTS-)RequestToSend(RTS)47TransmittedData+(TxD+)ClearToSend(CTS)582.4VC++的串口通訊C++語(yǔ)言是當(dāng)今最流行的面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言,而VisualC++是Microsoft公司開發(fā)的基于Windows操作系統(tǒng)的C++語(yǔ)言程序的可視化編程工具。VisualC++的執(zhí)行速度快,對(duì)操作系統(tǒng)的訪問權(quán)限高,這些是其他許多編程工具所無(wú)法比擬的。因此,VisualC++成為眾多程序員在Windows操作系統(tǒng)下編程的首選工具。我們選擇VisualC++6.0(以下簡(jiǎn)稱VC6)作為我們的編程工具。它提供了強(qiáng)大的編譯能力以及良好的界面操作性。能夠?qū)indows95/98、WindowsNT以及Windows2000下的C++程序設(shè)計(jì)提供完善的編程環(huán)境。同時(shí)VC6對(duì)網(wǎng)絡(luò)、數(shù)據(jù)庫(kù)等方面的編程也都提供相應(yīng)的環(huán)境支持。在VC++中有兩種方法可以進(jìn)行串口通訊。一種是利用Microsoft公司提供的ActiveX控件MicrosoftCommunicationsControl。另一種是直接用VC++訪問串口。下面將簡(jiǎn)述這兩種方法。2.4.1MicrosoftCommunicationsControlMicrosoft公司在WINDOWS中提供了一個(gè)串口通訊控件,用它,我們可以很簡(jiǎn)單的利用串口進(jìn)行通訊。在使用它之前,應(yīng)將控件加在應(yīng)用程序的對(duì)話框上。然后再用ClassWizard生成相應(yīng)的對(duì)象。現(xiàn)在我們可以使用它了。該控件有很多自己的屬性,你可以通過它的屬性窗口來(lái)設(shè)置,也可以用程序設(shè)置。我推薦用程序設(shè)置,這樣更靈活。SetCommPort:指定使用的串口。GetCommPort:得到當(dāng)前使用的串口。SetSettings:指定串口的參數(shù)。一般設(shè)為默認(rèn)參數(shù)"9600,N,8,1"。這樣方便與其他串口進(jìn)行通訊。GetSettings:取得串口參數(shù)。SetPortOpen:打開或關(guān)閉串口,當(dāng)一個(gè)程序打開串口時(shí),另外的程序?qū)o(wú)法使用該串口。GetPortOpen:取得串口狀態(tài)。GetInBufferCount:輸入緩沖區(qū)中接受到的字符數(shù)。SetInPutLen:一次讀取輸入緩沖區(qū)的字符數(shù)。設(shè)置為0時(shí),程序?qū)⒆x取緩沖區(qū)的全部字符。GetInPut:讀取輸入緩沖區(qū)。GetOutBufferCount:輸出緩沖區(qū)中待發(fā)送的字符數(shù)。SetOutPut:寫入輸出緩沖區(qū)。一般而言,使用上述函數(shù)和屬性就可以進(jìn)行串口通訊了。以下是一個(gè)范例。#defineMESSAGELENGTH100classCMyDialog:publicCDialog

{

protected:

VARIANTInBuffer;

VARIANTOutBuffer;

CMSCommm_Com;

public:

}BOOLCMyDiaLog::OnInitDialog()

{

CDialog::OnInitDialog();

m_Com.SetCommPort(1);

if(!m_Com.GetPortOpen()){

m_Com.SetSettings("57600,N,8,1");

m_Com.SetPortOpen(true);

m_Com.SetInBufferCount(0);

SetTimer(1,10,NULL);

InBuffer.bstrVal=newunsignedshort[MESSAGELENGTH];

OutBuffer.bstrVal=newunsignedshort[MESSAGELENGTH];

OutBuffer.vt=VT_BSTR;

}

returntrue;

}voidCMyDiaLog::OnTimer(UINTnIDEvent)

{

if(m_Com.GetInBufferCount()>=MESSAGELENGTH){

InBuffer=m_Com.GetInput();

//handletheInBuffer.

//FilltheOutBuffer.

m_Com.SetOutput(OutBuffer);

}

CDialog::OnTimer(nIDEvent);

}用該控件傳輸?shù)臄?shù)據(jù)是UNICODE格式。關(guān)于UNICODE和ANSI的關(guān)系和轉(zhuǎn)換請(qǐng)參看MSDN。關(guān)于該控件的其他詳細(xì)資料請(qǐng)查看MSDN關(guān)于COMMCONTROL部分。2.4.2直接用VC++訪問串口。在VC++中,串口和磁盤文件可以統(tǒng)一的方式來(lái)簡(jiǎn)單讀寫。這兩者幾乎沒有什么不同,只是在WINDOWS9X下磁盤文件只能做同步訪問,而串口只能做異步訪問。CreateFile:用指定的方式打開指定的串口。通常的方式為m_hCom=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);m_hCom為文件句柄。GENERIC_READ|GENERIC_WRITE指定可以對(duì)串口進(jìn)行讀寫操作。第三個(gè)參數(shù)0表示串口為獨(dú)占打開。OPEN_EXISTING表示當(dāng)指定串口不存在時(shí),程序?qū)⒎祷厥 ILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED則表示文件屬性。當(dāng)打開串口時(shí),必須指定FILE_FLAG_OVERLAPPED,它表示文件或設(shè)備不會(huì)維護(hù)訪問指針,則在讀寫時(shí),必須使用OVERLAPPED結(jié)構(gòu)指定訪問的文件偏移量。ReadFile:讀取串口數(shù)據(jù)。WriteFile:向串口寫數(shù)據(jù)。CloseHandle:關(guān)閉串口。COMMTIMEOUTS:COMMTIMEOUTS主要用于串口超時(shí)參數(shù)設(shè)置。COMMTIMEOUTS結(jié)構(gòu)如下:typedefstruct_COMMTIMEOUTS{

DWORDReadIntervalTimeout;

DWORDReadTotalTimeoutMultiplier;

DWORDReadTotalTimeoutConstant;

DWORDWriteTotalTimeoutMultiplier;

DWORDWriteTotalTimeoutConstant;

}COMMTIMEOUTS,*LPCOMMTIMEOUTS;ReadIntervalTimeout:兩字符之間最大的延時(shí),當(dāng)讀取串口數(shù)據(jù)時(shí),一旦兩個(gè)字符傳輸?shù)臅r(shí)間差超過該時(shí)間,讀取函數(shù)將返回現(xiàn)有的數(shù)據(jù)。設(shè)置為0表示該參數(shù)不起作用。ReadTotalTimeoutMultiplier:讀取每字符間的超時(shí)。ReadTotalTimeoutConstant:一次讀取串口數(shù)據(jù)的固定超時(shí)。所以在一次讀取串口的操作中,其超時(shí)為ReadTotalTimeoutMultiplier乘以讀取的字節(jié)數(shù)再加上ReadTotalTimeoutConstant。將ReadIntervalTimeout設(shè)置為MAXDWORD,并將ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant設(shè)置為0,表示讀取操作將立即返回存放在輸入緩沖區(qū)的字符。WriteTotalTimeoutMultiplier:寫入每字符間的超時(shí)。WriteTotalTimeoutConstant:一次寫入串口數(shù)據(jù)的固定超時(shí)。所以在一次寫入串口的操作中,其超時(shí)為WriteTotalTimeoutMultiplier乘以寫入的字節(jié)數(shù)再加上WriteTotalTimeoutConstant。SetCommTimeouts函數(shù)可以設(shè)置某設(shè)備句柄的超時(shí)參數(shù),要得到某設(shè)備句柄的超時(shí)參數(shù)可以用GetCommTimeouts函數(shù)。DCB:DCB結(jié)構(gòu)主要用于串口參數(shù)設(shè)置。該結(jié)構(gòu)太龐大,這里就不一一講述了,有興趣者可查看MSDN關(guān)于DCB的描述。其中下面兩個(gè)是比較重要的屬性。BaudRate:串口的通訊速度。一般設(shè)置為9600。ByteSize:字節(jié)位數(shù)。一般設(shè)置為8。DCB結(jié)構(gòu)可以用SetCommState函數(shù)來(lái)設(shè)置,并可以用GetCommState來(lái)得到現(xiàn)有串口的屬性。SetupComm:設(shè)置串口輸入、輸出緩沖區(qū)。OVERLAPPED:保存串口異步通訊的信息。具體結(jié)構(gòu)如下:typedefstruct_OVERLAPPED{

DWORDInternal;

DWORDInternalHigh;

DWORDOffset;

DWORDOffsetHigh;

HANDLEhEvent;

}OVERLAPPED;Internal,InternalHigh是保留給系統(tǒng)使用的,用戶不需要設(shè)置。Offset,OffsetHigh是讀寫串口的偏移量,一般設(shè)置OffsetHigh為NULL,可以支持2GB數(shù)據(jù)。hEvent讀寫事件,因?yàn)榇谑钱惒酵ㄓ?,操作可能被其他進(jìn)程堵塞,程序可以通過檢查該時(shí)間來(lái)得知是否讀寫完畢。事件將在讀寫完成后,自動(dòng)設(shè)置為有效。通過以上這些函數(shù)和結(jié)構(gòu),我們就可以通過串口進(jìn)行通訊了,現(xiàn)在我們具體看下面的實(shí)例:

BOOLCSerial::Open(intnPort,intnBaud)

{

if(m_bOpened)return(TRUE);

charszPort[15];

DCBdcb;

wsprintf(szPort,"COM%d",nPort);

m_hComDev=CreateFile(szPort,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);

if(m_hComDev==NULL)return(FALSE);

memset(&m_OverlappedRead,0,sizeof(OVERLAPPED));

memset(&m_OverlappedWrite,0,sizeof(OVERLAPPED));

COMMTIMEOUTSCommTimeOuts;

CommTimeOuts.ReadIntervalTimeout=0xFFFFFFFF;

CommTimeOuts.ReadTotalTimeoutMultiplier=0;

CommTimeOuts.ReadTotalTimeoutConstant=0;

CommTimeOuts.WriteTotalTimeoutMultiplier=0;

CommTimeOuts.WriteTotalTimeoutConstant=5000;

SetCommTimeouts(m_hComDev,&CommTimeOuts);

m_OverlappedRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

m_OverlappedWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

dcb.DCBlength=sizeof(DCB);

GetCommState(m_hComDev,&dcb);

dcb.BaudRate=nBaud;

dcb.ByteSize=8;

if(!SetCommState(m_hComDev,&dcb)||

!SetupComm(m_hComDev,10000,10000)||

m_OverlappedRead.hEvent==NULL||

m_OverlappedWrite.hEvent==NULL){

DWORDdwError=GetLastError();

if(m_OverlappedRead.hEvent!=NULL)CloseHandle(m_OverlappedRead.hEvent);

if(m_OverlappedWrite.hEvent!=NULL)CloseHandle(m_OverlappedWrite.hEvent);

CloseHandle(m_hComDev);

returnFALSE;

}

m_bOpened=TRUE;

returnm_bOpened;

}

intCSerial::InBufferCount(void)

{

if(!m_bOpened||m_hComDev==NULL)return(0);

DWORDdwErrorFlags;

COMSTATComStat;

ClearCommError(m_hIDComDev,&dwErrorFlags,&ComStat);

return(int)ComStat.cbInQue;

}

DWORDCSerial::ReadData(void*buffer,DWORDdwBytesRead)

{

if(!m_bOpened||m_hComDev==NULL)return0;

BOOLbReadStatus;

DWORDdwErrorFlags;

COMSTATComStat;

ClearCommError(m_hComDev,&dwErrorFlags,&ComStat);

if(!ComStat.cbInQue)return0;

dwBytesRead=min(dwBytesRead,(DWORD)ComStat.cbInQue);

bReadStatus=ReadFile(m_hComDev,buffer,dwBytesRead,&dwBytesRead,&m_OverlappedRead);

if(!bReadStatus){

if(GetLastError()==ERROR_IO_PENDING){

WaitForSingleObject(m_OverlappedRead.hEvent,2000);

returndwBytesRead;

}

return0;

}

returndwBytesRead;

}

DWORDCSerial::SendData(constchar*buffer,DWORDdwBytesWritten)

{

if(!m_bOpened||m_hComDev==NULL)return(0);

BOOLbWriteStat;

bWriteStat=WriteFile(m_hComDev,buffer,dwBytesWritten,&dwBytesWritten,&m_OverlappedWrite);

if(!bWriteStat){

if(GetLastError()==ERROR_IO_PENDING){

WaitForSingleObject(m_OverlappedWrite.hEvent,1000);

returndwBytesWritten;

}

return0;

}

returndwBytesWritten;

}上述函數(shù)基本實(shí)現(xiàn)串口的打開,讀寫操作。本文章略去該串口類的說明和關(guān)閉函數(shù)。讀者應(yīng)該能將這些內(nèi)容寫完。接下來(lái),你就可以在你的程序中調(diào)用該串口類了。2.5MSComm控件介紹MSComm控件通過串行端口傳輸和接收數(shù)據(jù),為應(yīng)用程序提供串行通訊功能。MSComm控件在串口編程時(shí)非常方便,程序員不必去花時(shí)間去了解較為復(fù)雜的API函數(shù),而且在VC、VB、Delphi等語(yǔ)言中均可使用。MicrosoftCommunicationsControl(以下簡(jiǎn)稱MSComm)是Microsoft公司提供的簡(jiǎn)化Windows下串行通信編程的ActiveX控件,它為應(yīng)用程序提供了通過串行接口收發(fā)數(shù)據(jù)的簡(jiǎn)便方法。具體的來(lái)說,它提供了兩種處理通信問題的方法:一是事件驅(qū)動(dòng)(Event-driven)方法,一是查詢法。2.5.1MSComm控件提供下列兩種處理通訊的方式:事件驅(qū)動(dòng)方式和查詢方式。一、事件驅(qū)動(dòng)方式事件驅(qū)動(dòng)通訊是處理串行端口交互作用的一種非常有效的方法。在許多情況下,在事件發(fā)生時(shí)需要得到通知,例如,在串口接收緩沖區(qū)中有字符,或者CarrierDetect(CD)或RequestToSend(RTS)線上一個(gè)字符到達(dá)或一個(gè)變化發(fā)生時(shí)。在這些情況下,可以利用MSComm控件的OnComm事件捕獲并處理這些通訊事件。OnComm事件還可以檢查和處理通訊錯(cuò)誤。所有通訊事件和通訊錯(cuò)誤的列表,參閱CommEvent屬性。在編程過程中,就可以在OnComm事件處理函數(shù)中加入自己的處理代碼。這種方法的優(yōu)點(diǎn)是程序響應(yīng)及時(shí),可靠性高。每個(gè)MSComm控件對(duì)應(yīng)著一個(gè)串行端口。如果應(yīng)用程序需要訪問多個(gè)串行端口,必須使用多個(gè)MSComm控件。二、查詢方式查詢方式實(shí)質(zhì)上還是事件驅(qū)動(dòng),但在有些情況下,這種方式顯得更為便捷。在程序的每個(gè)關(guān)鍵功能之后,可以通過檢查CommEvent屬性的值來(lái)查詢事件和錯(cuò)誤。如果應(yīng)用程序較小,并且是自保持的,這種方法可能是更可取的。例如,如果寫一個(gè)簡(jiǎn)單的電話撥號(hào)程序,則沒有必要對(duì)每接收一個(gè)字符都產(chǎn)生事件,因?yàn)槲ㄒ坏却邮盏淖址钦{(diào)制解調(diào)器的“確定”響應(yīng)。2.5.2MSComm控件有很多重要的屬性,但首先必須熟悉幾個(gè)屬性。CommPort設(shè)置并返回通訊端口號(hào)。Settings以字符串的形式設(shè)置并返回波特率、奇偶校驗(yàn)、數(shù)據(jù)位、停止位。PortOpen設(shè)置并返回通訊端口的狀態(tài)。也可以打開和關(guān)閉端口。Input從接收緩沖區(qū)返回和刪除字符。Output向傳輸緩沖區(qū)寫一個(gè)字符串。下面分別描述:CommPort屬性設(shè)置并返回通訊端口號(hào)。語(yǔ)法object.CommPort[value](value一整型值,說明端口號(hào)。)說明在設(shè)計(jì)時(shí),value可以設(shè)置成從1到16的任何數(shù)(缺省值為1)。但是如果用PortOpen屬性打開一個(gè)并不存在的端口時(shí),MSComm控件會(huì)產(chǎn)生錯(cuò)誤68(設(shè)備無(wú)效)。注意:必須在打開端口之前設(shè)置CommPort屬性。RThreshold屬性:在MSComm控件設(shè)置CommEvent屬性為comEvReceive并產(chǎn)生OnComm之前,設(shè)置并返回的要接收的字符數(shù)。語(yǔ)法object.Rthreshold[=value](value整型表達(dá)式,說明在產(chǎn)生OnComm事件之前要接收的字符數(shù)。)說明當(dāng)接收字符后,若Rthreshold屬性設(shè)置為0(缺省值)則不產(chǎn)生OnComm事件。例如,設(shè)置Rthreshold為1,接收緩沖區(qū)收到每一個(gè)字符都會(huì)使MSComm控件產(chǎn)生OnComm事件。CTSHolding屬性:確定是否可通過查詢ClearToSend(CTS)線的狀態(tài)發(fā)送數(shù)據(jù)。ClearToSend是調(diào)制解調(diào)器發(fā)送到相聯(lián)計(jì)算機(jī)的信號(hào),指示傳輸可以進(jìn)行。該屬性在設(shè)計(jì)時(shí)無(wú)效,在運(yùn)行時(shí)為只讀。語(yǔ)法:object.CTSHolding(Boolean)Mscomm控件的CTSHolding屬性設(shè)置值:TrueClearToSend線為高電平。FalseClearToSend線為低電平。說明:如果ClearToSend線為低電平(CTSHolding=False)并且超時(shí)時(shí),MSComm控件設(shè)置CommEvent屬性為comEventCTSTO(ClearToSendTimeout)并產(chǎn)生OnComm事件。ClearToSend線用于RTS/CTS(RequestToSend/ClearToSend)硬件握手。如果需要確定ClearToSend線的狀態(tài),CTSHolding屬性給出一種手工查詢的方法。詳細(xì)信息有關(guān)握手協(xié)議,請(qǐng)參閱Handshaking屬性。SThreshold屬性:MSComm控件設(shè)置CommEvent屬性為comEvSend并產(chǎn)生OnComm事件之前,設(shè)置并返回傳輸緩沖區(qū)中允許的最小字符數(shù)。語(yǔ)法object.SThreshold[=value]value整形表達(dá)式,代表在OnComm事件產(chǎn)生之前在傳輸緩沖區(qū)中的最小字符數(shù)。說明:若設(shè)置Sthreshold屬性為0(缺省值),數(shù)據(jù)傳輸事件不會(huì)產(chǎn)生OnComm事件。若設(shè)置Sthreshold屬性為1,當(dāng)傳輸緩沖區(qū)完全空時(shí),MSComm控件產(chǎn)生OnComm事件。如果在傳輸緩沖區(qū)中的字符數(shù)小于value,CommEvent屬性設(shè)置為comEvSend,并產(chǎn)生OnComm事件。comEvSend事件僅當(dāng)字符數(shù)與Sthreshold交叉時(shí)被激活一次。例如,如果Sthreshold等于5,僅當(dāng)在輸出隊(duì)列中字符數(shù)從5降到4時(shí),comEvSend才發(fā)生。如果在輸出隊(duì)列中從沒有比Sthreshold多的字符,comEvSend事件將絕不會(huì)發(fā)生。Handshake常數(shù)常數(shù)值描述comNone0無(wú)握手。comXonXoff1XOn/Xoff握手。comRTS2Request-to-send/clear-to-send握手。comRTSXOnXOff3Request-to-send和clear-to-send握手皆可。OnComm常數(shù)常數(shù)值描述comEvSend1發(fā)送事件。comEvReceive2接收事件。comEvCTS3clear-to-send線變化。comEvDSR4data-setready線變化。comEvCD5carrierdetect線變化。comEvRing6振鈴檢測(cè)。comEvEOF7文件結(jié)束。Error常數(shù)常數(shù)值描述comEventBreak1001接收到中斷信號(hào)comEventCTSTO1002Clear-to-send超時(shí)comEventDSRTO1003Data-setready超時(shí)comEventFrame1004幀錯(cuò)誤comEventOverrun1006端口超速comEventCDTO1007Carrierdetect超時(shí)comEventRxOver1008接收緩沖區(qū)溢出comEventRxParity1009Parity錯(cuò)誤comEventTxFull1010傳輸緩沖區(qū)滿comEventDCB1011檢索端口設(shè)備控制塊(DCB)時(shí)的意外錯(cuò)誤InputMode常數(shù)常數(shù)值描述comInputModeText0(缺?。┩ㄟ^Input屬性以文本方式取回?cái)?shù)據(jù)。comInputModeBinary1通過Input屬性以二進(jìn)制方式檢取回?cái)?shù)據(jù)。CDHolding屬性:通過查詢CarrierDetect(CD)線的狀態(tài)確定當(dāng)前是否有傳輸。CarrierDetect是從調(diào)制解調(diào)器發(fā)送到相聯(lián)計(jì)算機(jī)的一個(gè)信號(hào),指示調(diào)制解調(diào)器正在聯(lián)機(jī)。該屬性在設(shè)計(jì)時(shí)無(wú)效,在運(yùn)行時(shí)為只讀。語(yǔ)法object.CDHolding設(shè)置值:CDHolding屬性的設(shè)置值為:設(shè)置描述TrueCarrierDetect線為高電平FalseCarrierDetect線為低電平說明:注意當(dāng)CarrierDetect線為高電平(CDHolding=True)且超時(shí)時(shí),MSComm控件設(shè)置CommEvent屬性為comEventCDTO(CarrierDetect超時(shí)錯(cuò)誤),并產(chǎn)生OnComm事件。注意在主機(jī)應(yīng)用程序中捕獲一個(gè)丟失的傳輸是特別重要的,例如一個(gè)公告板,因?yàn)楹艚姓呖梢噪S時(shí)掛起(放棄傳輸)。CarrierDetect也被稱為ReceiveLineSignalDetect(RLSD)。數(shù)據(jù)類型BooleanDSRHolding屬性:確定DataSetReady(DSR)線的狀態(tài)。DataSetReady信號(hào)由調(diào)制解調(diào)器發(fā)送到相連計(jì)算機(jī),指示作好操作準(zhǔn)備。該屬性在設(shè)計(jì)時(shí)無(wú)效,在運(yùn)行時(shí)為只讀。語(yǔ)法:object.DSRHoldingobject所在處表示對(duì)象表達(dá)式,其值是“應(yīng)用于”列表中的對(duì)象。DSRHolding屬性返回以下值:值描述TrueDataSetReady線高FalseDataSetReady線低說明:當(dāng)DataSetReady線為高電平(DSRHolding=True)且超時(shí)時(shí),MSComm控件設(shè)置CommEvent屬性為comEventDSRTO(數(shù)據(jù)準(zhǔn)備超時(shí))并產(chǎn)生OnComm事件。當(dāng)為DataTerminalEquipment(DTE)機(jī)器寫DataSetReady/DataTerminalReady握手例程時(shí)該屬性是十分有用的。數(shù)據(jù)類型:BooleanSettings屬性:設(shè)置并返回波特率、奇偶校驗(yàn)、數(shù)據(jù)位、停止位參數(shù)。語(yǔ)法:object.Settings[=value]說明:當(dāng)端口打開時(shí),如果value非法,則MSComm控件產(chǎn)生錯(cuò)誤380(非法屬性值)。Value由四個(gè)設(shè)置值組成,有如下的格式:"BBBB,P,D,S"BBBB為波特率,P為奇偶校驗(yàn),D為數(shù)據(jù)位數(shù),S為停止位數(shù)。value的缺省值是:"9600,N,8,1"InputLen屬性:設(shè)置并返回Input屬性從接收緩沖區(qū)讀取的字符數(shù)。語(yǔ)法object.InputLen[=value]InputLen屬性語(yǔ)法包括下列部分:value整型表達(dá)式,說明Input屬性從接收緩沖區(qū)中讀取的字符數(shù)。說明:InputLen屬性的缺省值是0。設(shè)置InputLen為0時(shí),使用Input將使MSComm控件讀取接收緩沖區(qū)中全部。

第3章系統(tǒng)設(shè)計(jì)系統(tǒng)設(shè)計(jì)的目的是確定系統(tǒng)如何完成預(yù)定的任務(wù),也就是確定系統(tǒng)的物理配置方案,并且進(jìn)而確定組成系統(tǒng)的每個(gè)程序的結(jié)構(gòu)。首先需要從數(shù)據(jù)流圖出發(fā),設(shè)想完成系統(tǒng)功能的若干種合理的物理方案,分析員應(yīng)該仔細(xì)比較這些方案,并且和用戶共同選定一個(gè)最佳方案,然后,進(jìn)行軟件結(jié)構(gòu)設(shè)計(jì),確定軟件由哪些模塊組成以及這些模塊之間的動(dòng)態(tài)調(diào)用關(guān)系。進(jìn)行軟件結(jié)構(gòu)設(shè)計(jì)時(shí)應(yīng)該遵循的最主要的原理是模塊獨(dú)立原理,也就是說:軟件應(yīng)該由一組完成相對(duì)獨(dú)立的子功能模塊組成,這些模塊之間的接口關(guān)系應(yīng)盡量簡(jiǎn)單。自頂向下逐步求精是進(jìn)行軟件結(jié)構(gòu)設(shè)計(jì)的常用途經(jīng),但是,如果已經(jīng)有了詳細(xì)的數(shù)據(jù)流圖,也可以使用面向數(shù)據(jù)流的設(shè)計(jì)方法,用形式化的方法由數(shù)據(jù)流圖映射出軟件結(jié)構(gòu)。在進(jìn)行詳細(xì)的過程設(shè)計(jì)和編寫程序之前,首先進(jìn)行結(jié)構(gòu)設(shè)計(jì),其好處在于可以在軟件開發(fā)的早期站在全局高度對(duì)軟件結(jié)構(gòu)進(jìn)行優(yōu)化,在這個(gè)時(shí)期進(jìn)行優(yōu)化付出的代價(jià)不高,卻可以使軟件質(zhì)量得到重大改進(jìn)。3.1系統(tǒng)功能設(shè)計(jì)我們把系統(tǒng)分為了三大模塊:串口連接管理模塊,數(shù)據(jù)收發(fā)管理模塊和信息顯示管理模塊。下面我將對(duì)每個(gè)模塊的總體設(shè)計(jì)作簡(jiǎn)要說明。串口通信程序模塊構(gòu)成:1)串口連接管理模塊該模塊可以實(shí)現(xiàn)對(duì)串口連接的管理,可以打開和關(guān)閉串口。選擇好串口號(hào)、波特率、校驗(yàn)位、數(shù)據(jù)位、停止位等后,可以打開串口。通信完畢后可以關(guān)閉串口。用在Windows下進(jìn)行串口通信的編程流程下圖所示。打開串口是確定串口號(hào)與串口的打開方式;初始化串口用于配置通訊的波特率、每字節(jié)位數(shù)、校驗(yàn)位、停止位和讀寫超時(shí)等;讀寫串口用于向串口進(jìn)行發(fā)送數(shù)據(jù)和從串口接收數(shù)據(jù);關(guān)閉串口用于將串口關(guān)閉并釋放串口資源(Windows系統(tǒng)下串口是系統(tǒng)資源)。2)數(shù)據(jù)收發(fā)管理模塊該模塊可以實(shí)現(xiàn)對(duì)數(shù)據(jù)的發(fā)送和接受管理。我們采用了MSComm控件進(jìn)行串口通信。MSComm控件通過串行端口傳輸和接收數(shù)據(jù),為應(yīng)用程序提供串行通訊功能。MSComm控件在串口編程時(shí)非常方便,程序員不必去花時(shí)間去了解較為復(fù)雜的API函數(shù),而且在VC、VB、Delphi等語(yǔ)言中均可使用。MicrosoftCommunicationsControl(以下簡(jiǎn)稱MSComm)是Microsoft公司提供的簡(jiǎn)化Windows下串行通信編程的ActiveX控件,它為應(yīng)用程序提供了通過串行接口收發(fā)數(shù)據(jù)的簡(jiǎn)便方法。3)信息顯示管理模塊該模塊主要實(shí)現(xiàn)對(duì)通信數(shù)據(jù)的顯示。無(wú)論是接受的數(shù)據(jù)和發(fā)送的數(shù)據(jù),按照一定的格式進(jìn)行顯示。3.2算法分析//打開或關(guān)閉串口voidCSCommChatView::OnButtonOpen(){ UpdateData(true); //如果串口是打開的,則關(guān)閉 if(m_bOpen==true) { //關(guān)閉串口 m_ctrlComm.SetPortOpen(FALSE); //設(shè)置按鈕為打開串口 CButton*pButton=(CButton*)this->GetDlgItem(IDC_BUTTON_OPEN); pButton->SetWindowText("打開串口"); //設(shè)置各下拉框?yàn)榛? ((CComboBox*)this->GetDlgItem(IDC_COMBO_PORT))->EnableWindow(true); ((CComboBox*)this->GetDlgItem(IDC_COMBO_BAUD))->EnableWindow(true); ((CComboBox*)this->GetDlgItem(IDC_COMBO_PARITY))->EnableWindow(true); ((CComboBox*)this->GetDlgItem(IDC_COMBO_DATA))->EnableWindow(true); ((CComboBox*)this->GetDlgItem(IDC_COMBO_STOP))->EnableWindow(true); m_bOpen=false; } else { //如果串口打開了,關(guān)閉它 if(m_ctrlComm.GetPortOpen()) m_ctrlComm.SetPortOpen(FALSE); //設(shè)置串口號(hào) m_ctrlComm.SetCommPort(m_nPort+1); //打開串口 if(!m_ctrlComm.GetPortOpen()) m_ctrlComm.SetPortOpen(TRUE); else { AfxMessageBox("打開串口失敗,沒有發(fā)現(xiàn)此串口或占用!"); return; } //指定串口的參數(shù)(波特率,校驗(yàn)位,數(shù)據(jù)位,停止位)。一般設(shè)為默認(rèn)參數(shù)"9600,N,8,1" intBAUD[]={300,600,1200,2400,4800,9600,19200,38400,43000,56000,57600,115200}; charPARITY[]={'n','o','e'}; intDATA[]={8,7,6}; intSTOP[]={1,2}; charset[100]; sprintf(set,"%d,%s,%d,%d",BAUD[m_nBaud],"n",DATA[m_nData],STOP[m_nStop]); m_ctrlComm.SetSettings(set); //參數(shù)1表示每當(dāng)串口接收緩沖區(qū)中有多于或等于1個(gè)字符時(shí)將引發(fā)一個(gè)接收數(shù)據(jù)的OnComm事件 m_ctrlComm.SetRThreshold(1); //調(diào)用此設(shè)置以解決VARIANT轉(zhuǎn)換為COleSafeArray時(shí)產(chǎn)生的錯(cuò)誤 m_ctrlComm.SetInputMode(1); //設(shè)置當(dāng)前接收區(qū)數(shù)據(jù)長(zhǎng)度為0 m_ctrlComm.SetInputLen(0); //先預(yù)讀緩沖區(qū)以清除殘留數(shù)據(jù) m_ctrlComm.GetInput(); //設(shè)置按鈕為關(guān)閉串口 CButton*pButton=(CButton*)this->GetDlgItem(IDC_BUTTON_OPEN); pButton->SetWindowText("關(guān)閉串口"); //設(shè)置各下拉框?yàn)榛? ((CComboBox*)this->GetDlgItem(IDC_COMBO_PORT))->EnableWindow(false); ((CComboBox*)this->GetDlgItem(IDC_COMBO_BAUD))->EnableWindow(false); ((CComboBox*)this->GetDlgItem(IDC_COMBO_PARITY))->EnableWindow(false); ((CComboBox*)this->GetDlgItem(IDC_COMBO_DATA))->EnableWindow(false); ((CComboBox*)this->GetDlgItem(IDC_COMBO_STOP))->EnableWindow(false); m_bOpen=true; }}//發(fā)送數(shù)據(jù)voidCSCommChatView::OnButtonSend(){ //讀取編輯框內(nèi)容 UpdateData(TRUE); //發(fā)送數(shù)據(jù) m_ctrlComm.SetOutput(COleVariant(m_strSend)); SendString(m_strSend); //設(shè)置發(fā)送數(shù)據(jù)框?yàn)楫?dāng)前控件 CEdit*pEdit=(CEdit*)GetDlgItem(IDC_EDIT_SEND); pEdit->SetActiveWindow();}BEGIN_EVENTSINK_MAP(CSCommChatView,CFormView)//{{AFX_EVENTSINK_MAP(CSCommChatView) ON_EVENT(CSCommChatView,IDC_MSCOMM,1/*OnComm*/,OnCommMscomm,VTS_NONE) //}}AFX_EVENTSINK_MAPEND_EVENTSINK_MAP()//接受數(shù)據(jù)voidCSCommChatView::OnCommMscomm(){ //事件值為2表示接收緩沖區(qū)內(nèi)有字符 if(m_ctrlComm.GetCommEvent()==2) { //讀緩沖區(qū) VARIANTvariant_inp; variant_inp=m_ctrlComm.GetInput(); //VARIANT型變量轉(zhuǎn)換為ColeSafeArray型變量 COleSafeArraysafearray_inp; safearray_inp=variant_inp; //得到有效數(shù)據(jù)長(zhǎng)度 intlen=safearray_inp.GetOneDimSize(); //轉(zhuǎn)換為BYTE型數(shù)組 BYTErxdata[2048];//設(shè)置BYTE數(shù)組An8-bitintegerthatisnotsigned. for(LONGk=0;k<len;k++) safearray_inp.GetElement(&k,rxdata+k); //設(shè)置字符串結(jié)束 rxdata[k]='\0'; CStringstrtemp=(char*)rxdata; RecvString(strtemp); }}//顯示發(fā)送的信息voidCSCommChatView::SendString(CStringstr){ //顯示發(fā)送信息 m_strRecv+="己方說:"; m_strRecv+=str; m_strRecv+="\r\n"; //更新編輯框內(nèi)容 UpdateData(false);}//顯示接受的信息voidCSCommChatView::

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論