(轉)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); //傳送資料
}
好了,這時此小串列埠程式就基本上完成了。