《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 業(yè)界動態(tài) > 用Windows API設(shè)計(jì)多線程的串行通信ActiveX控件

用Windows API設(shè)計(jì)多線程的串行通信ActiveX控件

2009-05-05
作者:雷 鵬 陳 星

??? 摘? 要: 介紹了利用VC++6.0實(shí)現(xiàn)基于Window API的多線程串行通信ActiveX控件的設(shè)計(jì)方法,并給出主要的通信程序代碼。?

??? 關(guān)鍵詞: ActiveX? Windows API? 串行通信? 多線程

?

??? 串行通信是計(jì)算機(jī)之間及計(jì)算機(jī)與數(shù)字化儀器和設(shè)備的一種重要通信手段,是實(shí)現(xiàn)工業(yè)監(jiān)控的一種主要方式。Windows下的串行通信主要有兩種方法:利用VB的MSCOMM控件和利用Windows API。MSCOMM控件簡單易用,但由于其對串口設(shè)備的封裝及調(diào)用方式的局限性,不能靈活方便地對串口設(shè)備進(jìn)行控制。而通過Windows API則可以實(shí)現(xiàn)對串口設(shè)備的完全控制,并且可以提供多線程的通信機(jī)制。?

??? 在復(fù)雜應(yīng)用中,通信通常在后臺完成,需要采用多線程技術(shù)。一個多線程的應(yīng)用程序實(shí)際上是在其內(nèi)部實(shí)現(xiàn)了多任務(wù)擴(kuò)展,為代碼賦予了并行執(zhí)行的特性,適于執(zhí)行一些實(shí)時性或隨機(jī)性很強(qiáng)的操作,也有利于提高CPU的利用率,加快通信程序的信息處理速度。?

??? 本文以一臺工業(yè)控制PC機(jī)與多臺基于單片機(jī)的智能控制單元進(jìn)行串行通信為實(shí)例。PC機(jī)和各智能控制單元通過RS485總線互聯(lián)。由于RS485的通信方式是半雙工的,只能由作為主節(jié)點(diǎn)的PC機(jī)依次輪詢網(wǎng)絡(luò)上的各智能控制單元子節(jié)點(diǎn)。每次通信都是由PC機(jī)通過串口向智能控制單元發(fā)布命令,智能控制單元在接收到正確的命令后做出應(yīng)答。?

??? 系統(tǒng)的主節(jié)點(diǎn)應(yīng)用程序是用VB6.0編寫的,為了既能提供多線程的串行通信機(jī)制,又可使應(yīng)用程序易于實(shí)現(xiàn)串行通信功能,利用VC++6.0開發(fā)基于Window API的多線程串行通信ActiveX控件。主節(jié)點(diǎn)的應(yīng)用程序通過對串行通信ActiveX控件的調(diào)用完成與各子節(jié)點(diǎn)的通信。?

1 創(chuàng)建ActiveX控件JinRiComm.OCX?

??? VC++6.0和MFC是創(chuàng)建ActiveX控件的強(qiáng)大而又靈活的工具。JinRiComm控件創(chuàng)建步驟簡單概述如下:?

??? (1)用MFC ActiveX ControlWizard生成ActiveX控件工程,命名為JinRiComm。?

??? (2)打開ClassWizard窗口,選擇Automation標(biāo)簽,單擊“Add Property”按鈕,命名新的屬性。單擊“Add Method”按鈕,命名新的方法。選擇ActiveX Event標(biāo)簽,單擊“Add Event”按鈕,命名新的事件。?

??? (3) 向控件工程中添加類CSerialPort,為該類添加成員變量和成員函數(shù),該類將完成串行通信工作。?

2 串口通信的基本編程?

??? 用Windows API函數(shù)實(shí)現(xiàn)串行通信,其特點(diǎn)是對串口的操作如對文件操作一樣,打開和關(guān)閉串行設(shè)備與打開和關(guān)閉文件使用相同的函數(shù)。?

??? (1) 打開串口?

??? m_hComm = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0,?? NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);???? ?

??? (2) 獲取當(dāng)前通信信息,設(shè)置通信設(shè)備?

??? GetCommState(m_hComm, &m_dcb);?

??? SetCommState(m_hComm, &m_dcb);?

??? (3) 讀、寫串口?

??? bResult=ReadFile(port->m_hComm, &RXBuff, 1, &BytesRead, port->m_ov);?

??? bResult=WriteFile(port->m_hComm,&(port->m_Byte)[i],1, &BytesSent, &port->m_ov);?

