英創(chuàng)公司的ARM9工控主板產(chǎn)品均預(yù)裝了Windows CE5.0操作系統(tǒng),支持包括EVC、C#、VB、LabView等多種開(kāi)發(fā)工具。作為工業(yè)控制領(lǐng)域的嵌入模塊,客戶的應(yīng)用程序往往對(duì)系統(tǒng)的底層調(diào)用較多,相對(duì)于其它語(yǔ)言,C++具有強(qiáng)大的硬件控制能力和很高執(zhí)行效率,因此我們提供的示例程序和軟件方面的技術(shù)支持均集中在C++方面。而C#、.net VB等在圖型界面開(kāi)發(fā)、數(shù)據(jù)庫(kù)方面的應(yīng)用和易用性方面更具優(yōu)勢(shì),我們很多客戶也選用他們作為開(kāi)發(fā)工具。為了結(jié)合各語(yǔ)言的優(yōu)勢(shì),為了對(duì)客戶提供更好的支持,我們將與主板密切相關(guān)的一些底層功能模塊封裝成COM組件,用戶可以使用自己喜歡的語(yǔ)言來(lái)調(diào)用COM組件,不必關(guān)心低層調(diào)用的細(xì)節(jié),而COM組件本身則采用C++來(lái)編寫(xiě)。本文將介紹基于英創(chuàng)工控主板串口應(yīng)用的COM組件和組件調(diào)用方法。
1、創(chuàng)建串口應(yīng)用COM組件
串口通訊在工業(yè)控制場(chǎng)合應(yīng)用十分廣泛,當(dāng)串口作為RS485通信應(yīng)用時(shí),很多場(chǎng)合下,需要通過(guò)硬件RTS信號(hào)來(lái)控制數(shù)據(jù)收發(fā)的方向,以提高抗干擾能力。在C#這一類(lèi)的高級(jí)語(yǔ)言中,盡管也包括了串口控件,但缺乏對(duì)RTS硬件的操作,因此在RS485應(yīng)用中受到一定的限制。為了彌補(bǔ)這一缺陷,在我們所設(shè)計(jì)的串口應(yīng)用COM組件中,通過(guò)對(duì)串口DCB結(jié)構(gòu)參數(shù)的設(shè)置,并結(jié)合英創(chuàng)ARM9主板低層的串口驅(qū)動(dòng)程序,實(shí)現(xiàn)對(duì)RTS信號(hào)的完整控制。本串口組件采用C++編寫(xiě),在組件內(nèi)部對(duì)RTS進(jìn)行設(shè)置,而上層的開(kāi)發(fā)工具,如C#等,可通過(guò)向組件接口函數(shù)傳遞參數(shù)來(lái)控制RTS信號(hào),從而最終實(shí)現(xiàn)RS485的半雙工通訊。
本串口COM組件提供四個(gè)接口方法函數(shù):打開(kāi)串口,關(guān)閉串口,向串口寫(xiě)數(shù)據(jù),讀串口數(shù)據(jù)。客戶方調(diào)用COM組件打開(kāi)串口后,COM組件服務(wù)器便在組件內(nèi)部創(chuàng)建一數(shù)據(jù)接收線程,接收線程里通過(guò)WaitCommEvent來(lái)等待串口事件發(fā)生,當(dāng)串口收到數(shù)據(jù)后,將數(shù)據(jù)放入指定的接收數(shù)據(jù)緩存中,客戶方可調(diào)用讀串口數(shù)據(jù)方法函數(shù)將緩存中的數(shù)據(jù)讀出。在實(shí)際應(yīng)用中,客戶可在接收線程中加入自己特定的協(xié)議轉(zhuǎn)換代碼,使得通過(guò)組件讀取的數(shù)據(jù)為一個(gè)完整應(yīng)用報(bào)文。
為了跨語(yǔ)言調(diào)用組件,接口方法函數(shù)參數(shù)數(shù)據(jù)均采用VARIANT數(shù)據(jù)類(lèi)型,這樣ASP、vbscript等可方便的進(jìn)行組件調(diào)用,從而輕松實(shí)現(xiàn)通過(guò)網(wǎng)頁(yè)對(duì)串口進(jìn)行操作。
COM組件的創(chuàng)建過(guò)程請(qǐng)參考本網(wǎng)站相關(guān)文章或參考相應(yīng)書(shū)籍。這里不再贅述。
2、串口應(yīng)用組件接口方法函數(shù)
為了跨語(yǔ)言調(diào)用組件,組件接口方法函數(shù)參數(shù)數(shù)據(jù)均采用VARIANT數(shù)據(jù)類(lèi)型。
(1)OpenPort( VARIANT portNo, VARIANT baud, VARIANT parity, VARIANT dataBits, VARIANT stopBits, VARIANT rtsCtrl, VARIANT* pbool)
功能描述:打開(kāi)指定串口。
輸入?yún)?shù):
VARIANT portNo 要打開(kāi)的串口號(hào)
VARIANT baud 設(shè)置波特率
VARIANT parity 設(shè)置奇偶較驗(yàn)
VARIANT dataBits 設(shè)置數(shù)據(jù)位
VARIANT stopBits 設(shè)置停止位
VARIANT rtsCtrl RTS設(shè)置
輸出參數(shù):
VARIANT* pbool 串口打開(kāi)成功失敗標(biāo)志
(2)WritePort(VARIANT *var_inp, VARIANT *retLen)
功能描述:向串口寫(xiě)數(shù)據(jù)
輸入?yún)?shù):
VARIANT *var_inp 發(fā)送數(shù)據(jù)緩存
輸出參數(shù):
VARIANT *retLen 發(fā)送數(shù)據(jù)個(gè)數(shù)
(3)ReadPort(VARIANT *rxData)
功能描述:讀取串口數(shù)據(jù)
輸出參數(shù):
VARIANT *rxData 接收數(shù)據(jù)緩存
(4)ClosePort( )
功能描述:關(guān)閉串口
3、串口組件調(diào)用
下面是在EVC中調(diào)用串口組件接口函數(shù)的一些程序片段,主要說(shuō)明在調(diào)用接口方法時(shí),VARIANT參數(shù)的用法。
// 從Program ID得到Class ID
hr = CLSIDFromProgID( OLESTR( ‘ComSerial.CoSerial’ ), &clsid );
if( FAILED( hr ) )
{
return -1;
}
// 從Class ID得到ICoSerial接口指針
hr = CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, __uuidof( ICoSerial ),
( void** )&pICoSerial );
if( FAILED( hr ))
{
return -1;
}
//打開(kāi)串口
CComVariant portNo( 3 ); // 打開(kāi)串口3
CComVariant baud( 9600 ); // 波特率:9600
CComVariant parity( ‘n’ ); // 無(wú)校驗(yàn)位
CComVariant dataBits( 8 ); // 8位數(shù)據(jù)
CComVariant stopBits( 1 ); // 1位停止位
CComVariant rtsCtrl(RTS_CONTROL_TOGGLE); // RTS設(shè)置
CComVariant pbool( FALSE ); // 串口打開(kāi)成功標(biāo)志
pbool = pICoSerial-》OpenPort( portNo, baud, parity, dataBits, stopBits, rtsCtrl );
// 向串口發(fā)送數(shù)據(jù)
char strBuf[100];
strcpy( strBuf, ‘1234567890!’ );
long i=0, m=0;
m = strlen( strBuf );
SAFEARRAY FAR* pSafeArray;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = m;
pSafeArray = SafeArrayCreate( VT_VARIANT, 1, rgsabound );
VARIANT var;
for( i; i 《 m; i++)
{
var.vt = VT_UI1;
var.bVal = strBuf[i];
SafeArrayPutElement( pSafeArray, &i, &var );
}
VARIANT tarray,retLen;
tarray.parray = pSafeArray;
retLen = pICoSerial-》WritePort( &tarray );
// 接收數(shù)據(jù)
VARIANT vinput, var;
BYTE rxBuf[1500];
vinput = pICoSerial-》ReadPort( );
SafeArrayGetUBound( vinput.parray, 1, &lUbound );
SafeArrayGetLBound( vinput.parray, 1, &lLbound );
// m:串口接收到的數(shù)據(jù)個(gè)數(shù)
m = lUbound - lLbound+1;
// m=0表示串口沒(méi)有收到數(shù)據(jù)
if( 0 == m )
return;
for( i=0; i 《 m; i++)
{
Safe=ArrayGetElement( vinput.parray, &i, &var );
rxBuf[i] = (BYTE)var.bVal;
}
在實(shí)際的應(yīng)用中,通訊各方必須遵循統(tǒng)一的通訊規(guī)約。在發(fā)送數(shù)據(jù)前通常需要將數(shù)據(jù)按相應(yīng)的協(xié)議打包,添加較驗(yàn)信息等,收到數(shù)據(jù)后,要進(jìn)行幀完整性判斷、數(shù)據(jù)解包、數(shù)據(jù)較驗(yàn)、協(xié)議轉(zhuǎn)換等工作?,F(xiàn)在可以將這些與協(xié)議密切相關(guān)的處理放在COM組件內(nèi)部,客戶方在使用串口時(shí)僅需要對(duì)客戶感興趣的數(shù)據(jù)進(jìn)行處理,而協(xié)議轉(zhuǎn)換等工作交由COM組件完成。這樣程序具有更好結(jié)構(gòu),維護(hù)也更加方便。
-
WINDOWS
+關(guān)注
關(guān)注
3文章
3545瀏覽量
88694 -
嵌入式主板
+關(guān)注
關(guān)注
7文章
6085瀏覽量
35336
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論