《電子技術應用》
您所在的位置:首頁 > 嵌入式技術 > 業界動態 > 用Windows API設計多線程的串行通信ActiveX控件

用Windows API設計多線程的串行通信ActiveX控件

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

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

??? 關鍵詞: ActiveX? Windows API? 串行通信? 多線程

?

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

??? 在復雜應用中,通信通常在后臺完成,需要采用多線程技術。一個多線程的應用程序實際上是在其內部實現了多任務擴展,為代碼賦予了并行執行的特性,適于執行一些實時性或隨機性很強的操作,也有利于提高CPU的利用率,加快通信程序的信息處理速度。?

??? 本文以一臺工業控制PC機與多臺基于單片機的智能控制單元進行串行通信為實例。PC機和各智能控制單元通過RS485總線互聯。由于RS485的通信方式是半雙工的,只能由作為主節點的PC機依次輪詢網絡上的各智能控制單元子節點。每次通信都是由PC機通過串口向智能控制單元發布命令,智能控制單元在接收到正確的命令后做出應答。?

??? 系統的主節點應用程序是用VB6.0編寫的,為了既能提供多線程的串行通信機制,又可使應用程序易于實現串行通信功能,利用VC++6.0開發基于Window API的多線程串行通信ActiveX控件。主節點的應用程序通過對串行通信ActiveX控件的調用完成與各子節點的通信。?

1 創建ActiveX控件JinRiComm.OCX?

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

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

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

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

2 串口通信的基本編程?

??? 用Windows API函數實現串行通信,其特點是對串口的操作如對文件操作一樣,打開和關閉串行設備與打開和關閉文件使用相同的函數。?

??? (1) 打開串口?

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

??? (2) 獲取當前通信信息,設置通信設備?

??? 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) 關閉串口?

??? CloseHandle(m_hComm);?

3 設計程序中的線程?

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

?

?

??? 應用AfxBeginThread函數來啟動一個工作線程,用法如下:?

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

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

??? UINT ThreadUFunction(LPVOID pParam )?

??? {?

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

??? return 0;?

??? }?

??? 終止線程有兩種途徑:當線程函數返回時,線程終止;線程函數也可以在內部調用AfxEndThread函數來終止自己。?

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

?

?

4 線程間的通信?

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

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

??? (2) 通過參數?

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

UINT CSerialPort::CommThread(LPVOID pParam)?

{?

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

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

}?

??? (3) 通過消息?

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

??? 通信線程通知主線程,串口接收到了數據?

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

5 線程的同步?

??? 多線程的優點之一是所有線程都可以訪問相同的全局對象和共享資源,它提供了程序設計的簡捷性和便利性,提高了對信息處理的并發度。但如果不妥善處理好線程的并發問題,也會帶來數據的錯誤或是資源的死鎖。為了避免這些問題發生,線程在使用共享資源或對象前必須獲得一個約束訪問同步對象的權力,也就是通過同步的機制來控制這種權力的使用。線程間的同步有多種方法。?

??? (1) 臨界區?

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

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

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

??? //使調用線程等待獲得臨界區對象并在獲得擁有權時返回?

Do?

{?

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

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

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

??? //釋放對臨界區對象的擁有權?

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

??? }?

}?

??? (2) 事件?

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

??? 定義3個事件:?

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

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

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

??? 在通信線程的線程函數CommThread中等待3個事件的發生?

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

switch (Event)?

{?

??? case 0: //結束通信線程事件?

??? {?

??? port->m_bThreadAlive = FALSE;?

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

??? break;?

??? }?

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

??? {?

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

??? if (CommEvent & EV_RXCHAR)?

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

??? break;?

??? } ?

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

??? {?

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

??? break;?

??? }?

} // end switch?

參考文獻?

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

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

