轉自:吉翔的博客 http://jixiang1119.blog.163.com/blog/static/2827097320091283321941/
0 引言
隨着計算機網絡和多微機系統的廣泛應用,接口通信技術日益成爲當今一門非常重要的關鍵性技術。計算機與計算機以及其他設備的通信方式有串口通信,並口通信,USB通信和以太網通信等多種通信方式。儘管當今USB通信技術和以太網技術快速發展,然而串口通信技術始終以其連接簡便,價格低廉,穩定可靠等優點,在計算機通信領域佔有一席之地。MSComm控件是微軟公司爲了用戶使用方便,而提供的一種便捷的控制串口編程的解決方案,本文將利用VC++平臺詳細介紹VC++下利用MSComm控件的串行通信方法。
1 VC++下MSComm控件的串口編程簡介
1.1 MSComm控件串行通信處理方式
ActiveX是 Windows下進行應用程序開發的嶄新技術,它的核心內容是組件對象模型 COM (Component Object Model),ActiveX控件包括一系列的屬性、方法和事件 ,使用ActiveX控件的應用程序和 ActiveX控件之間的工作方式是客戶/服務器方式,即應用程序通過 ActiveX控件提供的接口來訪問 ActiveX控件的功能。Microsoft Communications Control (以下簡稱 MSComm)是 Microsoft 公司提供的簡化 Windows 下串行通信編程的ActiveX控件 ,它爲應用程序提供了通過串行接口收發數據的簡便方法。程序員不需要花時間去了解複雜的API函數,只需要利用MSComm控件就可實現串口編程。
MSComm控件提供了兩種處理通信問題的方法:一是事件驅動(Event-Driven)方法,二是查詢法。
1) 事件驅動方式
事件驅動方式是處理串行端口交互作用的一種非常有效的方法。使用事件驅動法設計程序時 ,每當有新字符到達或端口狀態改變 ,或發生錯誤時 ,MSComm 控件的OnComm事件捕獲並處理這些通信事件。而應用程序在捕獲該事件後,通過檢查 MSComm 控件的 CommEvent 屬性可以在OnComm事件處理函數中加入自己的處理代碼,這種方法由於程序響應及時可靠,在實際生活中經常使用。
2) 查詢方式
查詢的實質實際上仍然是事件驅動,這種方法應用程序每當執行完某一串行口操作後,將不斷的檢查CommEvent屬性的值來查詢事件或錯誤,如果應用程序較小,而且是自保持的,那麼這種方法可能比較可取。
1.2 MSComm 控件的屬性
MSComm控件有許多屬性,其中非常重要的幾個屬性如下:
CommPort :設置並返回通信端口號。
Setting:以字符串的形式設置並返回波特率,奇偶校驗位,數據位,停止位。
PortOpen:設置並反返回通信端口的狀態。也可以打開和關閉端口。
Input:從接收緩衝區返回和刪除字符
Output:向傳輸緩衝區寫一個字符
2 MSComm控件串口通信編程實例
2.1 創建串口通信程序工程MySCommTest
打開 Visual C + + 6. 0 集成開發環境 ,創建一個基於對話框的 MFC應用程序項目 ,命名爲MySCommTest,完成這一步後 ,選擇菜單項 Project/Add to Project/ Components and Controls,將彈出一個對話框,選擇 “Registered ActiveX Controls” 文件夾下的 “Microsoft Communications Control,version6.0”,再點擊“Insert”按鈕爲當前工程添加CMSComm類,並提示CMSComm類的頭文件爲MSComm.h,實現文件爲MSComm.cpp。點擊“ok”按鈕,再點擊“close”關閉對話框。這樣就爲當前工程添加了一個CMSComm類。同時在對話框編輯器裏的工具欄將出現 MSComm 控件圖標,形狀類似電話機, 這就是MSComm 控件,要在對話框中應用該控件,還需要將該控件用鼠標拖入對話框中,這個對話框就成了MSComm控件的容器或者說是“宿主”。同時還要在對話框中添加的控件有:兩個靜態文本控件IDC_STATIC(其標籤分別設爲“發送數據”和“接收數據”),兩個編輯框控件IDC_EDIT1和IDC_EDIT2,並分別爲其添加成員變量m_strEditTXData和m_strEditRXData。變量類型爲CString。一個按鈕控件IDC_BUTTON1,其標籤設爲“發送”。
2.2 串口初始化
右鍵點擊對話框,選擇ClassWizard->Member Variables頁,選中IDC_MSCOMM1控件,再點擊“Add Variable…”在CMySCommTestDlg類中爲串口控件添加CMSComm類的控制變量m_ctrlcomm。
在MySCommTestDlg::OnInitDialog( )函數中寫入對串口的初始化語句。通過串口初始化變量m_ctrlcomm來設置串口控件的屬性。
初始化代碼示例如下:
BOOL CMySCommTestDlg::OnInitDialog( )
{
。。。。
// TODO: Add extra initialization here
m_ctrlcomm.SetCommPort(1); //選擇com1
//波特率9600,無校驗,8個數據位,1個停止位
m_ctrlcomm.SetInputMode(1); //1表示輸入方式爲二進制輸入方式,0代表文本方式
m_ctrlcomm.SetInBufferSize(1024); // 設置輸入緩衝區大小
m_ctrlcomm.SetOutBufferSize(512); // 設置輸出緩衝區大小
//波特率9600,無校驗,8個數據位,1個停止位
m_ctrlcomm.SetSettings("9600,n,8,1");
if(!m_ctrlcomm.GetPortOpen())
m_ctrlcomm.SetPortOpen(TRUE); //打開端口
m_ctrlcomm.SetRThreshold(1); //1表示每當串口接收緩衝區中多餘或等於一個字符時將觸發OnComm事件
m_ctrlcomm.SetInputLen(0); //設置當前接收區數據長度爲0
m_ctrlcomm.GetInput(); // 先預讀緩衝區以清除殘留數據
return TRUE; // return TRUE unless you set the focus to a control
}
2.3 串口事件處理函數OnComm( )
MsComm控件一般用事件驅動方式從串口接收數據,事件驅動法完成對數據的監視和處理,有事件發生時或者出錯時通知應用程序,並在程序中捕捉並處理這些事件。
右擊對話框打開ClassWizard->Member Variables頁,選中IDC_MSCOMM1控件,然後在Message中雙擊OnComm,爲串口事件添加OnComm()消息處理函數。消息處理函數試對串口事件的處理,根據自身需要編寫,本例的消息處理函數OnComm()主要是從串口接收數據並顯示在接收數據編輯框中。
示例代碼爲:
void CMySCommTestDlg::OnComm() //使用MSComm控件的事件驅動方式接收串口數據
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
CString strtemp;
BYTE rxdata[2048]; //設置BYTE數組
if( m_ctrlcomm.GetCommEvent()==2) //事件值爲2表示接收緩衝區內有字符
{ variant_inp=m_ctrlcomm.GetInput(); //讀緩衝區
safearray_inp=variant_inp; //VARIANT變量轉化爲COleSafeArray變量
len=safearray_inp.GetOneDimSize(); //得到有效的數據長度
for( k=0;k<len;k++)
{
safearray_inp.GetElement(&k,rxdata+k); //轉換成BYTE型數組
}
for( k=0;k<len;k++) //將數組轉換成Cstring型的變量
{ BYTE bt=*(char*)(rxdata+k); //字符型
strtemp.Format("%c",bt); //將字符送入臨時變量
m_strEditRXData+=strtemp; //加入接收編輯框對應字符串
}
} UpdateData(FALSE); //更新編輯框內容
}
2.4 串口讀寫操作
在串口數據的發送和就收過程中都是使用的VARIANT數據類型,因此我們必須把CString字符串數據轉換成variant數據進行串口數據傳送。
同樣的方法爲按鈕IDC_BUTTON1添加處理函數BIN_CLICKED,並在函數中添加如下處理代碼:
void CMySCommTestDlg::OnButton1() //把CString字符串類型數據強制轉換爲variant類型數據從串口發送
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); //讀取編輯框內容
m_ctrlcomm.SetOutput(COleVariant(m_strEditTXData)); //發送數據
}
2.5 關閉串口
串口在進行數據處理完畢後,要關閉串口以釋放串口,即將PortOpen()的屬性設置爲FALSE。至此一個完整的串口通信程序完成了。並經過串口調試助手測試,程序順利運行。可以用文件的方法保存接收框的數據。添加一個“保存”按鈕,爲按鈕添加單擊事件,事件名爲OnSave用以保存接收數據
void CSCommTestDlg::OnSave()
{ FILE *fp;
if((fp=fopen("data.txt","w+"))==NULL)
exit(0);
fprintf(fp,m_strEditRXData);
fclose(fp);
}
3 結束語
本文詳細介紹了VC++下的MSComm控件編程方法,通過MSComm控件用戶可以十分便捷的寫出靈活性高,移植性強的串口通信程序,避免了去瞭解一些複雜的windows API函數。這種方法具有很強的實用性,可以廣泛的用於工業數據採集等領域。