• c++串口上位机调试助手的总结和部分代码


    在初始化函数中添加:

     // TODO: Add extra initialization here

     m_bAutoSend=FALSE;  //m_bAutoSend为全局变量
     m_nCycleTime=1000;

     m_GPSCOM.SetCommPort(1);   //选择COM1
     m_GPSCOM.SetInputMode(1); //输入方式为二进制方式
     m_GPSCOM.SetInBufferSize(1024); //设置输入缓冲区大小
     m_GPSCOM.SetOutBufferSize(512); //设置输出缓冲区大小
    // m_GPSCOM.SetSettings("9600,n,8,1"); //波特率115200,无校验,8个数据位,1个停止位 
     if(m_GPSCOM.GetPortOpen())   //如果串口是打开的
       m_GPSCOM.SetPortOpen(FALSE);//则关闭串口

     //参数1表示每当串口接收缓冲区中有多于
     //或等于1个字符时将引发一个接收数据的OnComm事件
     m_GPSCOM.SetRThreshold(1); 
     m_GPSCOM.SetInputLen(0);  //设置当前接收区数据长度为0
     //m_GPSCOM.GetInput();    //先预读缓冲区以清除残留数据 

    显示接收到的内容

    m_RXDATA建立的变量是CEidtl类型,不是CString

    static long  RXcount=0;
    void CGPS_COM1Dlg::OnGPSCOM()           //编辑框接收函数——用于显示串口接收到的数据
    {
     // 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;
     CString strRXData;
      
     strRXData.Empty();
        if(m_GPSCOM.GetCommEvent()==2)     //事件值为2表示接收缓冲区内有字符
     {
      variant_inp=m_GPSCOM.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);      //字符型
       if(m_hexdisplay.GetCheck())
       {
        strtemp.Format("%02x ",bt);         //将十六进制送入临时变量strtemp存放
       }
       else
       {
        strtemp.Format("%c",bt);         //将字符送入临时变量strtemp存放
       }
       strRXData=strRXData+strtemp;    //加入接收编辑框对应字符串 
       
      }

      m_RXDATA.ReplaceSel(strRXData);
      
      RXcount=RXcount+len;
      CString rxdatacount;
      rxdatacount.Format("%ld",RXcount);
    //  rxdatacount="接收:"+rxdatacount;

      m_RXdatacount.SetWindowText(rxdatacount); //显示接收计数 
      
     }
    }

    //不用UpdateData(),这样写的好处就是当一直在接收时,也能自由发送而不受UpdateData()函数影响。

    串口打开或关闭

    void CGPS_COM1Dlg::OnButton1()     //串口打开或关闭
    {
     // TODO: Add your control notification handler code here
     if(m_ctrlAutoSend.GetCheck())
     {
      AfxMessageBox("请先关闭自动发送,才可以关闭串口");
     }
     else
     {
      
      if(!m_GPSCOM.GetPortOpen())
      {
       m_GPSCOM.SetPortOpen(TRUE);//打开串口
       SetDlgItemText(IDC_BUTTON1,"关闭串口");

      }
      else
      {
       m_GPSCOM.SetPortOpen(FALSE);//关闭串口
       SetDlgItemText(IDC_BUTTON1,"打开串口");
      }
     }
    }

     m_TXDATA建立的变量是CEidtl类型,不是CString

    long TX_count=0;
    void CGPS_COM1Dlg::OnButton2Tx()   //数据发送函数
    {
     // TODO: Add your control notification handler code here
     if(!m_GPSCOM.GetPortOpen())
     {
      AfxMessageBox("请先打开串口");
     }
     else
     {
      UpdateData(TRUE); //读取编辑框内容
      if(m_strHexSend.GetCheck())
      {
       CByteArray hexdata;
       int len=String2Hex(m_TXDATA,hexdata); //此处返回的len可以用于计算发送了多少个十六进制数
       m_GPSCOM.SetOutput(COleVariant(hexdata)); //发送十六进制数据
       TX_count+=(long) ((m_TXDATA.GetLength()+1)/3); //十六进制计数要注意算法
      }
      else 
      {
       m_GPSCOM.SetOutput(COleVariant(m_TXDATA));//发送ASCII字符数据
       TX_count+=m_TXDATA.GetLength();
      }
      CString strTemp;
      strTemp.Format("%d",TX_count);
      m_TXcount.SetWindowText(strTemp);
     }
    }

    void CGPS_COM1Dlg::OnButton3Clear()  //清除接收编辑框
    {
     // TODO: Add your control notification handler code here
     m_RXDATA.SetWindowText("");//清除接收对话框中的数据


    }

    void CGPS_COM1Dlg::OnCHECK1hexdisplay() 
    {
     // TODO: Add your control notification handler code here
     
    }


    void CGPS_COM1Dlg::OnCOMchose() 
    {
     // TODO: Add your control notification handler code here 
     char str[10];
     
     int iPos=m_COMChose.GetCurSel();
     int iNum=m_COMChose.GetLBText( iPos, (LPTSTR) str) ;
     int i=atoi(str+3);
     if(m_GPSCOM.GetPortOpen())
     {
      AfxMessageBox("请先关闭串口,再选择COM口");
     }
     if(!m_GPSCOM.GetPortOpen())
     {
      m_GPSCOM.SetCommPort(i);   //选择COM口

     }

    }

    void CGPS_COM1Dlg::OnHexSend() 
    {
     // TODO: Add your control notification handler code here


    }


    void CGPS_COM1Dlg::OnTimer(UINT nIDEvent) 
    {
     // TODO: Add your message handler code here and/or call default
     switch(nIDEvent)
     {
      case 1:  OnButton2Tx();
       break;
    /*  case 2:
       m_strCurPath.SetWindowText(m_strCurPath); //重新显示路径
       KillTimer(2);//关闭定时器

    */
      default:      ;
       break;
     
     }
     CDialog::OnTimer(nIDEvent);
    }

    void CGPS_COM1Dlg::OnCheck2_AutoSend() 
    {
     // TODO: Add your control notification handler code here
     
     m_bAutoSend=!m_bAutoSend;  //标志是否打开自动发送
     if(m_bAutoSend)
     {
      if(!m_GPSCOM.GetPortOpen())
      {
       m_bAutoSend=!m_bAutoSend;
       m_ctrlAutoSend.SetCheck(0);
       AfxMessageBox("串口没有打开,请打开串口");
       return;
      }
      else
       SetTimer(1,m_nCycleTime,NULL); //设置定时器1 m_nCycleTime
     }
     else
     {
      KillTimer(1);  //“杀”掉定时器1
     }
    }

    void CGPS_COM1Dlg::OnChangeEdit_CycleTime() 
    {
     // TODO: If this is a RICHEDIT control, the control will not
     // send this notification unless you override the CDialog::OnInitDialog()
     // function and call CRichEditCtrl().SetEventMask()
     // with the ENM_CHANGE flag ORed into the mask.
     
     // TODO: Add your control notification handler code here
     
     CEdit* pEdit=(CEdit*)GetDlgItem(IDC_EDIT1);
     CString strText;
     pEdit->GetWindowText(strText);
     m_nCycleTime=atoi(strText);


    }

    void CGPS_COM1Dlg::OnClearCount() 
    {
     // TODO: Add your control notification handler code here
     RXcount=0;  
     TX_count=0;
     m_RXdatacount.SetWindowText("");//清除接收对话框中的数据 
     m_TXcount.SetWindowText("");//清除接收对话框中的数据 
    }

    void CGPS_COM1Dlg::OnButtonSavedata() 
    {
     // TODO: Add your control notification handler code here
     UpdateData(TRUE);

     CFile m_rFile;
     LPCSTR lpszPath="c:\comdata";   //存盘路径为c:\comdata
     SetCurrentDirectory(lpszPath);

     CString  m_Filename,m_name1;
     m_name1=m_strFilename;   //填写的名字
     m_Filename=m_name1+".txt";  //以TXT格式存储
     if(0==m_strFilename.GetLength())
     {
      AfxMessageBox("请先输入保存的文件名");
     }
     else
     {
      if(!m_rFile.Open(m_Filename,CFile::modeCreate | CFile::modeWrite))
      {
       AfxMessageBox("创建记录文件失败!");
       return;
      }

      char TxtTemp[60000];   //字符串的长度
      int Maxsize=60000;    //
      int i=m_RXDATA.GetWindowText(TxtTemp,Maxsize);//将接受编辑框的数据取出放到数组TxtTemp中
      
      //在文件开始处写上保存日期
      CTime t=CTime::GetCurrentTime();
      CString str=t.Format("%Y年%m月%d日%H时%M分%S秒 ");
      m_rFile.Write((LPCTSTR)str,str.GetLength());
      //保存数据
      m_rFile.Write((LPCTSTR)TxtTemp,m_RXDATA.GetWindowTextLength());
      m_rFile.Flush(); 
      m_rFile.Close();  //关闭文件
      AfxMessageBox("保存成功");
      UpdateData(FALSE);
     }
    }

    在头文件中要声明这两个函数

      //由于这个转换函数的格式限制,在发送框中的十六制字符应该每两个字符之间插入一个空隔
      //如:A1 23 45 0B 00 29
      //CByteArray是一个动态字节数组,可参看MSDN帮助
    int CGPS_COM1Dlg::String2Hex(CString str, CByteArray &senddata)
    {
      int hexdata,lowhexdata;
      int hexdatalen=0;
      int len=str.GetLength();
      senddata.SetSize(len/2);
      for(int i=0;i<len;)
      {
       char lstr,hstr=str[i];
       if(hstr==' ')
       {
        i++;
        continue;
       }
       i++;
       if(i>=len)
       break;

       lstr=str[i];
       hexdata=ConvertHexChar(hstr);
       lowhexdata=ConvertHexChar(lstr);
       if((hexdata==16)||(lowhexdata==16))
        break;
       else 
        hexdata=hexdata*16+lowhexdata;
       i++;
       senddata[hexdatalen]=(char)hexdata;
       hexdatalen++;
      }
      senddata.SetSize(hexdatalen);
      return hexdatalen;
    }

      //这是一个将字符转换为相应的十六进制值的函数
      //好多C语言书上都可以找到
      //功能:若是在0-F之间的字符,则转换为相应的十六进制字符,否则返回-1
    char CGPS_COM1Dlg::ConvertHexChar(char ch) 
    {
      if((ch>='0')&&(ch<='9'))
       return ch-0x30;
      else if((ch>='A')&&(ch<='F'))
        return ch-'A'+10;
      else if((ch>='a')&&(ch<='f'))
        return ch-'a'+10;
      else return (-1);
    }

  • 相关阅读:
    2020年12月2日
    2020年12月1日
    2020年11月30日
    2020年11月29日
    2020年11月28日
    2020年11月27日
    2020年11月26日
    2020年11月25日
    浅谈扩展欧几里得算法
    Hello 2020
  • 原文地址:https://www.cnblogs.com/jack-jia-moonew/p/4178663.html
Copyright © 2020-2023  润新知