本站內容除特別聲明的原創文章之外,轉載內容只為傳遞更多信息,并不代表本網站贊同其觀點。轉載的所有的文章、圖片、音/視頻文件等資料的版權歸版權所有權人所有。本站采用的非本站原創文章及圖片等內容無法一一聯系確認版權者。如涉及作品內容、版權和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當措施,避免給雙方造成不必要的經濟損失。聯系電話:010-82306118;郵箱:aet@chinaaet.com。
亚洲一区二区欧美_亚洲丝袜一区_99re亚洲国产精品_日韩亚洲一区二区
国内精品国语自产拍在线观看| 亚洲乱码日产精品bd| 欧美电影资源| 久久影院亚洲| 久久一综合视频| 亚洲高清久久久| 亚洲午夜av在线| 亚洲伦理精品| av成人毛片| 国产亚洲视频在线观看| 国产精品成人av性教育| 欧美日韩成人网| 欧美全黄视频| 亚洲国产成人久久综合一区| 欧美亚一区二区| 欧美日韩一区二区三区在线观看免 | 午夜欧美大片免费观看| 亚洲一区欧美二区| 亚洲欧美日产图| 欧美一区二区三区久久精品| 欧美亚洲免费电影| 久久精品国产综合精品| 久久久久久一区| 麻豆成人在线播放| 欧美美女视频| 欧美视频在线观看免费网址| 国产精品美女午夜av| 国产午夜精品久久久久久久| 狠狠久久婷婷| 亚洲国产网站| 一本一本久久a久久精品牛牛影视| 亚洲天堂久久| 欧美在线观看天堂一区二区三区| 欧美中文字幕视频| 亚洲精品小视频| 亚洲免费在线观看| 久久久成人网| 欧美精品www| 国产精品女人毛片| 韩国精品久久久999| 亚洲激情在线观看视频免费| aa日韩免费精品视频一| 午夜一区在线| 91久久久久久久久| 中文国产成人精品| 久久不射2019中文字幕| 欧美成人一区二免费视频软件| 欧美日韩午夜剧场| 国产午夜精品全部视频播放| 亚洲国产精品va在线观看黑人| 一本色道久久加勒比精品| 午夜视频久久久久久| 亚洲精品日韩欧美| 午夜亚洲一区| 欧美成人xxx| 国产精品免费小视频| 影音先锋在线一区| 国产欧美一区二区三区在线老狼| 亚洲福利视频一区| 国产在线视频欧美| 亚洲精品日韩在线观看| 亚洲欧美在线一区| 日韩亚洲欧美在线观看| 欧美在线日韩精品| 欧美精品一区二区三区在线播放| 国产精品自拍网站| 亚洲人久久久| 欧美一区日韩一区| 亚洲一级网站| 女同性一区二区三区人了人一| 国产精品久久一区主播| 亚洲国产专区校园欧美| 羞羞答答国产精品www一本| 9色国产精品| 久久久一区二区| 国产精品视频xxx| 亚洲人线精品午夜| 欧美在线精品一区| 亚洲欧美精品在线| 欧美精品一区在线| 国外成人在线视频网站| 一二三四社区欧美黄| 亚洲欧洲在线免费| 久久久久国产精品一区| 国产精品成人观看视频国产奇米| 在线观看欧美黄色| 欧美影院久久久| 午夜精品久久久久99热蜜桃导演| 欧美精品二区| 亚洲大片一区二区三区| 欧美亚洲视频| 亚洲欧美中日韩| 欧美性色aⅴ视频一区日韩精品| 亚洲高清中文字幕| 久久精品日韩一区二区三区| 欧美在线视频观看| 国产精品久久77777| 亚洲另类一区二区| 日韩视频不卡中文| 欧美成人精品在线播放| 激情自拍一区| 欧美中文在线观看国产| 性欧美激情精品| 国产精品高潮呻吟久久| 99riav国产精品| 制服丝袜激情欧洲亚洲| 欧美精品一区二区三区高清aⅴ| 亚洲福利精品| 亚洲国内自拍| 美女国产一区| 亚洲高清免费视频| 亚洲黄色视屏| 欧美h视频在线| 亚洲电影免费观看高清| 亚洲激情成人网| 美日韩丰满少妇在线观看| 伊人色综合久久天天| 亚洲第一区在线观看| 久热精品视频| 在线免费日韩片| 亚洲区一区二| 欧美经典一区二区三区| 91久久国产综合久久| 日韩亚洲精品电影| 欧美日韩精品欧美日韩精品 | 一区二区三区成人| 亚洲一区二区三区在线播放| 国产精品a级| 亚洲性夜色噜噜噜7777| 欧美一区免费视频| 国内精品嫩模av私拍在线观看 | 欧美一区二区三区久久精品| 国产欧美日韩综合一区在线播放| 午夜精品美女自拍福到在线 | 亚洲三级电影全部在线观看高清| 欧美77777| 亚洲人成人99网站| 亚洲影院免费| 国产女同一区二区| 亚洲第一天堂无码专区| 欧美精品一区二区精品网| 夜夜爽夜夜爽精品视频| 亚洲欧美日韩区| 国产一区二区激情| 亚洲欧洲三级电影| 欧美婷婷在线| 性刺激综合网| 欧美韩日一区二区| 中文欧美日韩| 久久亚洲不卡| 亚洲精选91| 欧美一区国产一区| 亚洲高清免费视频| 亚洲一本视频| 国产原创一区二区| 99国产精品久久久久老师| 国产精品扒开腿做爽爽爽软件| 亚洲欧美激情精品一区二区| 久久五月天婷婷| 狠狠狠色丁香婷婷综合激情| 99精品国产一区二区青青牛奶| 欧美视频精品一区| 亚洲欧美视频| 欧美大成色www永久网站婷| 一区二区三区视频在线看| 久久久久国内| 亚洲精品国产系列| 久久av老司机精品网站导航| 亚洲国产精品专区久久| 亚洲中午字幕| 亚洲第一区在线| 午夜精品亚洲| 亚洲激情成人在线| 久久er精品视频| 亚洲精品免费在线| 久久激五月天综合精品| 亚洲精选中文字幕| 久久久久久9| 一本到高清视频免费精品| 久久久青草青青国产亚洲免观| 日韩亚洲欧美一区| 裸体一区二区| 亚洲一区中文字幕在线观看| 欧美成年网站| 欧美一级一区| 欧美日韩直播| 亚洲国产专区| 国产欧美一区二区精品忘忧草| 亚洲免费电影在线| 国产一区二区三区四区老人| 亚洲性视频网站| 亚洲欧洲综合| 久久一区二区三区超碰国产精品| 一区二区三区黄色| 欧美韩日视频| 亚洲电影免费观看高清完整版在线 | 亚洲欧美日韩一区二区| 亚洲第一搞黄网站| 久久久不卡网国产精品一区| 在线视频免费在线观看一区二区|