在mfc中進行串口通訊最簡單的方法莫過于在對話框中使用MSCOMM控件了,MSComm通信控件提供了一系列標準通信命令的接口,它允許建立串口連接,可以連接到其他通信設備(如Modem).還可以發送命令、進行數據交換以及監視和響應在通信過程中可能發生的各種錯誤和事件,從而可以用它創建全雙工 、事件驅動的、高效實用的通信程序。
## 一、用MSComm控件通信
1.串口通信基礎知識
一般悅來,計算機都有一個或多個串行端口,它們依次為com1、Com2、…,這些串口還提供了外部設備與pC進行數據傳輸和通信的通道。這些串口在CPU和外設之間充當解釋器的角色。當字符數據從CPU發送給外設時,這些字符數據將被轉換成串行比特流數據;當接收數據時,比特流數據被轉換為字符數據傳遞給CPU,再進一步說,在操作系統方面,Windows用通信驅動程序(COMM.DRV)調用API函數發送和接收數據,當用通信控件或聲明調用API函數時,它門由COMM. DRV解釋并傳遞給設備驅動程序,作為一個程序員,要編寫通信程序.只需知道通信控件提供給Windows通信AP1函數的接口即可.換句話說,只需設定和監視通信控件的屬性和事件即可。
2.使用Mscomm控件
**在開始使用MSComm控件之前。需要先了解其屬性、事件或錯誤**
屬性??????????????? 描述
CommPort?????? 設置或返回通信端口號
Settings????????? 以字符串的形式設置或返回波特率、奇偶校驗、數據位和停止位
PortOpen??????? 設置或返回通信端口的狀態。也可以打開和關閉端口
Input?????????????? 返回和刪除接收緩沖區中的字符
Output??????????? 將字符串寫入發送緩沖區
**CommEvent屬性為通信事件或錯誤返回下列值之一。在該控件的對象庫中也可以找到這些常量。**
常量????????????????????????? 值??????????????? 描述
ComEventBreak??????? 1001?????????? 收到了斷開信號
ComEventCTSTO????? 1002?????????? Clear To Send Timeout。在發送字符時,在系統指定的事1件內,CTS(Clear To end)線是低電平
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=’{post.content}’;
str2=(const char*)str;????????????? //清除字符串中的不必要字符
m_RcvData=(const char *)str;
}
//數據顯示處理
m_disp+=m_RcvData;
UpdateData(false);
}
~~~