DSP

VS2012 MFC编程之串口通信上位机实现电压采集(1)

2019-07-13 14:58发布

       本节内容为电脑串口通信上位机的编写,使用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=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