??? (4) 關(guān)閉串口?

??? CloseHandle(m_hComm);?

3 設(shè)計(jì)程序中的線程?

??? MFC執(zhí)行兩種類型的線程:用戶界面線程和工作線程。前者用來處理用戶輸入,響應(yīng)由用戶產(chǎn)生的事件和消息。后者不處理窗口消息,用于完成后臺計(jì)算、打印和其它一些沒有必要強(qiáng)迫用戶來等待的任務(wù)。在本程序中,用戶界面線程就是程序的主線程,另外再添加兩個工作線程:通信線程和延時線程。它們的功能介紹如表1所示。?

?

?

??? 應(yīng)用AfxBeginThread函數(shù)來啟動一個工作線程,用法如下:?

??? CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc,LPVOID pParam,int nPriority=THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL )?

??? 在啟動一個工作線程之前,必須為線程編寫一個全局的線程函數(shù)。這個線程函數(shù)接受一個32位的LPVOID作為參數(shù),返回一個UINT,線程函數(shù)的結(jié)構(gòu)為:?

??? UINT ThreadUFunction(LPVOID pParam )?

??? {?

??? //線程處理代碼?

??? return 0;?

??? }?

??? 終止線程有兩種途徑:當(dāng)線程函數(shù)返回時,線程終止;線程函數(shù)也可以在內(nèi)部調(diào)用AfxEndThread函數(shù)來終止自己。?

??? 程序流程圖如圖1所示。?

?

?

4 線程間的通信?

??? (1) 通過全局變量??? ?

??? 主線程可以采用多種方式與工作線程進(jìn)行通信,最簡單的辦法是通過全局變量,因?yàn)檫M(jìn)程中的所有線程都可以訪問所有的全局變量。如:定義全局變量bReceiveSuccess,它表示是否收到了正確的響應(yīng)。在主線程向串口寫數(shù)據(jù)之后它被置為FALSE,然后延時線程啟動。當(dāng)系統(tǒng)收到正確的響應(yīng)后,bReceiveSuccess被主線程改為TRUE。延時線程根據(jù)bReceiveSuccess的值來決定是結(jié)束該線程還是給主線程發(fā)消息。?

??? (2) 通過參數(shù)?

??? 主線程可以向工作線程傳遞一個4字節(jié)的參數(shù),一種使用該參數(shù)的常見方式是傳遞一個指針,它指向這個線程的父類。如:?

UINT CSerialPort::CommThread(LPVOID pParam)?

{?

??? CSerialPort *port=(CSerialPort*)pParam; //取得串口類指針?

??????????????????????????????? ?? //線程處理代碼?

}?

??? (3) 通過消息?

??? 工作線程獲得主線程的窗口句柄,則可以給主線程發(fā)送消息。如:?

??? 通信線程通知主線程,串口接收到了數(shù)據(jù)?

??? ::PostMessage((port->m_pOwner)->m_hWnd, WM_COMM_RXCHAR,(WPARAM) RXBuff, (LPARAM) port->m_nPortNr);?

5 線程的同步?

??? 多線程的優(yōu)點(diǎn)之一是所有線程都可以訪問相同的全局對象和共享資源,它提供了程序設(shè)計(jì)的簡捷性和便利性,提高了對信息處理的并發(fā)度。但如果不妥善處理好線程的并發(fā)問題,也會帶來數(shù)據(jù)的錯誤或是資源的死鎖。為了避免這些問題發(fā)生,線程在使用共享資源或?qū)ο笄氨仨毇@得一個約束訪問同步對象的權(quán)力,也就是通過同步的機(jī)制來控制這種權(quán)力的使用。線程間的同步有多種方法。?

??? (1) 臨界區(qū)?

??? 臨界區(qū)是通過對多個線程的串行化來訪問公共資源或一段代碼。如:?

??? InitializeCriticalSection(&(port->m_csCommunicationSync)); //初始化臨界區(qū)對象?

??? EnterCriticalSection(&port->m_csCommunicationSync);?

??? //使調(diào)用線程等待獲得臨界區(qū)對象并在獲得擁有權(quán)時返回?

Do?

{?

??? if(!bReceiveSuccess)????????? //訪問全局變量?

??? {?????????????????????????????????? ?

??? LeaveCriticalSection(&port->m_csCommunicationSync);?

??? //釋放對臨界區(qū)對象的擁有權(quán)?

??? //其它處理代碼?

??? }?

}?

