while(true)
刀等待串口2中斷
ev_group=sc_ fpend(group_ id,0,4,0,&erro);
刀中斷到來(lái),清中斷同步標(biāo)志
ev_group=sc_ fclear(gruop_ id,4,&err);
read_ CommData();//處理并讀取數(shù)據(jù)
刀處理各種指令,并設(shè)置各相關(guān)標(biāo)志
process_ Comm (BYTE *Buff,BYTE *cPtr);
}
4.2上位機(jī)通信控件的實(shí)現(xiàn)
為了便于用戶使用,把上位機(jī)的通信功能封裝到ActiveX控件中。選擇VC++6進(jìn)行通信控件的開發(fā),串口操作使用API函數(shù)來(lái)實(shí)現(xiàn)?丶胁捎昧硕嗑程技術(shù)。為監(jiān)控串口任務(wù)創(chuàng)建了一個(gè)工作線程,以免它堵塞主線程,提高了系統(tǒng)的響應(yīng)性。通信控件采用了異步v0方式,以提高發(fā)送、接收和處理數(shù)據(jù)的效率。異步v0操作建立后會(huì)立即返回,即使操作還未完成。這樣把費(fèi)時(shí)的v0操作放在后臺(tái)進(jìn)行,線程就可以干別的事情,極大地提高了程序的運(yùn)行效率。在串口通信中,有幾種讀取串口數(shù)據(jù)的方式,其中事件驅(qū)動(dòng)是最有效率的方式。在監(jiān)視串口的輔助線程中,當(dāng)有數(shù)據(jù)到達(dá)時(shí)串口是,串口事件觸發(fā),控件開始讀取串口輸入緩沖區(qū)的數(shù)據(jù)。如果沒(méi)有數(shù)據(jù)到達(dá),那么使用WaitForMultipleObjects 0''數(shù)堵塞監(jiān)測(cè)線程,把資源讓給其它線程。在使用線程堵塞技術(shù)之后,監(jiān)視串口線程占用的系統(tǒng)資源大大減少,同時(shí)提高了指令的發(fā)送效率。串口讀寫和監(jiān)控是通信的最主要部分,采用了異步v0操作,使得程序復(fù)雜化。異步v0操作分兩部分:一是創(chuàng)建該v0操作,然后返回;二是探測(cè)操作的完成。下面是讀串口的部分程序清單:
void CCommCtrl::ReadChar(COMSTAT comstat)
{
while (comstat.cbInQue>0)f
C1earCommError(mJWomm,&dwError,&comstat);
if(!ReadFile(hcomm,&RXBuf,l,&dwRead,&m_ ov))
f //ReadFile返回FALSE,判斷是出錯(cuò)還是沒(méi)完成
if(GetLastError()==ERROR IO_PENDING) f
//沒(méi)完成,需要等待
if(!GetOverlappedResult(hComm,&m- ov,
&dwRead,TRUE)) //等待讀操作完成
{…}刀完成讀操作,但出錯(cuò)
else //正確完成讀操作
{…}//處理接收的字符
else(…}/贖操作出錯(cuò)
else //讀操作在函數(shù)返回前已經(jīng)完成
{…}刀處理接收的字符
}
return; //沒(méi)有字符了,返回
}
寫串口程序和讀串口類似。監(jiān)視線程的部分代碼如下:
DINT CommWatch(LPVOID pParam)
{刀清緩存
PurgeComm(hcom,PURGE_ RXCLEAR I PURGE一XCLEAR I
PURGE_ RXABORTIPURGE一XABORT);
for(;;) f
bResult2=WaitCommEvent(hcom,&dwEvtMask,&m一 ov);
刀等待串口事件的發(fā)生
if(!bResult2)[//事件WaitCommEvent返回假
switch (dw=GetLastError(川
case ERROR-10-PENDING://異步I/O操作(WaitCommEvent)/
/進(jìn)行中,正常情況
{break;}
default:[ // I/O操作出現(xiàn)錯(cuò)誤
ProcessErrorMessage("WaitCommEvent()");
break;}}}
else{//事件WaitCommEven嶇回真,操作完成
bResult2=C1earCommError(hcom,&dw, &commstat);
if (commstat.cbInQue==0)
continue;}
刀堵塞線程,等待事件組發(fā)生。事件組包括:關(guān)閉線程事件、
刀讀事件、寫事件
Event=WaitForMultipleObjects(3, m- hEventArray, FALSE,
INFINITE);
switch (Event){//判斷是哪個(gè)事件發(fā)生
case 0:f//關(guān)閉事件
mJbThreadAlive= FALSE;
AfxEndThread(100);//關(guān)閉線程
break;)
case 1:f//字符到達(dá),讀字符
bRead=TRUE;
bResult=TRUE;
GetCommMask(hcom, &CommEvent);
if(CommEvent&EV_ RXCHAR)(
刀通知控件句柄讀取字符
::SendMessage(CommWnd,WM_ COMM_ READ,0,0);)
break;)
case 2:{//寫事件
//通知控件句柄寫串口
::SendMessage(CommWnd,WM_ COMM_ WRITE,0,0);)}}
刀主循環(huán)結(jié)束
return 0;}
5結(jié)束語(yǔ)
我們根據(jù)激光加工機(jī)器人通信的特點(diǎn),制定了相應(yīng)的通信協(xié)議,同時(shí)采用了多種有效的編程方法,以達(dá)到安全、高效、實(shí)用的目的。經(jīng)過(guò)大量的測(cè)試以及I年多工業(yè)運(yùn)用表明,該通信協(xié)議及通信系統(tǒng)取得了很好的效果,完全達(dá)到了工業(yè)機(jī)器人通信的要求。
參考文獻(xiàn)
1宗光華,劉海波,程君實(shí).機(jī)器人技術(shù)手冊(cè).北京:科學(xué)出版社,1996
2候捷.Win32多線程程序設(shè)計(jì).武漢:華中科技大學(xué)出版社,2002
3徐軍.Visual C++5開發(fā)人員指南.北京:機(jī)械工業(yè)出版社,1998
4 Serial Communications in Win32. http://www自wtech.com/serialcomm





