目前,在用計算機進行數據傳輸時,常用的是串行通信方式。在Visual C++的編程中,既可以用Windows API函數進行串行通信編程,也可以利用環境自帶的控件進行編程。利用 API函數編寫實際應用程序時,往往要考慮多線程的問題,這樣編出來的程序不但十分龐大,而且結構比較復雜,繼承性差,維護困難。但是使用串行通信控件就相對簡單一些,而且功能強大,性能安全可靠。
本文以Microsoft Communications Control(version 6.0)為例,介紹串行通信控件在VC++中的使用方法。
嵌入通信控件
使用串行通信控件前,首先要進行系統注冊。
1、在建立新工程時,將ActiveX Controls復選框選中,表示本程序支持ActiveX 控件。
2、單擊Project菜單,從中選擇Add to Project,在彈出的對話框中單擊Components and Controls選項,然後在彈出的對話框中再單擊Registered ActiveX Controls選項。
3、在列表中選擇Microsoft Communications Control (version6.0),形狀為帶有紅色底座的黃色電話機。單擊Insert按鈕,確認後,會出現一個Confirm Classes對話框,其中列出了該控件的類名(CMSComm)、頭文件名(MSComm.h)、執行文件名(MSComm.cpp)。
關閉此對話框,在程序主界面的控件列表中,可以看到該通信控件已被加入,拖動該控件就可以將其放入程序中。
編寫通信程序
通信控件的工作原理類似於中斷方式,當有通信事件發生時,如發送、接收數據,就會觸發OnComm事件。在OnComm事件的處理函數中調用 GetCommEvent()函數,由該函數的返回值即可確定是什麼類型的事件,並由此做出相應的處理。
下面以接收處理串口的GPS信號為例,說明該控件在編程中的具體應用。
利用MFC生成一個基於對話框的應用程序,對話框中的控件及其相應的消息與響應函數如下表所示。
控件名稱 控件 ID 對應變量 通信控件 IDC_MSCOMM m_Comm 接收按鈕 IDC_BUTTON_RECEIVEGPSDATA OnbuttonStartreceivegps() GPS信號顯示 IDC_EDIT_COMDATA m_comdata 停止接收按鈕 IDC_BUTTON_ENDRECEIVEGPSDATA OnbuttonEndreceivegps() 設置控件各部分屬性:
CommPort:1;
DTREnable:1;
InBufferSize:4096;
EOFEnable:TRUE;
Handshaking:nohandshaking;
InputMode:1-Binary;
NullDiscard:False;
Rthreshold:250;
RTSEnable:False;
Settings:9600,n,8,1;
Sthreshold:0。
部分程序如下:
//開始接收GPS信號
void CGpsDlg::OnButtonStartreceivegps()
{
//判斷串口的狀態,如果是關閉狀態,則打開
if(!m_Comm.GetPortOpen() )
//打開串口
m_Comm.SetPortOpen(TRUE);
UpdateData(TRUE);
}
//停止接收GPS的信號
void CGpsDlg::OnButtonEndreceivegps();
{
//判斷串口的狀態,如果是打開狀態,則關閉
if( m_Comm.GetPortOpen() )
m_Comm.SetPortOpen(FALSE);
UpdateData(FALSE);
}
//相應的OnComm事件處理
void CGpsDlg::OnComm()
{
m_comdata.Empty();
VARIANT m_input1;
COleSafeArray m_input2;
LONG length,i;
BYTE data[1024];
CString str;
//接收緩沖區內字符
if(m_Comm.GetCommEvent()== 2)
{
m_comdata.Empty();
//讀取緩沖區內的數據
m_input1=m_Comm.GetInput();
//將VARIANT型變量轉換為ColeSafeArray型變量
m_input2=m_input1;
//確定數據長度
length=m_input2.GetOneDimSize();
//將數據轉換為BYTE型數組
for(i=0;i< length;i++)
m_input2.GetElement(&i,data+i);
//將數組轉換為CString型變量
for(i=0;i< length;i++) {
char a=* (char *)(data+i);
str.Format(“%c",a);
m_comdata += str;
}
/*在上面的程序中,先將VARIANT型變量
轉換為ColeSafeArray型變量,再將其轉換為
BYTE型數組,然後將數組轉換為CString型變量,
以滿足不同的變量類型顯示數據的需要。*/
//提取GPS信號
CString m_zjz;
m_zjz=m_comdata;
//尋找GPS信號的頭標志
int s;
s=m_zjz.Find(“$GPRMC,");
CString m_gps;
//NUM為所提取GPS信號的長度
m_gps=m_zjz.Mid(s,NUM);
int x;
x=m_gps.GetLength();
//信號長度不符合要求,則拒絕接收
if (x != NUM) {
m_gps.Empty();
}
//尋找所需要的GPS信號的頭標志
int y;
y=m_gps.Find(“$GPRMC,");
if (y != 0)
{
m_gps.Empty();
}
//m-gpsdata是已聲明的類成員變量
m_gpsdata=m_gps;
}
}
這樣就將GPS信號的數據流提取出來了。再通過簡單的字符串操作就可以分別找出GPS信號中的經度、緯度以及相對應的格林威治時間等定位信息。
以上程序在Win98/95/NT、P133 PC機、ROCKWELL JUPITER GPS接收板環境下調試通過。