Windows CE.NET 4.2下PC與單片機的串行通信
在工業(yè)控制中,常需要將單片機采集到的數(shù)據(jù)傳送給PC機處理、顯示,并且根據(jù)處理結(jié)果給單片機發(fā)送控制命令。串行通信雖然傳送速度相對較慢,但是傳送成本低,對實現(xiàn)監(jiān)視和控制,具有足夠的帶寬,并且沒有過于復雜的編解碼,實現(xiàn)自定義的協(xié)議也不復雜,因而在工業(yè)自動化、通信和軍事等領(lǐng)域的應用十分廣泛。隨著Windows CE嵌入式操作系統(tǒng)在工業(yè)控制中的廣泛應用,設(shè)計和實現(xiàn)Windows CE下PC與單片機的串行通信具有重要的意義。
1Windows CE.NET 4.2簡介
Windows CE 是一個面向移動計算和嵌入式應用的操作系統(tǒng),其突出優(yōu)點是模塊化、可定制性、完備性、實時性、通信能力強大和基于Win32應用程序編程接口。 Windows CE.N ET 4.2是為嵌入式市場重新設(shè)計的Windows CE 3.0的后繼產(chǎn)品,為快速建立下一代智能移動和小內(nèi)存占用的設(shè)備提供了一個健壯的實時操作系統(tǒng)。他包括創(chuàng)建一個基于定制設(shè)備的Wi ndows CE所需的一切。?
2Windows CE.NET 4.2下的串行通信技術(shù)
串行端口在Windows CE.NET 4.2(以下簡稱Windows CE)下屬于流接口設(shè)備,他是串行設(shè)備接口常規(guī)I/O驅(qū)動程序的調(diào)用與通信相關(guān)的具體函數(shù)的結(jié)合。串行設(shè)備被視為用于打開、關(guān)閉和讀寫串行端口的常規(guī)的可安裝的流設(shè)備。Windows CE的串口函數(shù)和Windows的串口函數(shù)基本相同,但有幾點值得注意:
(1)Windows CE只支持Unicode字符集,在編程時必須特別注意。
(2) Windows CE不支持重疊的I/O操作。
2.1打開和關(guān)閉串行端口
在所有的流設(shè)備驅(qū)動程序中,均使用CreateFile來打開串行端口設(shè)備,如果這個端口不存在,CreateFile返回 ERROR_FILE_NOT_FOUND。因此,用戶指定的端口必須是存在并且可用的,而且要遵循Windows CE流接口設(shè)備驅(qū)動程序的命名規(guī)則,即COM后接要打開的端口號再緊跟一個冒號。
HANDLE hPort = CreateFile (_T("COM1:"),
GENERIC_READ|GENERIC_WRITE, 0,NULL,
OPEN_EXISTING,0,NULL);
關(guān)閉串行端口比較簡單,調(diào)用CloseHandle函數(shù)就能關(guān)閉一個打開的串行端口。CloseHandle只有一個參數(shù),即調(diào)用CreateFile函數(shù)打開端口時返回的句柄,方法如下:
CloseHandle (hPort);
2.2讀寫串行端口
正如使用CreateFile打開串行端口一樣,可以使用ReadFile和WriteFile函數(shù)來讀寫串行端 口。假設(shè)已經(jīng)調(diào)用CreateFile成功地打開了串行端口,那么只需調(diào)用ReadFile即可從串行端口讀取數(shù)據(jù):
由于Windows CE不支持重疊的I/O操作,所以第5個參數(shù)必須設(shè)置為NULL。寫串行端口也很 簡單。調(diào)用過程如下:
如果從主線程讀、寫大量的串行數(shù)據(jù),主線程就會因為等待相對較慢的串行讀或串行寫操作而阻塞,不能即時處理其他的消息。因此最好用單獨的線程來讀寫串行端口。
2.3配置串行端口
讀和寫串行端口比較簡單,但是還需要對端口配置好正確的波特率、字符長度、奇偶校驗、傳輸模式等,端口才能正確通信。可以調(diào)用I/O設(shè)備控制(IOCTL)來配置串行驅(qū)動程序,但此操作需要一些底層的知識,并且要有相應的“嵌入工具包”(ETK),而SDK不能實現(xiàn)該操作。除此之外,還有一種更簡單的方法,就是調(diào)用GetCommState和SetCommState函數(shù)配置串行端口。由于配置端口的DCB結(jié)構(gòu)內(nèi)容較多,所以使用起來比較麻煩。錯誤地初始化 DCB結(jié)構(gòu)是配置串行端口常見的問題。如果一個串行通信函數(shù)沒有產(chǎn)生預期的效果,那么錯誤很可能是在DCB結(jié)構(gòu)體的賦值。在與單片機實現(xiàn)串行通信的時候,由于只用到了RS 232串行口的RXD,TXD和GND三個引腳,而其他的引腳均舍棄不用,所以DCB的成員變量應該如下設(shè)置,否則不能正常通信:
2.4設(shè)置超時值
對于串行端口來說,還必須配置超時值,否則程序可能陷入到一個等待來自串口字符的死循環(huán)。通常,配置超時值和配置串口類似。首先用 GetCommTimeouts函數(shù)獲取當前串口的超時值,然后修改CommTimeouts成員變量的值,最后用SetCommTimeouts設(shè)置新的超時值。
2.5異步多線程通信
雖然Windows CE不支持重疊I/O,但還是可以使用多個線程來實現(xiàn)同樣的操作。當主線程正忙時,需要做的就是運行單獨的線程來處理同步I/O操作。除了使用用于讀和寫的單獨線程以外,Windows CE還支持Win32的WaitCommEvent函數(shù),該函數(shù)將線程阻塞,直到預先設(shè)定的串行通信事件中的一個發(fā)生。該函數(shù)一般和函數(shù) SetCommMask配合起來使用,SetCommMask設(shè)置WaitCommEvent要等待的串口事件。一般的使用方法是:
先調(diào)用SetCommMask函數(shù)設(shè)定要等待的串口事件,例如串口有數(shù)據(jù)到來(EV_RXCHAR)事件;然后在讀串口線程中調(diào)用WaitCommEvent阻塞線程,等待EV_RXCHAR事件的發(fā)生。當?shù)?/p>
待的EV_RXCHAR事件發(fā)生時,調(diào)用ClearCommError函數(shù)清除通信錯誤信息,并且獲取串口的當前狀態(tài),主要是獲取串口接收緩沖區(qū)中的字節(jié)數(shù),然后調(diào)用ReadFile函數(shù)將接收緩沖區(qū)的數(shù)據(jù)全部讀出。最后調(diào)用PostMessage函數(shù)將這些數(shù)據(jù)發(fā)送給主線程進行處理。
這里存在一個問題:讀串口數(shù)據(jù)操作是在讀串口線程中進行的,而處理數(shù)據(jù)操作是在主線程中進行的,如果上次接收的數(shù)據(jù)還沒處理完,下次的數(shù)據(jù)又發(fā)送給了主線程處理,勢必造成混亂。這個問題的解決,涉及到線程間的同步機制。
2.6線程間的同步
在Windows CE中采用同步對象的方法來協(xié)調(diào)多線程的執(zhí)行。一個線程監(jiān)視一個同步對象,當用信號通知該對象時,解除正在阻塞的線程并調(diào)度該線程。同步對象包括事件和互斥體兩種方式。本文只介紹事件方式。
事件對象是一種有兩種信號狀態(tài)有信號和無信號的同步對象,創(chuàng)建的事件對象可以被不同的線程共享。Windows CE常用等待函數(shù)阻塞線程自身的執(zhí)行,等待其監(jiān)視的對象產(chǎn)生一定的信號才停止阻塞,繼續(xù)線程的執(zhí)行。常用的等待函數(shù)有監(jiān)視單個同步對象的 WaitForSingleObject,和監(jiān)視多個同步對象的WaitForMultipleObjects。在Windows CE串口通信中,用CreateEvent函數(shù)創(chuàng)建事件時,手動設(shè)置為有信號狀態(tài),以便程序在第一次能夠順利地進入到WaitCommEvent函數(shù)處等待串口數(shù)據(jù)的到來,等到程序讀取了串口的數(shù)據(jù)并發(fā)送給主線程處理后,調(diào)用ResetEvent函數(shù)將事件狀態(tài)設(shè)置成無信號狀態(tài),線程就阻塞在 WaitForSingleObject函數(shù)處,一直等到主線程把接收到的數(shù)據(jù)處理完后,再將事件狀態(tài)用SetEvent函數(shù)設(shè)置成有信號狀態(tài),釋放 WaitForSingleObject函數(shù)對線程的阻塞,重新進入WaitCommEvent函數(shù)處等待串口數(shù)據(jù)的到來。循環(huán)接收、處理串口數(shù)據(jù)的流程如圖1所示。
3完整的串行通信程序
頭文件定義:
4結(jié)語
為了實現(xiàn)Windows CE下PC與單片機的串行通信,本串口通信程序采用自定義的通信協(xié)議,在運行Windows 2000的PC機上,用Embedded Visual C++4.0編寫,在PC機上編譯、調(diào)試成功后,下載到運行Windows CE.NET 4.2的工控機上運行,實現(xiàn)了和單片機的正確通信,獲得了很好的效果。本程序也能夠應用于其他類似的測控應用場合。?
參考文獻?
[1]傅曦,齊宇.嵌入式系統(tǒng)Windows CE開發(fā)技巧與實例[M].北京:化學工業(yè)出版社,2003
[2]田東風.Windows CE應用程序設(shè)計[M].北京:機械工業(yè)出版社,2003
[3][美]Douglas Boling.Microsoft Windows CE程序設(shè)計[M].北京博彥科技發(fā)展有限公司譯.北京:北京大學出版社,1999
[4][美]Chris Muench. Windows CE權(quán)威指南[M].精英科技譯.北京:中國電力出版社,2001.