VS2012 MFC編程之串口通信上位機實現電壓採集(1)

       本節內容爲電腦串口通信上位機的編寫,使用MFC編寫串口通信上位機程序,主要是通過微軟提供的MSComm控件來編寫的。使用控件提供的API函數,編寫上位機較爲簡單,利於開發。本例程是基於電壓採集實驗完成的,下位機使用的是TI的C2000系列DSP TMS320F280049C,下位機將採集到的電壓數據通過串口發送給上位機上顯示,上位機中添加了TeeChart控件來顯示採集到的電壓波形。TeeChart控件的使用將會在後續的博客中講述,敬請關注。

(1)MSComm控件介紹

      MSComm控件的下載網址如下:https://download.csdn.net/download/fanxianyan1993/10990498

      MSComm控件的常用屬性如下所示:

CommPort: 設置和獲取當前的串口號  put_CommPort,get_CommPort函數
PortOpen: 打開或者關閉串口  put_PortOpen函數
Settings: 設置和獲取當前通信的數據格式  put_Settings,get_Settings函數

Input:

從接收緩衝區返回和刪除字符

Output:

向傳輸緩衝區寫一個字符串

     MSComm控件的常用函數的使用方式如下所示:

  1.  m_ctrlComm.get_PortOpen();    獲取當前端口的狀態。
  2.  m_ctrlComm.put_CommPort(BOOL newValue); 設置串口編號。
  3.  m_ctrlComm.put_PortOpen(TRUE); 打開串口。
  4.  m_ctrlComm.put_Settings(_T("460800,n,8,1"));設定串口的通信格式。
  5.  m_ctrlComm.put_InputMode(1); 0:以文本方式取回數據;1:以二進制方式檢取數據。
  6.  m_ctrlComm.put_RThreshold(1); 參數1表示每當串口接收緩衝區中有多於或等於1個字符時將引發一個接收數據的OnComm事件。
  7.  m_ctrlComm.put_InputLen(0); 設置當前接收區數據長度爲0。

(2)建立工程

        先創建基於對話框的MFC程序,在對話框中添加MSComm控件。在對話框界面上點擊右鍵,點擊插入ActiveX控件(X),再選擇Microsoft Communications Control,version 6.0(SP6)。這時對話框界面上就會出現一個電話的圖標,任意放個位置,程序運行後看不到該圖標。

(3)連接串口

        串口連接的程序如下所示,打開串口前先判斷串口是否已經被打開了,如果串口已經打開了,先關閉串口,再對串口進行操作。打開串口後再對串口進行配置,主要包括數據格式、輸入模式以及緩衝區的設置。

void CMFC_COM_Test02Dlg::OnBnClickedComOpen()
{
	if(nConnectFlag == 0)
	{
		if(m_ctrlComm.get_PortOpen())
			m_ctrlComm.put_PortOpen(FALSE);
		
		m_ctrlComm.put_CommPort(m_nCom+1);
		m_ComBo.SetCurSel(m_nCom);
		 
		if(!m_ctrlComm.get_PortOpen())
		{
			m_ctrlComm.put_PortOpen(TRUE);				//打開串口
//			AfxMessageBox(_T("打開串口成功!"));
			GetDlgItem(IDC_COM_OPEN) ->SetWindowText(_T("關閉串口"));
			nConnectFlag=1;
		}	
		else
			AfxMessageBox(_T("打開串口失敗!"));
		
		m_ctrlComm.put_Settings(_T("460800,n,8,1"));
		m_ctrlComm.put_InputMode(1); //1:表示以二進制方式檢取數據
		m_ctrlComm.put_RThreshold(1); 
		//參數1表示每當串口接收緩衝區中有多於或等於1個字符時將引發一個接收數據的OnComm事件
		m_ctrlComm.put_InputLen(0); //設置當前接收區數據長度爲0
		m_ctrlComm.get_Input();		//先預讀緩衝區以清除殘留數據
	}
	else
	{
		if(m_ctrlComm.get_PortOpen())
		{
			m_ctrlComm.put_PortOpen(FALSE);			//關閉串口
		}

		GetDlgItem(IDC_COM_OPEN) ->SetWindowText(_T("開啓串口"));
		nConnectFlag = 0;
		AfxMessageBox(_T("串口關閉成功!"));
	}	
}

