串口以CString型输出16进制,不能输出80,即10进制的128以上的数,这是为什么?????

解决方案 »

  1.   

    估计你用WriteFile写串口的,而打开的时候,是以文本格式打开的。 应该用二进制格式打开,并且直接写CString的buffer!!
      

  2.   

    BOOL CCardDlg::OnInitDialog()
    {
    CDialog::OnInitDialog(); // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE); // Set big icon
    SetIcon(m_hIcon, FALSE); // Set small icon
    CString strTemp;
    int iCount=((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCount(); //取得目前已经有的行数
    if(iCount<1)//防止重复多次添加
    {
    ((CComboBox*)GetDlgItem(IDC_COMBO1))->ResetContent();
    for(int i=1;i<=100;i++)
    {
    strTemp.Format("%d",i);
    ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString(strTemp);
    }
    }
    int iPos=((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel(); 
    ((CComboBox*)GetDlgItem(IDC_COMBO1))->GetWindowText(strTemp); //将获取的值存放到CString类型变量strTemp中。 
    ((CComboBox*)GetDlgItem(IDC_COMBO1))->GetLBText(1,strTemp);  //其中n为从0开始的索引值 
    ((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel(); //返回的是当前选中值的行数,是整型。
    ((CComboBox*)GetDlgItem(IDC_COMBO1))->SetCurSel(1); //设置第n行内容为显示的内容。
    // TODO: Add extra initialization here
    if(m_mscomm.GetPortOpen())
    m_mscomm.SetPortOpen(false);
    m_mscomm.SetCommPort(1);
    if(!m_mscomm.GetPortOpen()) //打开串口
      {
            m_mscomm.SetPortOpen(true); 
      }
    else
    AfxMessageBox("cannot open serial port!!");      m_mscomm.SetInputMode(1); //设置输入方式为二进制方式 
          if(!m_mscomm.GetPortOpen()) //打开串口
      {
            m_mscomm.SetPortOpen(true); 
      }
                m_mscomm.SetSettings("9600,n,8,1"); //设置波特率等参数 
          m_mscomm.SetRThreshold(1); //为1表示有一个字符即引发事件
    //   m_mscomm.SetInputModel(1);//1:表示以二进制方式捡取数据
          m_mscomm.SetInputLen(0);//设置当前接收区数据长度为0
          m_mscomm.GetInput();//先预读缓冲区以清除残留数据
       return TRUE;  // return TRUE  unless you set the focus to a control
    }
    void CCardDlg::OnOnCommMscomm1() 
    {
    // TODO: Add your control notification handler code here
    VARIANT variant_inp;
       COleSafeArray safearray_inp;
       CString strtemp;
       long len,i;
       //char head;
       BYTE rxdData[2048];
       //char dataon='Z';    if (m_mscomm.GetCommEvent()==2)    ////事件值为2表示接收缓冲区内有字符
       {
       m_cmdsend.Empty();
       variant_inp=m_mscomm.GetInput();   ////读缓冲区
       safearray_inp=variant_inp;           //VARIANT型变量转换为ColeSafeArray型变量
       len=safearray_inp.GetOneDimSize();    ////得到有效数据长度
              
       //i=0;
       for(i=0;i<len;i++)
    safearray_inp.GetElement(&i,&rxdData);//转换为BYTE型
       for(i=0;i<len;i++)     //将数组转换为CString型变量
       {
       char bt=*(char*)(rxdData+i);//字符型
       strtemp.Format("%c",bt);//将字符送入临时变量strtemp存放
      //m_cmdsend+=strtemp;//加入接收编辑框对应字符串
       }
    UpdateData(false);//更新编辑框内容
       }}void CCardDlg::OnEditchangeCombo1() 
    {

    }
    BOOL CCardDlg::SetPort(int com,int rate, int stop,int bit,char xor)
    {
    char   szSetting[256];   
    memset(szSetting,0,256); 
    sprintf(szSetting,"%d,%c,%d,%d",rate,xor,bit,stop);
    if(m_mscomm.GetPortOpen())
    {
    m_mscomm.SetPortOpen(FALSE);
    } m_mscomm.SetCommPort(m_com); //选择com
    if( !m_mscomm.GetPortOpen())
    {
    m_mscomm.SetPortOpen(TRUE);//打开串口
    }
    else
    {
    AfxMessageBox("cannot open serial port");
    } m_mscomm.SetSettings((LPCTSTR)szSetting); //波特率rate,校验xor,数据位bit,停止位stop
    m_mscomm.SetInputMode(1); //1:表示以二进制方式检取数据
    m_mscomm.SetRThreshold(1); //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
    m_mscomm.SetInputLen(0); //设置当前接收区数据长度为0
    m_mscomm.GetInput();//先预读缓冲区以清除残留数据
    return TRUE;}void CCardDlg::OnSelchangeCombo1() 
    {
    // TODO: Add your control notification handler code here
    // TODO: Add your control notification handler code here
    CString temp;
    int nIndex;
    nIndex=m_boxcom.GetCurSel();
    m_boxcom.GetLBText(nIndex , temp);
    int k=temp.Find("M",0); //寻找得到字符串中的"M"
    temp=temp.Right(temp.GetLength()-k-1);//得到字符串中"M"右边的字符串
    m_com=atoi(temp);//atoi将右边的字符串转换为int 即串口号
    BOOL ans=SetPort(m_com,19200,1,8,'n');//设置串口
    if(!ans)
    {
    AfxMessageBox("不能打开串口!");
    }
    else if(ans)
        {  temp.Empty(); 
             temp.Format("%d",m_com);
         // ::WritePrivateProfileString("Info","COM",temp,"e:\\VC\\VC程序\\SUNSI\\student.ini"); 
      m_cmdsend.Empty();         //清空命令
          //  m_cmdsend+='z';            //命令头
               m_mscomm.SetOutput(COleVariant(m_cmdsend));     //发送 
    }
    }void CCardDlg::OnButton1() 
    {
    // TODO: Add your control notification handler code here
    m_cmdsend.Empty(); m_cmdsend+=m_num;//加入接收编辑框对应数字
       
        m_cmdsend+=252;

        m_cmdsend+=81;

    m_cmdsend+=172;//m_cmdsend+=172;
    //    strcpy(m_cmdsend1,m_cmdsend);
    m_mscomm.SetOutput(COleVariant(m_cmdsend));
    // m_mscomm.SetOutput(COleVariant(m_cmdsend1));
    // m_mscomm.SetOutput(COleVariant(m_cmdsend2));
    // m_mscomm.SetOutput(COleVariant(m_cmdsend3));
    }void CCardDlg::OnButton2() 
    {
    // TODO: Add your control notification handler code here

    }void CCardDlg::OnButton3() 
    {
    // TODO: Add your control notification handler code here

    }void CCardDlg::OnButton4() 
    {
    // TODO: Add your control notification handler code here

    }void CCardDlg::OnButton5() 
    {
    // TODO: Add your control notification handler code here

    }void CCardDlg::OnChangeNum() 
    {
    // 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.
    UpdateData(true);
    // TODO: Add your control notification handler code here

    }
    zh
      

  3.   

    先按 #3 楼的说法做做看吧,应该没什么别的问题。
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
      

  4.   

    用什么 先把16进制放到 char数组里 在转化成CString 这样应该比较好吧
      

  5.   

    我用了7楼的方法,先把16进制的数给char型数组,再转化成CString,还是很原来一样最后一位还是显示3F,我想显示的是01 FC 51 AC
    现在输出01 FC 51 3F
      

  6.   

    m_mscomm 是什么类型的对象?SetOutput() 函数是你自己写的吗?函数原型是什么?如果 SetOutput() 是你自己写的,那么就要参考 #3 楼的说法了。如果不是你自己写的,那请给出函数原型,大家才能帮你分析该如何传入参数。
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
      

  7.   

    void CMSComm::SetOutput(const VARIANT& newValue)
    {
    static BYTE parms[] =
    VTS_VARIANT;
    InvokeHelper(0x19, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
     &newValue);
    }
    这是函数原型
      

  8.   

    这样啊……那你就得考察 CMSComm 这个 COM 对象的接口文档了。这个 COM 对象是哪里来的?你看一下它的 0x19 属性接口,能接受什么样的入口参数。如果能接受 BYTE × 类型就简单了,你传给它什么它就是什么。像你现在这样传一个 BSTR 给它,它内部也要转换成 BYTE *,因为串口在物理上是 BYTE 型的。而转换过程中就可能出现你所描述的问题,这取决于这个 COM 的内部实现。
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
      

  9.   

    我该了如下代码,还是显示不对,但是数组再多加个输出的数,输出就又正确了,很奇怪、、、、、、
    void CharToStr(char* buf,int len,CString &str)
    {
     str = "";
     for(int i=0;i<len;i++)
     {
      str+= buf[i];
     }
     
    }
    void CCardDlg::OnButton1() 
    {
    // TODO: Add your control notification handler code here
    m_cmdsend.Empty(); m_cmdsend1[0]=m_num;//加入接收编辑框对应数字
       
        m_cmdsend1[1]=0xFC;

        m_cmdsend1[2]=0x51;

    m_cmdsend1[3]=m_cmdsend1[0]^m_cmdsend1[1]^m_cmdsend1[2];
        
    CharToStr(m_cmdsend1,4,m_cmdsend);

    //m_cmdsend+=172;
    //    strcpy(m_cmdsend1,m_cmdsend);
    m_mscomm.SetOutput(COleVariant(m_cmdsend));
    // m_mscomm.SetOutput(COleVariant(m_cmdsend1));
    // m_mscomm.SetOutput(COleVariant(m_cmdsend2));
    // m_mscomm.SetOutput(COleVariant(m_cmdsend3));
    }
      

  10.   

    COM的内部实现是没有办法直接“看”到的,你只能读它的接口文档(如果有的话)。看来我还是直接给你写代码好了:CByteArray cmdsend;
    cmdsend.Add( m_num );
    cmdsend.Add( 0xFC );
    cmdsend.Add( 0x51 );
    cmdsend.Add( m_num ^ 0xFC ^ 0x51 );
    m_mscomm.SetOutput( COleVariant( cmdsend ) );
      

  11.   

    如果你有那个 COM 对象源代码的话(注意不是 CMSComm,这只是一个包装类),读一下它的 0x19 属性接口的实现代码,应该就能找到原因了。因为它是要把数据写到串口,所以一定要转换成 BYTE 序列的形式。如果你提供的是 CByteArray 的数据(就像上面说的),就不会有什么问题;而如果你提供的是 BSTR 形式的数据(就是你原来程序的样子),那它就要先转换成 BYTE 序列,但“把 WBCS 字符串转换成 BYTE 序列”这件事,对于源字符串是有合法性要求的,如果你的源字符串中包含非法字符,就会被替换成“万能字符”,也就是那个 0x3f。
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)