1、打開(kāi)串口
win32系統(tǒng)把文件的概念進(jìn)行了擴(kuò)展。無(wú)論是文件、通信設(shè)備、命名管道、郵件槽、磁盤(pán)、還是控制臺(tái),都是用api函數(shù)createfile來(lái)打開(kāi)或創(chuàng)建的。該函數(shù)的原型為:
handlecreatefile(lpctstrlpfilename,
dworddwsharemode,
lpsecurity_attributeslpsecurityattributes,
dworddwcreationdistribution,
dworddwflagsandattributes,
handlehtemplatefile);
各個(gè)參數(shù)說(shuō)明如下:
lpfilename:將要打開(kāi)的串口邏輯名,如“com1”;
dwdesiredaccess:指定串口訪問(wèn)的類(lèi)型,可以是讀取、寫(xiě)入或二者并列;
dwsharemode:指定共享屬性,由于串口不能共享,該參數(shù)必須置為0;
lpsecurityattributes:引用安全性屬性結(jié)構(gòu),缺省值為null;
dwcreationdistribution:創(chuàng)建標(biāo)志,對(duì)串口操作該參數(shù)必須置為open_existing;
dwflagsandattributes:屬性描述,用于指定該串口是否進(jìn)行異步操作,該值為file_flag_overlapped,表示使用異步的i/o;該值為0,表示同步i/o操作;
htemplatefile:對(duì)串口而言該參數(shù)必須置為null;
2、配置串口
在打開(kāi)通訊設(shè)備句柄后,常常需要對(duì)串口進(jìn)行一些初始化配置工作。這需要通過(guò)一個(gè)dcb結(jié)構(gòu)來(lái)進(jìn)行。dcb結(jié)構(gòu)包含了諸如波特率、數(shù)據(jù)位數(shù)、奇偶校驗(yàn)和停止位數(shù)等信息。在查詢或配置串口的屬性時(shí),都要用dcb結(jié)構(gòu)來(lái)作為緩沖區(qū)。在打開(kāi)串口后,可以調(diào)用getcommstate函數(shù)來(lái)獲取串口的默認(rèn)配置,該函數(shù)獲取一個(gè)dcb結(jié)構(gòu)體,只要在該結(jié)構(gòu)內(nèi)對(duì)應(yīng)該先修改dcb結(jié)構(gòu),然后再調(diào)用setcommstate函數(shù)以修改后的dcb結(jié)構(gòu)設(shè)置串口。dcb主要有以下幾個(gè)重要的成員:bytebytesize;//通信字節(jié)位數(shù)byteparity;//指定奇偶校驗(yàn)方法。此成員可以有下列值://evenparity偶校驗(yàn)noparity無(wú)校驗(yàn)//markparity標(biāo)記校驗(yàn)oddparity奇校驗(yàn)bytestopbits;//指定停止位的位數(shù)。此成員可以有下列值://onestopbit1位停止位//twostopbits2位停止位//one5stopbits1.5位停止位
除了使用bcd設(shè)置串口的一些基本參數(shù)外,一般還需要設(shè)置串口收發(fā)數(shù)據(jù)緩沖區(qū)的大小和超時(shí),超時(shí)的作用是在指定的時(shí)間內(nèi)沒(méi)有讀入或發(fā)送指定數(shù)量的字符,讀寫(xiě)操作仍然會(huì)結(jié)束。windows用i/o緩沖區(qū)來(lái)暫存串口輸入和輸出的數(shù)據(jù),如果通信的速率較高,則應(yīng)該設(shè)置較大的緩沖區(qū)。我們可以使用api函數(shù)setupcomm設(shè)置串口的輸入和輸出緩沖區(qū)的大小,其原型如下:boolsetupcomm(handlehfile,//串口句柄dworddwinqueue,//輸入緩沖區(qū)的大?。ㄗ止?jié)數(shù))dworddwoutqueue);//輸出緩沖區(qū)的大小(字節(jié)數(shù))
關(guān)于讀寫(xiě)串口的超時(shí)設(shè)置,windows給我們提供一個(gè)專(zhuān)門(mén)的結(jié)構(gòu)體commtimeouts,其定義如下:typedefstruct_commtimeouts{dwordreadintervaltimeout;//讀間隔超時(shí)dwordreadtotaltimeoutmultiplier;//讀時(shí)間系數(shù)dwordreadtotaltimeoutconstant;//讀時(shí)間常量dwordwritetotaltimeoutmultiplier;//寫(xiě)時(shí)間系數(shù)dwordwritetotaltimeoutconstant;//寫(xiě)時(shí)間常量}commtimeouts,*lpcommtimeouts;
commtimeouts結(jié)構(gòu)的成員都以毫秒為單位。總超時(shí)的計(jì)算公式是:
總超時(shí)=時(shí)間系數(shù)×要求讀/寫(xiě)的字符數(shù)+時(shí)間常量
例如,要讀入10個(gè)字符,那么讀操作的總超時(shí)的計(jì)算公式為:
讀總超時(shí)=readtotaltimeoutmultiplier×10+readtotaltimeoutconstant
通過(guò)該結(jié)構(gòu)體windowsapi為我們提供兩個(gè)函數(shù):getcommtimeouts和setcommtimeouts,前者獲取當(dāng)前的超時(shí)設(shè)置,后者使用修改后的commtimeouts設(shè)置超時(shí),與設(shè)置串口闡述類(lèi)似。
在讀寫(xiě)串口之前,還要用purgecomm(…)函數(shù)清空緩沖區(qū),該函數(shù)原型:
boolpurgecomm(
handlehfile,//串口句柄
dworddwflags);//需要完成的操作
參數(shù)dwflags指定要完成的操作,可以是下列值的組合:
purge_txabort中斷所有寫(xiě)操作并立即返回,即使寫(xiě)操作還沒(méi)有完成。
purge_rxabort中斷所有讀操作并立即返回,即使讀操作還沒(méi)有完成。
purge_txclear清除輸出緩沖區(qū)
purge_rxclear清除輸入緩沖區(qū)
3、讀寫(xiě)串口
讀寫(xiě)串口使用readfile和writefile兩個(gè)函數(shù),其原型如下:boolreadfile(handlehfile,//串口的句柄lpvoidlpbuffer,//保存讀入數(shù)據(jù)的指針,dwordnnumberofbytestoread,//要讀入的數(shù)據(jù)的字節(jié)數(shù)lpdwordlpnumberofbytesread,//實(shí)際讀入的字節(jié)數(shù)lpoverlappedlpoverlapped);//overlapped,同步為null
boolwritefile(
handlehfile,//串口的句柄
lpcvoidlpbuffer,//要寫(xiě)入數(shù)據(jù)的地址
dwordnnumberofbytestowrite,//要寫(xiě)入數(shù)據(jù)的字節(jié)數(shù)
lpdwordlpnumberofbyteswritten,//實(shí)際寫(xiě)入的字節(jié)數(shù)
lpoverlappedlpoverlapped);//overlapped,同步為null在進(jìn)行同步操作時(shí),讀寫(xiě)函數(shù)要等到執(zhí)行完才返回,而在異步操作時(shí)函數(shù)立即返回,但不保證讀寫(xiě)操作完成,這時(shí)候就需要使用overlapped結(jié)構(gòu)進(jìn)行異步控制,該結(jié)構(gòu)體有一個(gè)重要的成員hevent,該成員是windows事件對(duì)象的句柄在控制線程同步及異步操作時(shí)常用到,如果是異步操作,我們可以使用createevent(…)創(chuàng)建事件對(duì)象并將返回值賦給hevent,然后使用waitforsingleobject或getoverlappedresult等待讀寫(xiě)操作完成,進(jìn)而達(dá)到控制異步操作的目的。3.4關(guān)閉串口在不使用串口的時(shí)候應(yīng)該將其關(guān)閉,以釋放windows的資源供其他程序使用,關(guān)閉串口只需調(diào)用closehandle(hcomm/*串口句柄*/)即可。4串行通信在世紀(jì)星組態(tài)軟件中的應(yīng)用作為通用的組態(tài)軟件,世紀(jì)星要與其他plc、智能儀表等設(shè)備進(jìn)行通信,串行通信是主要的方式之一,基于前面所述使用api進(jìn)行串行通信開(kāi)發(fā)的優(yōu)點(diǎn),并考慮程序開(kāi)發(fā)的便捷和可重用等,在世紀(jì)星中,我們將串行通信api進(jìn)行封裝,以類(lèi)的方式對(duì)串口進(jìn)行操作,其中打開(kāi)串口及配置串口參數(shù)的操作我們通過(guò)可視化窗口進(jìn)行設(shè)定,然后在封裝類(lèi)中實(shí)現(xiàn),相關(guān)的操作處理讀寫(xiě)數(shù)據(jù)外基本都已實(shí)現(xiàn),因?yàn)椴煌脑O(shè)備有不同的協(xié)議,因而讀寫(xiě)串口的操作在驅(qū)動(dòng)程序中完成,這樣我們的開(kāi)發(fā)人員就不必關(guān)注太多其他的相關(guān)操作,只需根據(jù)實(shí)際設(shè)備重寫(xiě)讀寫(xiě)串口的成員函數(shù)即可。5結(jié)論windows是當(dāng)前應(yīng)用程序開(kāi)發(fā)的主流平臺(tái),vc++6.0是該平臺(tái)強(qiáng)大的開(kāi)發(fā)工具,使用windowsapi開(kāi)發(fā)串口通信的程序可是使我們更加清晰的了解串口通信的機(jī)制,并且開(kāi)發(fā)人員可以根據(jù)需要使用api進(jìn)行靈活的程序設(shè)計(jì),在scada中串行通信是必不可少的技術(shù),所以掌握串行通信的開(kāi)發(fā)方法具有現(xiàn)實(shí)意義。
評(píng)論
查看更多