??? (2) 事件?

??? 事件用來通知線程有一些事件已經(jīng)發(fā)生,比較適合于信號控制。事件有手動復(fù)位和自動復(fù)位兩種。手動復(fù)位事件是在應(yīng)用程序或系統(tǒng)后臺控制下改變它的信號狀態(tài)。當(dāng)手動復(fù)位事件處于有信號狀態(tài)時,所有等待該事件的線程都被激活,事件保留有信號狀態(tài)直到被一個應(yīng)用程序復(fù)位為止。當(dāng)一個自動復(fù)位事件處于有信號狀態(tài)時,只有一個等待線程會被激活,并且事件將復(fù)位成無信號,其它所有等待著的線程仍將保持掛起狀態(tài)。?

??? 定義3個事件:?

??? m_hEventArray[0] = m_hShutdownEvent;?//結(jié)束通信線程事件?

??? m_hEventArray[1] = m_ov.hEvent;???? //讀事件?

??? m_hEventArray[2] = m_hWriteEvent;?? ???? //寫事件?

??? 在通信線程的線程函數(shù)CommThread中等待3個事件的發(fā)生?

??? Event=WaitForMultipleObjects(3,port->m_hEventArray, FALSE, INFINITE);?

switch (Event)?

{?

??? case 0: //結(jié)束通信線程事件?

??? {?

??? port->m_bThreadAlive = FALSE;?

??? AfxEndThread(100);//結(jié)束通信線程?

??? break;?

??? }?

??? case 1:???? //讀事件 ?? ?

??? {?

??? GetCommMask(port->m_hComm, &CommEvent);?

??? if (CommEvent & EV_RXCHAR)?

??? ReceiveChar(port, comstat);//從串口讀數(shù)?

??? break;?

??? } ?

??? case 2:???? //寫事件?

??? {?

??? WriteChar(port);??????? //向窗口寫數(shù)?

??? break;?

??? }?

} // end switch?

參考文獻(xiàn)?

1 Visual C++6.0 Online Help [M]?

