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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章