在VC++6.0中使用串行通信控件
發(fā)表時(shí)間:2024-02-24 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]北京裝甲兵工程學(xué)院崔 杰 梁計(jì)春 王國(guó)軍 目前,在用計(jì)算機(jī)進(jìn)行數(shù)據(jù)傳輸時(shí),常用的是串行通信方式。在 Visual C++的編程中,既可以用 Windows API函數(shù)進(jìn)行串行通信編程,也可以利用環(huán)境自帶的控件進(jìn)行編程。利用 API函數(shù)編寫實(shí)際應(yīng)用程序時(shí),往往要考慮多線程的問題,這樣編出來(lái)的程序不...
北京裝甲兵工程學(xué)院
崔 杰 梁計(jì)春 王國(guó)軍
目前,在用計(jì)算機(jī)進(jìn)行數(shù)據(jù)傳輸時(shí),常用的是串行通信方式。在 Visual C++的編程中,既可以用 Windows API函數(shù)進(jìn)行串行通信編程,也可以利用環(huán)境自帶的控件進(jìn)行編程。利用 API函數(shù)編寫實(shí)際應(yīng)用程序時(shí),往往要考慮多線程的問題,這樣編出來(lái)的程序不但十分龐大,而且結(jié)構(gòu)比較復(fù)雜,繼承性差,維護(hù)困難。但是使用串行通信控件就相對(duì)簡(jiǎn)單一些,而且功能強(qiáng)大,性能安全可靠。
本文以 Microsoft Communications Control( version 6.0)為例,介紹串行通信控件在 VC++中的使用方法。
嵌入通信控件
使用串行通信控件前,首先要進(jìn)行系統(tǒng)注冊(cè)。
1.在建立新工程時(shí),將 ActiveX Controls復(fù)選框選中,表示本程序支持 ActiveX控件。
2.單擊 Project菜單,從中選擇 Add to Project,在彈出的對(duì)話框中單擊 Components and Controls選項(xiàng),然后在彈出的對(duì)話框中再單擊 Registered ActiveX Controls選項(xiàng)。
3.在列表中選擇 Microsoft Communications Control (version6.0),形狀為帶有紅色底座的黃色電話機(jī)。單擊 Insert按鈕,確認(rèn)后,會(huì)出現(xiàn)一個(gè) Confirm Classes對(duì)話框,其中列出了該控件的類名( CMSComm)、頭文件名 (MSComm.h)、執(zhí)行文件名 (MSComm.cpp)。
關(guān)閉此對(duì)話框,在程序主界面的控件列表中,可以看到該通信控件已被加入,拖動(dòng)該控件就可以將其放入程序中。
編寫通信程序
通信控件的工作原理類似于中斷方式,當(dāng)有通信事件發(fā)生時(shí),如發(fā)送、接收數(shù)據(jù),就會(huì)觸發(fā) OnComm事件。在 OnComm事件的處理函數(shù)中調(diào)用 GetCommEvent()函數(shù),由該函數(shù)的返回值即可確定是什么類型的事件,并由此做出相應(yīng)的處理。
下面以接收處理串口的 GPS信號(hào)為例,說(shuō)明該控件在編程中的具體應(yīng)用。
利用 MFC生成一個(gè)基于對(duì)話框的應(yīng)用程序,對(duì)話框中的控件及其相應(yīng)的消息與響應(yīng)函數(shù)如下表所示。
控件名稱 控件 ID 對(duì)應(yīng)變量
通信控件 IDC_MSCOMM m_Comm
接收按鈕 IDC_BUTTON_RECEIVEGPSDATA OnbuttonStartreceivegps()
GPS信號(hào)顯示 IDC_EDIT_COMDATA m_comdata
停止接收按鈕 IDC_BUTTON_ENDRECEIVEGPSDATA OnbuttonEndreceivegps()
設(shè)置控件各部分屬性:
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信號(hào)
void CGpsDlg::OnButtonStartreceivegps()
{
//判斷串口的狀態(tài),如果是關(guān)閉狀態(tài),則打開
if(!m_Comm.GetPortOpen() )
//打開串口
m_Comm.SetPortOpen(TRUE);
UpdateData(TRUE);
}
//停止接收 GPS的信號(hào)
void CGpsDlg::OnButtonEndreceivegps();
{
//判斷串口的狀態(tài),如果是打開狀態(tài),則關(guān)閉
if( m_Comm.GetPortOpen() )
m_Comm.SetPortOpen(FALSE);
UpdateData(FALSE);
}
//相應(yīng)的 OnComm事件處理
void CGpsDlg::OnComm()
{
m_comdata.Empty();
VARIANT m_input1;
COleSafeArray m_input2;
LONG length,i;
BYTE data[1024];
CString str;
//接收緩沖區(qū)內(nèi)字符
if(m_Comm.GetCommEvent()== 2)
{
m_comdata.Empty();
//讀取緩沖區(qū)內(nèi)的數(shù)據(jù)
m_input1=m_Comm.GetInput();
//將 VARIANT型變量轉(zhuǎn)換為 ColeSafeArray型變量
m_input2=m_input1;
//確定數(shù)據(jù)長(zhǎng)度
length=m_input2.GetOneDimSize();
//將數(shù)據(jù)轉(zhuǎn)換為 BYTE型數(shù)組
for(i=0;i< length;i++ )
m_input2.GetElement(& i,data+ i);
//將數(shù)組轉(zhuǎn)換為 CString型變量
for(i=0;i< length;i++ ) {
char a=* (char* )(data+ i);
str.Format("% c",a);
m_comdata+ = str;
}
/*在上面的程序中,先將 VARIANT型變量轉(zhuǎn)換為 ColeSafeArray型變量,再將其轉(zhuǎn)換為 BYTE型數(shù)組,然后將數(shù)組轉(zhuǎn)換為 CString型變量,以滿足不同的變量類型顯示數(shù)據(jù)的需要。* /
//提取 GPS信號(hào)
CString m_zjz;
m_zjz=m_comdata;
//尋找 GPS信號(hào)的頭標(biāo)志
int s;
s=m_zjz.Find("$ GPRMC,");
CString m_gps;
//NUM為所提取 GPS信號(hào)的長(zhǎng)度
m_gps=m_zjz.Mid(s,NUM);
int x;
x=m_gps.GetLength();
//信號(hào)長(zhǎng)度不符合要求,則拒絕接收
if (x != NUM) {
m_gps.Empty();
}
//尋找所需要的 GPS信號(hào)的頭標(biāo)志
int y;
y=m_gps.Find("$ GPRMC,");
if (y != 0)
{
m_gps.Empty();
}
//m- gpsdata是已聲明的類成員變量
m_gpsdata=m_gps;
}
}
這樣就將 GPS信號(hào)的數(shù)據(jù)流提取出來(lái)了。再通過簡(jiǎn)單的字符串操作就可以分別找出 GPS信號(hào)中的經(jīng)度、緯度以及相對(duì)應(yīng)的格林威治時(shí)間等定位信息。
以上程序在 Win98/95/NT、 P133 PC機(jī)、 ROCKWELL JUPITER GPS接收板環(huán)境下調(diào)試通過。