2 (美)本內(nèi)特(Bennett,D.)著,徐 軍譯.Visual C++5開發(fā)人員指南.北京:機(jī)械工業(yè)出版社,1998.6

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。
亚洲一区二区欧美_亚洲丝袜一区_99re亚洲国产精品_日韩亚洲一区二区
9久re热视频在线精品| 午夜精品在线看| 亚洲字幕一区二区| 99国产精品久久久| 亚洲欧洲日韩在线| 亚洲福利视频一区| 在线观看日韩av先锋影音电影院| 翔田千里一区二区| 亚洲网站视频福利| 亚洲私拍自拍| 亚洲欧美激情精品一区二区| 一本色道久久综合狠狠躁的推荐| 99国产精品| 亚洲精品一区二区三区福利| 1000精品久久久久久久久| 韩国成人精品a∨在线观看| 国内精品久久久久影院色| 国产一区在线免费观看| 国产在线拍揄自揄视频不卡99 | 久久本道综合色狠狠五月| 亚洲免费影视| 性欧美xxxx视频在线观看| 午夜精品婷婷| 久久国产精品99国产| 久久午夜电影网| 免费h精品视频在线播放| 欧美肥婆bbw| 欧美日韩精品欧美日韩精品| 欧美视频观看一区| 国产精品一香蕉国产线看观看| 欧美电影在线| 欧美日韩精品免费观看视频| 欧美午夜激情视频| 国产精品一区二区三区久久久| 欧美美女操人视频| 欧美日韩在线视频一区二区| 国产精品一级在线| 国内精品久久久久影院 日本资源| 欧美日韩一区二区三区免费看 | 国产视频综合在线| 国产主播精品在线| 亚洲高清精品中出| 一区二区激情视频| 欧美一区二区三区在| 亚洲国语精品自产拍在线观看| 亚洲永久视频| 欧美一区二区女人| 亚洲精品免费观看| 亚洲在线观看免费视频| 新片速递亚洲合集欧美合集| 可以免费看不卡的av网站| 欧美精品在线观看一区二区| 国产伦理精品不卡| 亚洲级视频在线观看免费1级| 国产在线观看一区| 激情欧美一区| 日韩一级视频免费观看在线| 性欧美暴力猛交69hd| 亚洲精品一区二区网址| 亚洲专区欧美专区| 久久久最新网址| 欧美人与禽猛交乱配视频| 国产欧美日韩视频在线观看 | 欧美亚洲视频| 亚洲精品极品| 欧美一区二区性| 欧美国产亚洲另类动漫| 国产伦精品一区二区三区在线观看| 欧美日韩在线观看视频| 国产精品欧美日韩一区二区| 激情综合色综合久久综合| 一本色道久久综合亚洲精品婷婷| 亚洲美女网站| 欧美一级免费视频| 中文在线不卡视频| 久久免费99精品久久久久久| 欧美日韩精品免费观看| 国产日韩欧美二区| av不卡免费看| 亚洲精品少妇网址| 久久久综合香蕉尹人综合网| 欧美午夜在线观看| 亚洲福利一区| 久久成人18免费网站| 亚洲欧美变态国产另类| 欧美国产免费| 好看的av在线不卡观看| 亚洲自拍16p| 亚洲午夜激情在线| 欧美成人亚洲| 狠狠色丁香久久婷婷综合_中| 国产一区视频在线看| 日韩一区二区精品葵司在线| 亚洲福利在线看| 久久精品三级| 国产精品高潮粉嫩av| 亚洲美女av网站| 亚洲日本在线观看| 久久久久久国产精品mv| 国产欧美日韩在线视频| 亚洲三级电影在线观看| 亚洲国产一区在线| 久久亚洲精选| 国产日韩欧美视频在线| 亚洲色无码播放| 一本久久知道综合久久| 欧美激情1区| 亚洲国产精品精华液网站| 亚洲高清成人| 久久综合狠狠综合久久综青草| 美日韩精品视频| 国产精品伦理| 一区二区三区免费网站| 一本综合精品| 欧美日韩国产一区二区| 亚洲第一精品夜夜躁人人躁| 久久精品国产欧美亚洲人人爽| 日韩午夜电影在线观看| 久久久999| 国产一区日韩二区欧美三区| 欧美一站二站| 久久精品国产清高在天天线| 国产三级精品三级| 午夜久久电影网| 久久久国产精品一区| 国产一区二区三区在线观看网站| 亚洲日本精品国产第一区| 亚洲精品美女久久久久| 欧美激情综合亚洲一二区| 最新中文字幕一区二区三区| 99精品视频免费观看| 欧美精品观看| 艳女tv在线观看国产一区| 亚洲欧美日韩视频一区| 国产精品一区二区三区乱码| 午夜精品视频在线观看| 久久一区激情| 亚洲国产午夜| 亚洲综合国产激情另类一区| 国产欧美精品日韩精品| 亚洲福利视频一区二区| 欧美二区在线播放| 欧美日韩国产区一| 免费h精品视频在线播放| 亚洲高清视频在线观看| 洋洋av久久久久久久一区| 欧美视频免费在线观看| 亚洲专区免费| 久久久久久网址| 亚洲国产精品va| 一区二区三区精品视频| 国产精品美女主播在线观看纯欲| 黄色av一区| 亚洲精品一区二区三区婷婷月 | 精品福利电影| 亚洲激情自拍| 欧美日本韩国一区二区三区| 亚洲小说欧美另类社区| 久久久久久97三级| 亚洲日本一区二区| 午夜精品一区二区三区在线播放| 欧美成人国产| 亚洲精品偷拍| 欧美一区二区视频在线| 亚洲成色777777在线观看影院| 亚洲欧美资源在线| 久久亚洲不卡| 91久久久久久久久| 欧美一区二区成人| 亚洲国产精品va在线看黑人动漫| 亚洲国产精品激情在线观看| 欧美日本久久| 西西裸体人体做爰大胆久久久| 一区二区三区www| 国产精品观看| 亚洲国产成人精品久久久国产成人一区| 欧美在线精品一区| 亚洲第一页在线| 亚洲欧美一区二区三区久久| 尹人成人综合网| 亚洲在线视频观看| 在线观看国产一区二区| 亚洲欧美亚洲| 亚洲精品一区二区三| 久久久久国产精品午夜一区| 亚洲国产日韩在线一区模特| 小处雏高清一区二区三区 | 亚洲欧美日韩国产综合在线| 久久综合影视| 亚洲一卡二卡三卡四卡五卡| 欧美黑人多人双交| 久久成人精品一区二区三区| 欧美偷拍一区二区| 亚洲黄色影院| 午夜一区二区三区不卡视频| 亚洲国产清纯| 午夜精品区一区二区三| 亚洲第一综合天堂另类专| 欧美一级大片在线观看| 午夜精品电影|