(4)自動識別串口

       當電腦上插入了串口線後,需要上位機軟件選擇相應的串口號來打開串口。添加自動串口識別程序後,當電腦上接入了串口後,上位機軟件就能自動識別串口號。在MFC編程中,通過調用CreateFile函數打開串口,通過函數返回的句柄來判斷串口是否存在。串口識別的代碼需放在對話框初始化函數OnInitDialog()當中,這樣當打開串口時就能獲得有效的串口編號。串口識別的源代碼如下所示:

	HANDLE hComm;
	CString ComName[] = {_T("COM1"),_T("COM2"),_T("COM3"),_T("COM4"),
		_T("COM5"),_T("COM6"),_T("COM7"),_T("COM8"),_T("COM9")};

	for(int i=0;i<9;i++)
	{
		hComm =(HANDLE)CreateFile(ComName[i], GENERIC_READ | GENERIC_WRITE, 0, 
                                   NULL,OPEN_EXISTING, 0, NULL);

		if(hComm != INVALID_HANDLE_VALUE)		
		{
			m_nCom = i;
			m_ComBo.SetCurSel(m_nCom);
			CloseHandle(hComm);				//關閉句柄,不然出錯
			break;
		}
	}

(5)數據接收

       上位機接收數據時,需要添加消息響應函數來獲取串口發送的數據。鼠標右鍵點擊串口通信的控件,點擊添加事件處理程序,再點擊添加編輯後,編譯器就會添加消息處理函數OnCommMscomm()。

消息響應函數中主要通過get_Input()函數從緩衝區中讀取數據,數據接收的源代碼如下所示:

void CMFC_COM_Test02Dlg::OnCommMscomm()
{
	VARIANT variant_inp;
    COleSafeArray safearray_inp;
    LONG len,k;
    BYTE RxData[2048];				//設置BYTE數組 An 8-bit integerthat is not signed.
    CString strTemp;
	CString RX_Data;

    if(m_ctrlComm.get_CommEvent()==2)		//事件值爲2表示接收緩衝區內有字符
    {										//以下你可以根據自己的通信協議加入處理代碼
        variant_inp=m_ctrlComm.get_Input(); //讀緩衝區
        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(_T("%c"),bt);	//將字符送入臨時變量strtemp存放
			RX_Data += strTemp;
        }
		m_Voltage = RX_Data;
				
		if(nDisplayFlag)
		{
			m_chart.Series(0).AddXY(m_nCount,_ttoi(RX_Data),NULL,NULL);
			m_nCount++;
			if(m_nCount>=2000)
			{
				m_chart.Series(0).Clear();
				m_nCount=0;
			}
		}
    }
	UpdateData(FALSE); 
}

(6)發送數據

    上位機發送數據時,只需調用put_Output()即可。程序的源碼如下所示:

void CMFC_COM_Test01Dlg::OnBnClickedSend()
{
	UpdateData(TRUE);            //從控件上獲取數據

	CString strTxData;
	int nLen = m_RichEditRXData.GetTextLength();
	m_RichEditRXData.SetSel(0,nLen);
	strTxData = m_RichEditRXData.GetSelText();
	
	m_ctrlComm.put_Output(COleVariant(strTxData));
	m_TxNum++;

	UpdateData(FALSE); 
}

(7)上位機軟件

      最後,編寫的上位機軟件如下圖所示。下位機通過串口將採集到的電壓(圖中並非實際採集到的的電壓,而是下位機隨意發送的數據)發送給上位機,上位機再將電壓以波形的形式顯示出來。

程序源碼的下載地址爲:https://download.csdn.net/download/fanxianyan1993/10991289

 

提問方式:有啥不懂的可以隨時向我提問哈,掃描下方二維碼我會在第一時間給大家回覆的哈,謝謝。 

發佈了16 篇原創文章 · 獲贊 31 · 訪問量 8795
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章