摘要:簡單分析Windows 下串口通信方式, 詳細(xì)介紹了使用 串口通訊庫PComm實現(xiàn)特殊波特率的方法。
關(guān)鍵詞:串口;特殊波特率;PComm庫
中圖分類號:TP393 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2009)15-3871-03
Realization of SpecialBaudRateBased on VC++
LIU Kui
(Zhejiang Textile and Fashion College, Ningbo 315211,China)
Abstract: The communication of serial interface has been analysed simply,and the paper introduces how to realize specialbaudrateby using thePComm communicationLibrary.
Key words: serial interface ; special baud rate; PComm Library
1 引言
串口是計算機(jī)上一種非常通用的接口。大多數(shù)計算機(jī)包含一個基于RS232的串口。串口本質(zhì)上是計算機(jī)的CPU和外部串行設(shè)備間的編碼轉(zhuǎn)換器。當(dāng)數(shù)據(jù)從CPU經(jīng)過串口發(fā)送出去時,字節(jié)數(shù)據(jù)被轉(zhuǎn)換為串行的位。而在接收數(shù)據(jù)時,串行的位則被轉(zhuǎn)換為字節(jié)數(shù)據(jù)。
串口同時也是工業(yè)過程控制中儀器儀表設(shè)備通用的接口,可以用于獲取遠(yuǎn)程采集設(shè)備的數(shù)據(jù)。目前在進(jìn)行工業(yè)設(shè)備改造的過程中,通常是在Windows環(huán)境中進(jìn)行應(yīng)用程序開發(fā),常常需要通過串口與工業(yè)設(shè)備通信。為了適應(yīng)工業(yè)設(shè)備(尤其是國外進(jìn)口設(shè)備)接口速率,這時對通信速率會有特殊要求,就不能使用計算機(jī)串口通常提供的速率(9600bps,19200bps,38400bps,57600bps,115200bps),而是76800bps。本文就Window環(huán)境下基于VC++開發(fā)串口通信程問題展開討論,并介紹一種串口特殊波特率的實現(xiàn)方法。
2Windows環(huán)境下基于VC++串口通信編程
2.1采用Windows API 函數(shù)
串口在Windows 中是作為文件來進(jìn)行處理的, 不是直接對物理端口進(jìn)行操作。對于串行通信, Windows 提供了相應(yīng)的文件I/O 函數(shù)與通信函數(shù), 通過了解這些函數(shù)的使用, 可以編制出符合不同需要的通信程序。與通信設(shè)備相關(guān)的結(jié)構(gòu)有COMMCONFIG , COMMPROP, COMMTIMEOUTS, COMSTAT,DCB, MODEMDEVCAPS,MODEMSETTINGS 共七個, 與通信有關(guān)的Windows API 函數(shù)共有26 個, 詳細(xì)說明可參考MSDN 幫助文件 。
操作串行口一般遵從以下四個步驟:
1) 打開串口。VC 中將串口作為文件操縱, 所以打開串口時, 也使用與打開文件相同的API 函數(shù), 如下:
HANDLE CreateFile( LPCTSTR lpFileName, //串口名稱或設(shè)備路徑
DWORD dwDesiredAccess, // 存取方式, 讀或?qū)?/p>
DWORD dwShareMode, //共享方式, 獨占或共享
LPSECURITY_ATTRIBUTES lpSecurityAttributes, //安全描述符
DWORD dwCreationDisposition, //創(chuàng)建方式
DWORD dwFlagsAndAttributes, //文件屬性
HANDLE hTemplateFile // 參照模板
) ;
但是dwDesiredAccess 必須為0, 因為串口是獨占設(shè)備;dwCreationDisposition 必須為OPEN_EXISTING, 因為只有串口存在時才能被打開; dwCreationDisposition 一般為FILE_FLAG_OVERLAPPED, 表示串行口以異步方式工作。
2) 設(shè)置串口工作參數(shù)。串口能夠順利通信必須保證通信參數(shù)設(shè)置正確, 這些通信參數(shù)包括波特率、數(shù)據(jù)長度、停止位、校驗方式等, 所以在串口打開之后必須進(jìn)行串口設(shè)置。設(shè)置串口屬性的一般思路是先利用GetCommState()獲得串口的設(shè)備控制塊DCB, 修改必要的部分之后, 再利用SetCommState( ) 將修改后的屬性信息寫回DCB 中。
3) 從串口讀取或向串口寫入數(shù)據(jù)。串口的讀寫主要通過兩個文件讀寫API 函數(shù)來實現(xiàn), 即ReadFile( ) 和WriteFile( )。但是由于串口的通信并不是絕對的穩(wěn)定, 所以應(yīng)該采用異步方式, 以防止通信故障使程序陷入無限等待中。串口的讀寫方式也有兩種, 一種是簡單的查詢方式, 這種方式比較容易實現(xiàn), 但是浪費了大量的CPU時間; 另一種是基于事件驅(qū)動的方式, Windows 中共提供了九種串口通信時間, 請參見MSDN 幫助文件 。
4) 關(guān)閉串口。串口是非共享資源,所以打開串口后,一定要關(guān)閉串口。關(guān)閉串口函數(shù)的原型:BOOL CloseHandle(HANDLE hObject);其中hObject參數(shù)為CreateFile()返回的端口句柄。返回值非0,則調(diào)用成功。
2.2采用MScomm控件編程
Microsoft Communications Control(簡稱MSComm)是Microsoft公司提供的簡化Windows下串行通信編程的控件,它為應(yīng)用程序提供了通過串行接口收發(fā)數(shù)據(jù)的簡便方法。具體地說,它提供了兩種處理通信問題的方法:1) 事件驅(qū)動(Event-driven)方法:主要是在comEvReceive(接收到數(shù)據(jù))事件發(fā)生時響應(yīng)并獲取緩沖區(qū)的數(shù)據(jù);2)查詢法:每當(dāng)應(yīng)用程序執(zhí)行完某一串行口操作后,應(yīng)不斷檢查MSComm控件的CommEvent屬性以檢查執(zhí)行結(jié)果或者檢查某一事件是否發(fā)生。
VC集成開發(fā)環(huán)境下對該控件編程的步驟:
1)在當(dāng)前的Workspace中插入MSComm控件
在VC環(huán)境下,創(chuàng)建基于對話框的MFC應(yīng)用程序,在設(shè)置項目選項時必須選上ActiveX Controls,其他的按照缺省設(shè)置。然后進(jìn)行以下步驟:Project菜單→Add to Project→Components and Controls→Registered ActiveX Controls→選擇Components: Microsoft Communications Control,version 6.0插入到當(dāng)前的Workspace中。
結(jié)果添加了類CMSComm(對應(yīng)相應(yīng)文件mscomm.h和mscomm.cpp也自動加入工程)。
2)在MainFrm.h中加入MSComm控件
protected:
CMSComm m_ComPort;
在Mainfrm.cpp::OnCreate()中加入:
DWORD style=WS_VISIBLE|WS_CHILD;
if(!m_ComPort.Create(NULL,style,CRect(0,0,0,0),this,ID_COMMCTRL)){
TRACE0(“Failed to create OLE Communications Control\”);
return-1;//創(chuàng)建失敗}
3)初始化串口
4)捕捉串口事件
MSComm控件可以采用輪詢或事件驅(qū)動的兩種方法從端口獲取數(shù)據(jù)。比較常用的是事件驅(qū)動方法:有事件(接收到數(shù)據(jù))時通知程序。在程序中需要捕獲并處理這些通訊事件。
5)讀寫串口
2.3 利用VC++庫標(biāo)準(zhǔn)通信函數(shù)實現(xiàn)串口編程
利用VC進(jìn)行異步通信編程,其實是對串口內(nèi)部寄存器的讀出或?qū)懭氩僮鳌C可利用VC++類庫中提供的標(biāo)準(zhǔn)通信函數(shù)_inp()、_outp()函數(shù)對其進(jìn)行編程。
通過計算機(jī)串口進(jìn)行串行通信之前,必須根據(jù)設(shè)備的有關(guān)通信參數(shù),約定雙方的通信方式,包括波特率的設(shè)置、奇偶位校驗及停止位的設(shè)立,確定數(shù)據(jù)傳輸幀格式和UART操作方式,逐個對線路控制寄存器、波特率因子寄存器等寄存器寫入操作,可以利用VC運(yùn)行庫提供的通信函數(shù)_inp(),_outp()來實現(xiàn)串口通信。
3 串口特殊波特率的實現(xiàn)方法
許多工業(yè)設(shè)備以串行方式傳送數(shù)據(jù),但傳輸速率往往使用計算機(jī)上不支持的76800bpps,尤其是國外進(jìn)口設(shè)備。決定計算機(jī)串口的通信速率是晶振頻率,這決定了本質(zhì)上是通過改變波特率因子來確定傳輸速率的標(biāo)準(zhǔn)串口是不支持76800bps速率的。
這一問題可以通過使用USB轉(zhuǎn)串口的接口解決,目前許多這類接口都提供比標(biāo)準(zhǔn)串口多的傳輸速率,其中包含76800bps的速率。在此基礎(chǔ)上,利用USB轉(zhuǎn)串口的設(shè)備結(jié)合所提供的庫函數(shù)PComm.lib,編程實現(xiàn)特殊波特率的方法。
1)程序開發(fā)環(huán)境設(shè)置:
將PComm.lib添加到鏈接庫列表中,如圖1,確保PComm.h 和PComm.lib 文件在搜索路徑中,如圖2、圖3。
添加PComm.h文件到程序頭部:
#include
#include “PComm.h”
2)采用PComm.lib進(jìn)行串口通信的典型步驟:
首先調(diào)用控制函數(shù)(打開、速率設(shè)置、校驗方式等),然后調(diào)用輸入、輸出函數(shù)進(jìn)行通信,調(diào)用串口狀態(tài)查詢函數(shù)(如果需要),關(guān)閉串口。典型示例如下:
port = 2; //串口2
ret = sio_open (port);// 打開
if (ret == 0) {//成功打開
sio_ioctl (port, B19200, P_NONE | BIT_8 | STOP_1 );// 速率、校驗方式、位數(shù)等設(shè)置
sio_write (port, \"ABCDE\", 5);//輸出
sio_read (port, ibuf, length);//輸入
}
sio_close (port);//關(guān)閉
3)主要庫函數(shù)功能:
串口控制函數(shù):功能包括串口的打開、關(guān)閉、傳輸參數(shù)的設(shè)置等,主要函數(shù)有sio_open()、sio_close ()、sio_ioctl()sio_baud ( )。其中可以通過sio_ioctl()設(shè)置速率、校驗方式、位數(shù)等,要使用特殊波特率則可以通過sio_baud ( )設(shè)置串口的實際波特率,例如設(shè)置串口2的波特率為76800可以用sio_baud (2,76800L),如果串口不支持該波特率,則會選擇最接近的波特率來工作。
串口讀寫控制函數(shù):功能包括串口讀寫、超時設(shè)置等,主要函數(shù)有sio_read()、sio_SetReadTimeouts()、sio_write()、sio_SetWriteTimeouts ()等。
串口狀態(tài)查詢函數(shù):功能包括輸入輸出隊列、串口參數(shù)等,主要函數(shù)有sio_iqueue ()、sio_oqueue () sio_getmode ()等。
串口中斷事件服務(wù)函數(shù):當(dāng)收到特定字符或收到設(shè)定的字符數(shù)時,觸發(fā)相應(yīng)的例程,主要函數(shù)有sio_term_irq()、 sio_cnt_irq()等。
4 結(jié)束語
PComm串行通信庫函數(shù)完全兼容Microsoft Win32 API。它完全適合Win32環(huán)境下所有類型的串口,使用它提供的函數(shù)可以很容易實現(xiàn)多線程,結(jié)合目前常用的USB轉(zhuǎn)串口的接口,可以實現(xiàn)較標(biāo)準(zhǔn)串口更多的傳輸速率,為開發(fā)工業(yè)環(huán)境下需要特殊速率的串行通信程序提供非常方便的途徑。