日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

VC基于MSCOMM控件串口通讯

發布時間:2025/3/21 c/c++ 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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='{post.content}';??????????????????????????????
?? str2=(const char*)str;????????????? //清除字符串中的不必要字符
?? m_RcvData=(const char *)str;
}
//數據顯示處理

m_disp+=m_RcvData;

UpdateData(false);



}

=====================================
摘要:本文介紹了在Microsoft Visual C++ 6.0環境下通過對Active X控件的編程來實現串口的通信的一般方法。

   一、 引言

   當我們在Windows操作系統下開發串行通信程序時通常不得不面對許多復雜的API函數,因為在Windows操作系統下不能直接對設備端口進行操作,也不能在系統級(Ring 3級別)使用任何DOS或BIOS中斷,如要對端口進行編程則只能以文件的形式來對端口進行操作,這就使開發人員不得不面對非常煩瑣的API函數編程。本文對此提出了另外一種封裝性很好的使用Microsoft Visual C++ 6.0自帶的"Microsoft Communications Control,version 6.0"Active X控件的編程方法,通過對該控件的正確使用,我們可以比較輕松地編寫出所需的串行通信程序。

   下面,我們將結合一個實際的程序示例來對此方法進行說明。本程序的編程環境是Windows 98和Microsoft Visual C++ 6.0。在本程序示例中對為避免阻塞而對線程的使用以及在使用中遇到的一些問題也做了詳細的介紹。

   二、 程序的設計實現

   在開始進行代碼編程前,首先以在工程中插入組件或控件的方式將Active X控件"Microsoft Communications Control,version 6.0"加入到工程中來,此時將會在工程中添加一個關于此控件的新類。使用該控件的一些方法和屬性時不能象使用類一樣簡單的聲明一個實例對象,而要通ClassWizard為該控件和一個成員變量建立起綁定關系,在此我們將該控件同變量m_Comm相綁定后就可以通過該控件提供的方法來對串口的各種通訊參數進行設置了。為了編程方便起見,也可以在資源視圖中直接對該控件的屬性進行設置,如無特別要求,對下表所列屬性進行設置就基本可以滿足編程要求了。現將常用的屬性列表如下:


屬性 設定值 屬性說明
CommPort 1 串口號,一般從1到4
InBufferSize 30720 接收緩沖區大小,為保持程序的穩定,建議設得值足夠大
InputMode 0-Text 接收數據的類型,0表示文本類型,1表示二進制類型
InputLen 0 從接收緩沖區讀取的字節數,0表示全部讀取
OutBufferSize 512 發送緩沖區大小
Settings 4800,n,8,1 串口的參數設置,依次為波特率、奇偶校驗(n-無校驗,e-偶校驗,o-奇校驗)、數據位數、停止位數
RThreshold 1 設定當接收幾個字符時觸發OnComm事件,0表示不產生事件,
1表示每接收一個字符就產生一個事件
SThreshold 0 設定在觸發OnComm事件前,發送緩沖區內所允許的最少的字符數,
0表示發送數據時不產生事件,1表示當發送緩沖區空時產生OnComm事件


   我們要求能在程序啟動的同時就打開串口以便即時對從串口到達的數據進行接收、處理。一般來說可以將下面的打開端口的代碼寫在OnCreate()、OnInitialUpdate()、InitInstance ()等程序入口函數中:

……
if(!m_Comm.GetPortOpen()) //檢測是否已經打開過端口
m_Comm.SetPortOpen(TRUE); //如沒有打開則將端口打開
……
接下來的工作就是對數據的發送與接收了,這也是本文所要介紹的重點所在。發送數據的代碼原則上是可以寫到一個成員函數中被直接調用的,但這并不是一個良好的編程習慣:我們應當把比較耗時的操作,如文件拷貝、打印、端口傳輸等工作放到一個單獨的線程當中,以避免其在工作時會引起整個進程的阻塞,以提高整個系統對CPU的利用率。例如我們可以在視類中菜單或按鈕的響應函數中用AfxBeginThread(WriteProc,this)函數來開啟一個名為"WriteProc"的線程,由于在線程中還需要使用視類的函數和變量,為了不產生新的視類的實例對象,我們通過該函數的第二個參數將指向當前的視類的指針this作為參數傳遞給線程。在線程中可以用如下兩種方法之中的一種調用視類的成員函數:

((COLECommView*) pParam)->DoSendProc();

   或是:

COLECommView* view=(COLECommView*) pParam;
View->DoSendProc();


   其中從pParam傳來的變量就是指向視類的指針。在線程中通過調用視類中的DoSendProc函數來完成對數據的發送,正是由于該函數是被全局的線程所調用的,我們就不可以使用取編輯框上的數據時通常所用的UpdateData()函數了,取而帶之的是API 函數GetDlgItemText(),取到輸入的數據后通過控件的SetOutput() 方法就把數據從串口發出去了,其中發送數據必須經ColeVariant類將其轉換為通用的VARIANT型變量。實現
主要代碼如下:

……
char a[255];
HWND hwnd=GetSafeHwnd();
::GetDlgItemText(hwnd,IDC_ED99v1,a,255);
int i=0;
CString str;
while(a[i]!='{post.content}')
{
str.Format("%c",a[i]);
m_SendData+=str;
i++;
}
str.Format("%c",10);
m_SendData+=str;
m_Comm.SetOutput(COleVariant(m_SendData));
……

   至于數據的接收,我們可以通過讓MS Comm控件響應其OnComm事件來完成,通過ClassWizard加入其對事件的響應后,通過下面的事件映射,當有字符到達時便會通知 OnComm()函數去處理,從而實現數據的異步接收:

……
BEGIN_EVENTSINK_MAP(COLECommView, CFormView)
//{{AFX_EVENTSINK_MAP(COLECommView)
ON_EVENT(COLECommView, IDC_MSCOMM1, 1 /* OnComm */, OnComm, VTS_NONE)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
……
void COLECommView::OnComm()
{
VARIANT Input;
if(m_Comm.GetCommEvent()==2)//接收緩沖區內有字符
{
Input=m_Comm.GetInput();//讀取緩沖區內的數據
CString msg=Input.bstrVal;
CString str;
str.Format("%c",10);
if(msg.Right(1)==str)
{
m_RecvData+=msg;
m_History.AddString(m_RecvData);
m_RecvData="";
}
else
m_RecvData+=msg;
}
}


   當數據被接收到接收緩沖區后,對于字符可以從VARIANT型結構變量的bstrVal成員變量中獲取,VARIANT數據結構相當復雜,并牽扯到COM(Component Object Model,組件對象模型)中的一些概念,具體詳情請參閱Microsoft Corpration發布的Msdn


總結

以上是生活随笔為你收集整理的VC基于MSCOMM控件串口通讯的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。