Visual C++為我們提供了一種好用的ActiveX控件Microsoft Communications Control(即MSComm)來支持應用程序對串口的訪問,在應用程序中插入MSComm控件后就可以較為方便地實現對通過計算機串口收發數據。
要使用ActiveX控件MSComm,程序員必須將其添加入工程,其方法是:
(1)單擊主菜單project的子菜單Add To project的Components and Controls選項;
(2)在彈出的"Components and Controls Gallery"對話框中選擇Registered ActiveX Controls文件夾中的"Microsoft Communications Control,version 6.0"選項
單擊其中的"Insert"按鈕,MSComm控件就被增加到工程中了。與此同時,類CMSComm的相關文件mscomm.h和mscomm.cpp也一並被加入Project的Header Files和Source Files中。當然,程序員可以自己修改文件名
1在建立的工程中插入MSComm控件
2添加MSComm控件ID的控制變量或對象
3對串口進行初始化,設置MSComm控件的屬性
4添加串口事件的消息處理函數OnComm()函數,在函數中根據應用需要,編寫數據處理代碼
5編寫串口發送等其他代碼
6關閉串口
一個MSComm控件只能對應一個串口,如果應用程序需要訪問多個串口,必須使用多個MSComm控件。
處理通信問題的方式:事件驅動方式(與中斷原理類似,觸發一個事件處理函數),查詢方式。
MSComm控件的重要屬性中的一部分
CommPort設置並返回通信端口號
Settings以字符串的形式設置並返回波特率、奇偶校驗、數據位、停止位。
PortOpen設置並返回通信端口的狀態。可以用來打開和關閉端口
Input從接受緩沖區返回和刪除字符串
Output向傳輸緩沖區寫一個字符串
每個屬性都通過Get/Set函數對來獲取或設置控件的屬性
屬性簡介
CommPort
設置並返回端口號
void CMSComm::SetCommPort(short nNewValue)
short CMSComm::GetCommPort()
RThreshold
在MSComm控件設置CommEvent屬性為comEvReceive並產生OnComm之前,設置並返回要接收的字符數。達到設定值則觸發OnComm。
void CMSComm::SetRThreshold(short nNewValue)
short CMSComm::GetRThreshold()
CTSHolding
確定是否可通過查詢CTS線的狀態發送數據。硬件握手的手工查詢
void CMSComm::SetCTSHolding(BOOL bNewValue)
BOOL CMSComm::GetCTSHolding()
SThreshold
在MSComm控件設置CommEvent屬性為comEvSend並產生OnComm之前,設置並返回傳輸緩沖區中允許的最小字符數。
void CMSComm::SetSThreshold(short nNewValue)
short CMSComm::GetSTreshold()
Handshaking
設置或返回硬件握手狀態,使用內部通信協議
void CMSComm::SetHandshaking(long nNewValue)
long CMSComm::GetHandshaking()
InputMode
設置或返回傳輸數據的類型
void CMSComm::SetInputMode(long nNewValue)
long CMSComm::GetInputMode()
DSRHolding
確定DSR線的狀態。
void CMSComm::SetDSRHolding(BOOL bNewValue)
BOOL CMSComm::GetDSRHolding()
Settings
設置並返回波特率、奇偶校驗、數據位、停止位參數
void CMSComm::SetSettings(LPCTSTR lpszNewValue)
CString CMSComm::GetSettings()
"BBBB,P,D,S"BBBB為波特率,P為奇偶校驗,D為數據位數,S為停止位數
缺省值為"9600,N,8,1"
InputLen
設置並返回Input屬性從接收緩沖區讀取的字符數
void CMSComm::SetInputLen(short nNewValue)
short CMSComm::GetInputLen()
缺省值為0,使用Input將使MSComm控件讀取接收緩沖區中的全部的內容。在使用Input前,可檢查InBufferCount屬性來確定緩沖區中是否已有需要數目的字符。此屬性在從輸出格式為定長數據的機器讀取數據時非常有用。
InBufferSize
設置或返回輸入緩沖區的大小
void CMSComm::SetInBufferSize(short nNewValue)
short CMSComm::GetInBufferSize()
默認為1024Byte
InBufferCount
設置或返回輸入緩沖區內等待讀取的字節個數
void CMSComm::SetInBufferCount(short nNewValue)
short CMSComm::GetInBufferCount()
當設置InBufferCount屬性的值為0時,可以清空接收緩沖區(很有用的功能)
OutBufferSize
設置或返回發送緩沖區的大小
void CMSComm::SetOutBufferSize(short nNewValue)
short CMSComm::GetOutBufferSize()
默認為512字節。此值不能太小,否則緩沖區易溢出,但太大會不必要地占用內存。
OutBufferCount
返回發送緩沖區的字節數或者清空發送緩沖區
void CMSComm::SetOutBufferCount(short nNewValue)
short CMSComm::GetOutBufferCount()
設置值為0時清空發送緩沖區
InPut
從接收緩沖區內讀出數據
VARIANT CMSComm::GetInPut()
返回為VARIANT型變量
當InPutMode為0時,檢取數據為文本方式,變量中含有String型數據類型,當InPutMode為1時,檢取數據為二進制方式,變量中含Byte數組型數據。
OutPut
向發送緩沖區寫數據,或返回發送緩沖區當前的數據
void CMSComm::SetOutPut(const VARIANT&newValue)
VARIANT CMSComm::GetOutPut()
PortOpen
用於打開或關閉串口,或返回串口的開、關狀態
void CMSComm::SetPortOpen(BOOL bNewValue)
BOOL CMSComm::GetPortOpen()
TURE打開串口,FALSE關閉串口,程序終止后,MSComm控件自動關閉串口
EOFEnable
確定在輸入過程中MSComm控件是否尋找文件結尾EOF字符,如果找到EOF字符,將停止輸入並激活OnComm事件,此時CommEvent屬性設置為ComEvEOF
void CMSComm::SetEOFEnable(BOOL bNewValue)
BOOL CMSComm::GetEOFEnable()
DTREnalbe
設置或返回DTR線狀態。
void CMSComm::SetDTREnable(BOOL bNewValue)
BOOL CMSComm::GetDTREnable()
RTSEnable
確定是否使RTS線有效
void CMSComm::SetRTSEnable(BOOL bNewValue)
BOOL CMSComm::GetRTSEnable()
Break
設置或清除中斷信號的狀態
void CMSComm::SetBreak(BOOL bNewValue)
BOOL CMSComm::GetBreak()
CommID
返回一個說明通信設備的句柄。
void CMSComm::SetCommID(long nNewValue)
long CMSComm::GetCommID()
該值與WindowsAPICreateFile函數返回的值一致。
NullDiscard
確定Null字符是否從端口傳送到接收緩沖區
void CMSComm::SetNullDiscard(BOOL bNewValue)
BOOL CMSComm::GetNullDiscard()
OnComm事件和CommEvent屬性
設置或返回無論何時當CommEvent屬性的值變化時,就產生OnComm事件,標志發生了一個通信事件或一個錯誤。CommEvent屬性值反映錯誤或者事件類型,通常在程序中的事件消息處理函數中對CommEvent事件進行處理。
void CMSComm::SetCommEvent(short nNewValue)
short CMSComm::GetCommEvent()
通常由函數GetCommEvent()得到當前事件值,再進行相應的處理。
MSComm控件的調出及其主要屬性如下。
(1)MSComm控件的調出
VB6.0的MSComm控件並不會主動出現在工具箱中,當需要它時,讓它出現在工具箱中的步驟如下:
①選擇菜單上的“工程”;
②在“工程”菜單中選擇“部件”;
③出現對話框后,在可勾選的項目中勾選Microsoft Comm Contro l6.0;
④按下“確定”按鈕,即可在工具箱中見到“電話盒”的圖標,就可以將此控件加載進行串行通信。
(2)MSComm屬性
MSComm屬性很多,其重要的屬性說明如下:
①CommPort:設定或返回通信端口號。端口號由1開始往上遞增,最大值是16。
②Settings:設定通信端口初始化參數。其格式為“Baud,P,D,S”,其中Baud為波特率, 可設為1200、2400、9600、14400、19200和28800等幾種;P為校驗位(E表示偶校驗、O表示奇校驗、M表示符號校驗(即在校驗位放置一個1的位)、S表示空白校驗(即在校驗位放置一個0的位)、N表示無校驗位(默認值));D為數據位數,可選值為4、5、6、7、8(默認值);S表示停止位數,可選值為1、1.5、2。
③PortOpen:設定並返回通信端口的狀態。
使用串行端口之前必須先打開該端口(PortOpen=True),而在使用完畢后必須關閉該端口(PortOpen=False)。
④Input:從輸入緩沖區返回並清除字符。這是一種FIFO(FirstinFirstOut)機制。如Buffer$=MSComm1.Input,表示將輸入緩沖區的字符讀入Buffer字符串變量中。
⑤Output:將一個字符或字符串寫入傳輸緩沖區,如MSComm1.Output=“ABCD”。此即將ABCD4個字符通過串行端口傳送出去。
⑥InBufferCount:傳回在接收緩沖區中的字符數,是指已接收,並在接收緩沖區等待讀取的字符數。
⑦InputMode:設定和返回類型。該屬性設為0時,數據通過Input屬性以文本方式取回,如設為1,則數據通過Input屬性以二進制方式取回。
VC基於MSCOMM控件串口通訊
在mfc中進行串口通訊最簡單的方法莫過於在對話框中使用MSCOMM控件了,MSComm通信控件提供了一系列標准通信命令的接口,它允許建立串口連接,可以連接到其他通信設備(如Modem).
還可以發送命令、進行數據交換以及監視和響應在通信過程中可能發生的各種錯誤和事件,從而可以用它創建全雙工 、事件驅動的、高效實用的通信程序。一、用MSComm控件通信
1.串口通信基礎知識
一般悅來,計算機都有一個或多個串行端口,它們依次為com1、Com2、…,這些串口還提供了外部設備與pC進行數據傳輸和
皿信的通道。這些串口在CPU和外設之間充當解釋器的角色。當字符數據從CPU發送給外設時,這些字符數據將被轉換成串行比特
流數據;當接收數據時,比特流數據被轉換為字符數據傳遞給CPU,再進一步說,在操作系統方面,Windows用通信驅動程序
(COMM.DRV)調用API函數發送和接收數據,當用通信控件或聲明調用API函數時,它門由COMM. DRV解釋並傳遞給設備驅動程序,
作為一個vB程序員,要編寫通信程序.只需知道通信控件提供給Windows通信AP1函數的接口即可.換句話說,只需設定和監視通
信控件的屬性和事件即可。
2.使用Mscomm控件
在開始使用MSComm控件之前。需要先了解其屬性、事件或錯誤
屬性 描述
CommPort 設置或返回通信端口號
Settings 以字符串的形式設置或返回波特率、奇偶校驗、數據位和停止位
PortOpen 設置或返回通信端口的狀態。也可以打開和關閉端口
Input 返回和刪除接收緩沖區中的字符
Output 將字符串寫入發送緩沖區
CommEvent屬性為通信事件或錯誤返回下列值之一。在該控件的對象庫中也可以找到這些常量。
常量 值 描述
ComEventBreak 1001 收到了斷開信號
ComEventCTSTO 1002 Clear To Send Timeout。在發送字符時,在系統指定的事1件內,CTS(Clear To Send)線是低電平
ComEventDSRTO 1003 Data Set Ready Timeout。在發送字符時,在系統指定的事件內,DSR(Data Set Ready)線是低電平
ComEventFrame 1004 數據幀錯誤。硬件檢測到一個數據幀錯誤
ComEventOverrun 1006 端口溢出。硬件中的字符尚未讀,下一個字符又到達,並且丟失
ComEventCDTO 1007 Carrier Detect Time。在發送字符時,在系統指定的事件內,CD(Carrier Detect)線是低電平。CD
也稱為RLSD(Receive Line Singal Detect,接收線信號檢測)
ComEventRxOver 1008 接收緩沖區溢出。在接收緩沖區中沒有空間
ComEventRxParity 1009 奇偶校驗錯。硬件檢測到奇偶校驗錯誤7
ComEventTxFull 1010 發送緩沖區滿。在對發送字符排隊時,發送緩沖區滿
ComEventDCB 1011 檢取端口DCB(Device Control Blick)時發生了沒有預料到的錯誤
通信事件包含了下面的設置:
常量 值 描述
ComEvSend 1 發送緩沖區中的字符數比Sthreshold值低
ComEvReceive 2 接收到了Rthreshold個字符。持續產生該事件,直到使用了Input屬性刪除了接收緩沖區中的數據
ComEvCTS 3 CTS(Clear To Send)線改變
ComEvDSR 4 DSR(Data Set Ready)線改變。當DSR從1到0改變時,該事件發生
ComEvCD 5 CD(Carrier Detect)線改變ComEvRing6檢測到響鈴信號。一些URAT(Universal AsynchronousReciver-
-Transmitters,通用異步收發器)不支持該事件
ComEvEOF 7 收到了EOF字符(ASCII字符26)
Error消息(MSComm控件)下表列出了MSComm控件可捕獲的錯誤消息:
常量 值 描述
ComInvalidPropertyValue 380 無效的屬性值
ComSetNotSupported 383 屬性只讀
ComGetNotSupported 394 屬性只讀
ComPortOpen 8000 端口打開時該存在無效
8001 超時設置必須比0值大
ComPortInvalid 8002 無效的端口號
8003 屬性只在運行時有效
8004 屬性在運行時是只讀的
ComPortAleadyOpen 8005 端口已經打開
8006 設備標識符無效或不支持
8007 不支持設備的波特率
8008 指定的字節大小無效
8009 缺省參數錯誤
8010 硬件不可用(被其他設備鎖住)
8011 函數不能分配隊列
ComNoOpen 8012 設備沒有打開
8013 設備已經打開
8014 不能使用通信通知
ComSetCommStateFailed 8015 不能設置通信狀態
8016 不能設置通信事件屏蔽
ComPortNotOpen 8018 該存在只在端口打開是有效
8019 設備忙
ComReadError 8020 通信設備讀錯誤
ComDCBError 8021 檢取端口設備控制塊時出現內部錯誤
注意在使用的時候一定要保證兩個通訊串口的設置是相同的,否則受到的信息將會產生錯誤!由於取值位數的不同,有可能發送的信息要讀很多次才能組合成需要的信息!1。建立mfc工程,都會撒。
將控件加進來:打開“Project->Add To Project->Components and Controls->Registered Activex Controls”,然后選擇控件:Microsoft Communication Control,version 6.0插入到當前的工程中。這樣就將類 CMSComm 的相關文件 mscomm.cpp 和 mscomm.h 一並加入到了工程中。編程時只需將控件對話中的 MSComm 控件拖至你的應用對話框中就OK了
2。定義串口對象:
CMSComm m_MSComm;
3。串口初始化:
DWORD style=WS_VISIBLE;
m_MSComm.Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM);
if(m_MSComm.GetPortOpen()) //如果串口是打開的,則行關閉串口
{
m_MSComm.SetPortOpen(FALSE);
}
m_MSComm.SetCommPort(1); //選擇COM1
m_MSComm.SetInBufferSize(1024); //接收緩沖區
m_MSComm.SetOutBufferSize(1024);//發送緩沖區
m_MSComm.SetInputLen(0);//設置當前接收區數據長度為0,表示全部讀取
m_MSComm.SetInputMode(1);//以二進制方式讀寫數據
m_MSComm.SetRThreshold(1);//接收緩沖區有1個及1個以上字符時,將引發接收數據的OnComm事件
m_MSComm.SetSettings("9600,n,8,1");//波特率9600無檢驗位,8個數據位,1個停止位
if(!m_MSComm.GetPortOpen())//如果串口沒有打開則打開
m_MSComm.SetPortOpen(TRUE);//打開串口
else
{
m_MSComm.SetOutBufferCount(0);
AfxMessageBox("Open The Serial Port 1 Failurre!");
}
4。串口數據讀寫:
MSComm 類的讀寫函數比較簡單:GetInput()和SetOutput()。函數原形分別為VARIANT GetInput()和void SetOutput(const VARIANT newValue),均使用VARIANT類型。但PC機發送和接收數據時習慣用字符串形式。MSDN中查閱VARIANT類型,可以用BSTR表示字符串,但所有的BSTR都包含寬字符,而只有Windows NT支持寬字符,Windows 9X並不支持。所以要完成一個適應各平台的串口應用程序必須解決這個問題。這里使用CbyteArray即可解決之。
發數據:在對話框對加入 按鈕 控件並給你添加消息
void CTest_mscommDlg::OnSend()
{
// TODO: Add your control notification handler code here
int i,Count;
CString m_SendData;
m_SendData="Hello!";
Count=m_SendData.GetLength();
CByteArray m_Array;
m_Array.RemoveAll();
m_Array.SetSize(Count);
for(i=0;i m_Array.SetAt(i,m_SendData[i]);
m_MSComm.SetOutput(COleVariant(m_Array));
}
收數據:給串口控件添加消息
void CTest_mscommDlg::OnOnCommMscomm()
{
VARIANT m_input;
char *str,*str1;
int k,nEvent,i;
CString str2,m_RcvData;
nEvent=m_MSComm.GetCommEvent();
switch(nEvent)
{
case 2:
k=m_MSComm.GetInBufferCount(); //接收緩沖區的字符數目
if(k>0)
{
m_input=m_MSComm.GetInput();
str=(char*)(unsigned char*)m_input.parray->pvData;
}
i=0;
str1=str;
while(i {
i++;
str1++;
}
*str1='\0';
str2=(const char*)str; //清除字符串中的不必要字符
m_RcvData=(const char *)str;
}
//數據顯示處理
m_disp+=m_RcvData;
UpdateData(false);
}
以上程序在vc6。0編譯通過,在2個pc機上測試通過。