MFC 串口編程詳細教程 圖文並茂


 

http://blog.csdn.net/a_runing_man/article/details/9947343

 

本人之前從未接觸MFC編程,由於項目需要,所以上網查閱了相關資料,並實現了上位機串口通信。由於網上的資料還不夠詳細,本人決定寫一個圖文並茂的詳細教程。因為本人只是初學,如有錯誤,歡迎指點。

開發環境是:VC 6.0

串口編程方法:32位控件

參考資料:http://leadtheway.iteye.com/blog/705760

第一步:建工程

運行VC 6.0,文件-〉新建,選擇MFC AppWizard(exe) ,工程名稱:CommTest。確定

進入MFC應用程序向導-步驟1

選擇基本對話框,其他的都默認,所以可以直接點擊完成。

這樣工程就建立完畢。

第二步:控件布局與設置

工程建立后,出現如下對話框:

刪除上面的一個靜態文本和兩個按鈕。從控件工具欄拖入兩個靜態文本,兩個編輯框,兩個按鈕和一個組框。如果沒有控件工具欄,可以鼠標右鍵點擊菜單欄空白處,選擇控件。布局后的效果:

   

接下來開始設置顯示的文字和ID號。

選中按鈕1,右鍵-〉屬性。ID號設為IDC_BtnOpen,標題為打開。用於打開串口

選中按鈕2,右鍵-〉屬性。ID號設為IDC_BtnSend,標題為發送。用於發送數據。

選擇第一個編輯框,右鍵-〉屬性,更改ID為IDC_EditRxData,用於顯示接收的數據。

同理選擇第二個編輯框,更改ID為IDC_EditTxData。用於輸入待發送的數據。

分別選中靜態文本和組框,更改標題,不需要更改ID號。

最終效果如下:

現在先編譯運行一次,避免出現錯誤而影響到后面的操作。

接下來這一步是關鍵的一步:

在對話框中鼠標右鍵-〉選中插入ActiveX控件。選擇Microsoft Communication Control,ver......(后面的字母沒看到)。確定

這時出現了一個電話的控件,右鍵該控件-〉選擇類向導……,出現如下對話框:

先設置每個控件的變量,選擇Member Variables,選擇IDC_BtnOpen,然后Add Variable。

設置變量名為m_BtnOpen,名稱與ID號相似只是為了方便記憶,可隨便定義。其他默認。同理添加其他控件的變量,在添加MSCOMM1的變量時,會出現提示,選擇“是”。

添加完畢后:

變量添加完畢后選回Message Maps,選擇IDC_BtnOpen->BN_CLICKED->Add Function,默認函數名就好了,OK。

同理分別添加IDC_BtnSend->BN_CLICKED函數和IDC_MSCOMM1->OnComm函數。確定。

 

編譯運行,避免有錯誤。如果出錯,詳細檢查有沒有誤操作。一般不會出錯的。

 

第三步:添加代碼

選擇左邊信息欄的File View,雙擊打開CommTestDlg.cpp,在文件尾部可以看到剛剛添加的三個函數。

在OnBtnOpen()函數添加代碼:

void CCommTestDlg::OnBtnOpen() 
{
// TODO: Add your control notification handler code here
if(m_Comm1.GetPortOpen())
m_Comm1.SetPortOpen(FALSE);

m_Comm1.SetCommPort(1); //選擇com1,可根據具體情況更改
m_Comm1.SetInBufferSize(1024); //設置輸入緩沖區的大小,Bytes
m_Comm1.SetOutBufferSize(1024); //設置輸入緩沖區的大小,Bytes//
m_Comm1.SetSettings("9600,n,8,1"); //波特率9600,無校驗,8個數據位,1個停止位
m_Comm1.SetInputMode(1); //1:表示以二進制方式檢取數據
m_Comm1.SetRThreshold(1); 
//參數1表示每當串口接收緩沖區中有多於或等於1個字符時將引發一個接收數據的OnComm事件
m_Comm1.SetInputLen(0); //設置當前接收區數據長度為0
if( !m_Comm1.GetPortOpen())
m_Comm1.SetPortOpen(TRUE);//打開串口
else
AfxMessageBox("cannot open serial port");
m_Comm1.GetInput();//先預讀緩沖區以清除殘留數據
UpdateData(false);
}

編譯運行。

 

在OnOnCommMscomm1()函數添加代碼:

void CCommTestDlg::OnOnCommMscomm1() 
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
    COleSafeArray safearray_inp;
    LONG len,k;
    BYTE rxdata[2048]; //設置BYTE數組 An 8-bit integerthat is not signed.
    CString strtemp;
    if(m_Comm1.GetCommEvent()==2) //事件值為2表示接收緩沖區內有字符
    {             ////////以下你可以根據自己的通信協議加入處理代碼
        variant_inp=m_Comm1.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); //將字符送入臨時變量strtemp存放
            m_EditRxData+=strtemp; //加入接收編輯框對應字符串 
        }
    }
    //UpdateData(FALSE); //更新編輯框內容
SetDlgItemText(IDC_EditRxData,m_EditRxData);//不使用UpdateData(FALSE);的原因是該函數會
//刷新整個對話框的數據,而SetDlgItemText()
//只更新接收編輯框的數據。
}

 

現在可以接上串口做測試了。我是用單片機做串口發送,上位機做串口接收。單片機持續發送字符' D '.上位機正常接收:

 

接着添加發送功能,

void CCommTestDlg::OnBtnSend() 
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); //讀取編輯框內容
m_Comm1.SetOutput(COleVariant(m_EditTxData));//發送數據
}

發送大寫字母N,在單片機用LED顯示。‘N’對應的ASCII碼的二進制是0100 1110。實物結果如圖:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM