1. 程式人生 > >(轉)VC串列埠小程式(用SerialPort類)

(轉)VC串列埠小程式(用SerialPort類)

×××××××××××××××××××××××××××××××××××××××××××××××××××××

在MFC裡面實現串列埠通訊有很多方式:

方案一:使用微軟公司提供的 串列埠類,SerialPort。這是官方的東西   有最大的靈活性和可靠性。  我的主攻選擇為這個。

微軟資源地址:https://msdn.microsoft.com/zh-cn/library/system.io.ports.serialport(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1

 

方案二:MSComm控制元件  。使用這種控制元件 就可以了。。。 不過MFC沒有自帶,需要新增。

 

方案三:API函式進行串列埠程式設計。  這種方式  也很好  就是難道較大。

×××

有個哥們整理了這些資料:http://www.vc-rs232.com/   我看了下  還是蠻好的。。

××××××××××××××××××××××××××××××××××××××××××××××××××××

先建立一個基於對話方塊的小程式,做好介面有串列埠號,開啟串列埠按鈕,關閉串列埠按鈕,傳送按鈕,接收資料區和傳送資料區。

然後給串列埠號即組合框新增變數 CComboBox m_ctrlComPort;

給接收資料編輯框新增關聯變數 CString m_strRxMsg;

給傳送資料編輯框新增關聯變數 CString m_strTxMsg;

然後將SerialPort類的標頭檔案和C++檔案複製到工程中區,然後將它們新增到工程中去,將SerialPort的標頭檔案包含到對話方塊中檔案中去。

在對話方塊標頭檔案中定義一個布林變數,用來表示標誌串列埠是否開啟,再定義一個物件用來呼叫SerialPort類中的函式。

原始碼 BOOL m_bPortOpen;  //定義一個布林變數標誌串列埠是否開啟;

CSerialPort m_SerialPort;  //定義一個串列埠類的物件。

然後開始編輯程式碼,在SerialPort類中有多個串列埠事件可以響應,在一般串列埠程式設計中,只需要處理WM_COMM_RXCHAR訊息就可以了,該類所有的訊息處理都需要人工新增訊息處理函式。

將處理函式名字定義為OnComm()。首先向對話方塊標頭檔案中新增串列埠字元接收訊息WM_COMM_RXCHAR(串列埠接收緩衝區中有一個字元)的訊息響應宣告: 

// Generated message map functions
 //{{AFX_MSG(CSmSerialPortDlg)
 afx_msg LONG OnComm(WPARAM ch,LPARAM port);   //串列埠字元接收訊息(WM_ONCOMM_RXCHAR)(串列埠接收緩衝區內有一個字元)的響應函式

然後再向對話方塊CPP檔案中新增WM_ONCOMM_RXCHAR的訊息對映

BEGIN_MESSAGE_MAP(CSmSerialPortDlg, CDialog)
 //{{AFX_MSG_MAP(CSmSerialPortDlg)
 ON_MESSAGE(WM_COMM_RXCHAR, OnComm)  //訊息對映

接著,在對話方塊CPP檔案中加入函式OnComm()的實現

//字元接收訊息響應函式
LONG CSmSerialPortDlg::OnComm(WPARAM ch,LPARAM port)
{
 m_strRxMsg+=ch; //將接收到的字元存入編輯框對應的變數中
 UpdateData(FALSE);  //將接收到的字元顯示在接受編輯框中
 return 0;
}

每當串列埠接收緩衝區中有一個字元時,就會產生一個WM_ONCOMM_RXCHAR訊息,觸發OnComm()函式,這時就可以在函式中進行資料處理,所以這個訊息就是整個程式的發動機。

在CSmSerialPortDlg::OnInitDialog()初始化函式中將串列埠預設設定為COM1; m_ctrlComPort.SetCurSel(0); //初始選擇串列埠1

新增 

GetDlgItem(IDC_BUTTON_OPENPORT)->EnableWindow(!m_bPortOpen);
 GetDlgItem(IDC_BUTTON_CLOSEPORT)->EnableWindow(m_bPortOpen);

使能開啟串列埠或關閉串列埠按鈕。

新增開啟串列埠,關閉串列埠和傳送按鈕的訊息響應處理函式如下:

void CSmSerialPortDlg::OnButtonCloseport()   //關閉串列埠按鈕訊息響應函式
{
 // TODO: Add your control notification handler code here
  
 m_bPortOpen=FALSE;

 GetDlgItem(IDC_BUTTON_OPENPORT)->EnableWindow(!m_bPortOpen);
 GetDlgItem(IDC_BUTTON_CLOSEPORT)->EnableWindow(m_bPortOpen);
}

void CSmSerialPortDlg::OnButtonOpenport()  //開啟串列埠按鈕訊息響應函式
{
 // TODO: Add your control notification handler code here
 
 int nPort=m_ctrlComPort.GetCurSel()+1;   //得到串列埠號
 if(m_SerialPort.InitPort(this,nPort,9600,'N',8,1,EV_RXFLAG | EV_RXCHAR,512))
 {
  m_SerialPort.StartMonitoring();  //啟動串列埠通訊檢測執行緒函式
  m_bPortOpen=TRUE;
 }
 else
 {
  AfxMessageBox("沒有發現此串列埠或者被佔用");
  m_bPortOpen=FALSE;
 }
 GetDlgItem(IDC_BUTTON_OPENPORT)->EnableWindow(!m_bPortOpen);
 GetDlgItem(IDC_BUTTON_CLOSEPORT)->EnableWindow(m_bPortOpen);
}

void CSmSerialPortDlg::OnButtonSend() 
{
 // TODO: Add your control notification handler code here
 if(!m_bPortOpen)
 return ;      //檢測串列埠是否開啟
 UpdateData(TRUE);     //讀入編輯框的資料
 m_SerialPort.WriteToPort((LPCTSTR)m_strTxMsg);  //傳送資料
}
好了,這時此小串列埠程式就基本上完成了。