羅丹 厲虹 周淑一
[摘要]Windows CE人機界面是面向移動計算機和嵌入式應用的操作系統,具有友好的用戶界面和強大的通信能力,RS-232串行通信是WinCE支持的最基本通信方式。本文將RS-232串行通信技術應用于供熱領域換熱站的預付費智能控制系統,設計了在WinCE操作系統下,實現RS-232人機界面與讀卡器之間以及$50非接觸射頻卡與讀卡器之間的通信程序,較好地解決了串口之間的通信問題,最終利用S8讀卡器軟件平臺對編寫程序做以驗證,為從事串口程序開發者提供了參考。
[關鍵詞]Windows CE 串行通信 讀卡器 S50非接觸射頻卡
目前,國內供熱領域對公建單位管理模式有所改進,形成一種換熱站預付費智能控制系統解決方案,而預付費智能控制系統離不開人機界面與讀卡器、讀卡器與IC卡之間的通信。串行通信是計算機通信的重要方式,以其設備價格低廉、連接簡單、技術成熟等優點得到廣泛應用。Windows CE是微軟推出的一個多任務、有友好界面、強大通信能力的32位開放實時操作系統,WinCE系統以其良好的性能得到越來越廣泛的應用。
二、WinCE環境下的串行通信
串行端口和應用程序的溝通是通過串行裝置驅動程序完成的,即通過操作系統中文件系統的應用程序開發接口存取串行裝置驅動程序,以傳送/接收信息和控制串行裝置。一般通信串口軟件結構如圖1所示:
串行設備被視為用于打開、關閉、讀寫串行端口的常規、可安裝的流設備。WinCE的通信函數和其他大多數Windows的通信函數相同,但WinCE不支持直接對串行端口的寄存器進行編程。所使用串行端口部分函數有:
2.1打開和關閉串口通信端口
打開串行端口使用函數CreateFile,若打開端口不存在,則CreateFile回傳“ERROR_FILE_NOT_FOUND”信息,且用戶被通知這個端口不存在。
打開串行通信端口的步驟如下:
(1)使用參數IpzPortName傳入指定的串行端口名稱。
(2)將參數dwShareMode設為0,表示不允許此COM口被其他應用程序同時打開。
(3)將參數dwCreationDisposition設為OPEN_EXISTING。
(4)將參數dwFlagsAndAttributes設為0,Windows CE只支持非交錯式輸入/輸出。
//打開串行端口
hPort=CreateFile(Serealcom,//指定串口名稱
0,//共享模式
OPEN_XISTING//打開方式
0);//串口屬性
當應用程序使用串行通信端口通信完畢后,使用函數CloseHandle關閉串行通信端口。CloseHandle被呼叫之后,在串行端口通信被關閉和資源釋放之前,會有2秒的延遲。
2.2設定串行通信端口
以DCB(device-control block)結構設定好串行通信端口,呼叫CreateFile函數打開一個有默認串行端口設定值的串行端口,使用GetCommState函數取得默認值,再使用SetCommState函數完成新值的設定,使用COMMTIMEOUTS結構設定讀寫操作的逾時值。
DCB PortDCB;//創建DCB
PortDCB.DCBlength=sizeof(DCB);//初始化
GetCommState(hPort,&PortDCB;);//取得默認port設置
PortDCB.BaudRate=1 15200;//傳輸波特率
PortDCB.Parity=NOPARITY;//校驗位
PortDCB.StopBits=ONESTOPBIT;//停止位
對于串口通信端口,應用程序必須使用COMMTIMEOUTS結構來設定串口端口的逾時值。通常,配置超時值和配置串口類似。首先用Get CommTimeots函數獲得當前串口的超時值,然后可以修改COMMTIMEOUT成員,最后用SetCommTimeouts函數設定超時值。
COMMTIMEOUTS CommTimeouts;//聲明結構
GetCommTimeouts(hPort,&CommTimeouts;);//獲得當前的超時值
//變更COMMTIMEOUT結構的設定值
SetCommTimeouts(hPort,&CommTimeouts;);//設定讀寫動作的逾時值
2.3讀取/寫入通信串口
讀取通信端口使用ReadFile函數接收從其他末端的串聯連接裝置來的信息,需要注意的是WinCE不支持重疊I/O,所以如果在主線程進行大量讀寫串口操作時,有可能使整個程序陷入緩慢的串口等待中去,因此一般都采用多線程來進行讀寫串口操作。WinCE不支持交錯式I/O,故其參數設置為NULL。讀取串行通信端口程序如下:
ReadFile(hPort,&Byte;,//指向讀取的信息存放之處
1,//欲讀取的字節個數
&dwBytesTransferred;,//實際讀取的字節個數
NULL//不支持交錯式I/O
串行通信端口使用WriteFile函數連接到另外的裝置傳輸信息,由于WinCE串行通信不支持交錯式I/O,故應用程序的主要線程或建立任何窗口的線程不應寫進大量信息到串行端口,否則這些線程會被阻塞等待輸入/輸出完成無法管理其他相關信息隊列,寫入串行通信端口的程序如下:
WriteFile(hPort,&Byte;,//指向欲寫入的信息
1,//欲寫入數據的字節個數
&dwBytesWritten;,//實際寫入的字節個數
NULL//不支持交錯式I/O
三、S50非接觸射頻卡與讀卡器通信
3.1硬件組成
本預付費智能控制系統讀卡器采用峰華科技S8型雙界面讀卡,通過RS232串行接口與人機界面連接,工作頻率為13.56MHz,支持非接觸卡MIFARE系列/DESFIRE/ICODE2等常見IC卡和CPU卡,本次測試與PC采用COM3連接,IC卡采用廣泛應用的S50卡,容量8k,分16個扇區,每個扇區4塊,每塊16個字節,每個扇區有獨立的一組密碼及訪問控制;IC卡有唯一的32位序列號,具有防沖突機制,可對數據塊進行初始化、讀、寫操作,每個扇區的塊3為控制塊,包括密碼A、存取控制以及密碼B,結構為:A0 A1 A2 A3 A4 A5 FF 07 80 69 B0 B1 B2 B3 B4 B5,圖2為S50卡讀寫單元結構。
3.2軟件設計
目前用匯編語言開發串行通信程序的應用較多,通常利用Mscomm控件、第3方動態鏈接庫和調用API函數三種方式編寫串行通信程序,Win32中使用API函數開發通信程序時串口和其他通信設備均被作為文件處理,串口的打開、關閉等操作使用的API函數與操作文件的函數相同。本文基于VC開發串行通信程序,利用第3方提供的動態鏈接庫以及調用API函數編寫通信程序。
系統使用umf.dll動態鏈接文件,在讀取IC卡以及讀卡器上所存放的電壓數據時,調用實現串口通信。其中iport參數是串口號,系統采用的是COM3串口通信,iBaud參數是傳輸波特率,根據用戶需求,傳輸波特率設定為115200,iSerialNo參數是讀卡器的序列號,系統規定為0。具體的傳輸協議使用動態鏈接庫的函數來實現數據通信,所以不再設置。
使用WinAPI進行串口通信程序設計具有很強的靈活性,Windows的API函數存放在動態鏈接庫中,調用函數API可以實現串口通信,圖3為$50卡與讀寫器的通信流程簡圖。
對于復位應答來說,通信協議和通信波特率已經是定義好的,當有卡片進入讀寫器操作范圍時,讀卡器與之通信來確定是否為本系統卡片類型,本系統設定一次只能選擇一張卡進行操作,故防沖突機制就是當有多張卡進入讀卡范圍時從中選擇一張進行操作,其他的等待下次讀卡,同時返回選中射頻卡的序列號。選定要處理的卡片對扇區密碼進行校驗確保無誤進行后續讀寫操作。
根據通信協議約定在主機控制單元對射頻卡讀寫控制時需要握手連接,利用如下代碼,若三次均成功則數據開始傳送,否則關閉端口。
Serial.SendData(&STX;_request,1);//發送聯絡信號
Sleep(1000);//等待回應
Serial.Read_Data(&read;_Buffer,1);//讀取射頻卡讀寫模塊響應信號
if(read_Buffer==DLE)
//在此進行命令數據傳送
else
Serial.Close();//操作完成后關閉端口
若握手成功則對卡片進行密碼驗證等系列命令,以下為部分源程序:
fw_getver(icdev,linchar);//獲取設備號
fw_request(indev,0,tagtype);//發出尋卡請求
fw_anticoll(icdev,0,&snr;);//防碰撞控制,返回卡序列號
show(“Find Card Ok!”1:
linstr.Format(“%u”,cardsnr;
show(linstr);
fw_select(icdev,snr,&size;);//選擇某一序號的卡,size返回卡的容量大小
if(fw_authentication(icdev,0,key)!=0)//核對扇區密碼
printf(“Authentication error!”);
else
show(“Auth Card Ok!”):
fw_read(icdev,4,data)//讀IC卡塊4數據
fw_changed3(iedev,1,keya,ctrlword,0,keyb);∥修改一扇區塊3密碼
fw_halt();//讀寫一次后掛起,直到卡重新進入有效范圍
本系統采用S8型讀寫器軟件平臺對編寫程序進行測試,首先連接數據通信線并打開S8.exe,對程序中部分功能進行驗證,圖4為連接成功后顯示的設備型號F#W-FMl702-V1.00,序號為預先設置的0。
本系統通信線連接使用COM3接口,故在初始化端口時選COM3端口并設置波特率為115200,圖5為初始化端口并設置參數。
S50卡分16個扇區,每個扇區由4塊組成,共有0-63塊,其中第0扇區的塊O存放廠商代碼,已經固化不可更改。系統對扇區3進行密碼驗證,如果不成功則返回重新尋卡操作,讀寫卡測試隨機選扇區4進行讀寫卡操作,點擊讀卡可看到扇區4里面的數據均讀出,且可改變數值進行寫卡操作。圖6、7分別為驗證扇區3密碼以及讀寫卡操作。
四、結論
基于VC語言實現在Windows CE平臺上的串行端口通信應用于換熱站智能預付費系統。利用調用WIN32 API函數的方式設計并開發S50卡與讀卡器的通信程序,在s8讀卡器上進行驗證,能接收到來自S50非接觸射頻卡上的數據,實現了讀卡器與IC卡之間的通信,該方法對實現基于WinCE的串口通信有一定參考價值,此串口程序的設計及開發為也為更多通信工程師提供了參考。