本帖最后由 oyljerry 于 2011-06-24 14:46:13 编辑

解决方案 »

  1.   

     接收到的波长数据99%,绝大部分显示,作图都是正常的,但是有时候波长会出现少量负数,而且有时候接收到的FBG数量不正常,。
    -------------------
    接收端解析的问题还是发送端的问题?
      

  2.   

    请各位帮我看一下。字节顺序是正确的,接收端解析。
    主要的应该就是解析,或者使用内存拷贝函数转化成浮点数的地方出了问题。
    功能:串口解析命令,接收ARM板发过来的波长4字节16进制数据,然后把它转成浮点数,最后将浮点数的波长动态作图显示出来。出现问题: 接收到的波长数据99%,绝大部分显示,作图都是正常的,但是有时候波长会出现少量负数,而且有时候接收到的FBG数量不正常,。问题分析:有可能2个原因:
    1.接收数据本身的问题。
    2.4字节16进制数,转化成浮点数的问题。协议说明:
    命令名称 帧头 命令类型 长度字节 命令数据
    发送波长数据 FE+FE A2 依据FBG数量而定 波长数据
       
      波长数据:增益及光开关通道(1字节)+FBG数量(1字节)+波长数据(四字节32位浮点数),其中“增益及光开关通道”字节 的最高位“1”表示高增益,“0”表示低增益,低五位表示当前光开关通道。
      请各位大侠,高手给我帮忙,看一下。今天就要交产品了,就剩下这么个问题。
    代码如下:void CCommWizardDlg::OnOnCommCommctrl()   
    {
     // TODO: Add your control notification handler code here
     VARIANT variant_inp;
     COleSafeArray safearray_inp;
     LONG len,k;
    float f[i]=20;
     int i;
     unsigned char rxdata[20480]; //设置BYTE数组 An 8-bit integerthat is not signed.
     CString strtemp;
     CString strtemp1;
     CString data;
     CString data1;
     CString s1;
     CString s2;
      double Spectrall;
     unsigned char *q=new unsigned char[20];
     unsigned char *p=new unsigned char[20000];
    if(bReceive)
     {
      if(m_Com.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
      {
      for(i=0;i<20;i++)
     {
      f[i]=0;
     }
      variant_inp = m_Com.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型变量
      {
      unsigned char bt=*(BYTE*)(rxdata+k); //字符型
      p[k]=bt;  strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放 */
      strtemp1.Format("%02X",bt);
      data+=strtemp;
      data1+=strtemp1;  }
     if((p[0]==0xFE)&&(p[1]==0xFE)&&(p[2]==0xA2)&&(p[3]==0x0E)&&(p[4]==0x80))   
     {
      if(bochang) //开关变量
      {
        
      m_fbg=(int)p[5];
      m_ctrlChart2.GetPage().SetMaxPointsPerPage(200);
      m_ctrlChart2.GetAxis().GetLeft().SetMinMax(1528,1560);
       
      len4=p[5]; //第5位表示波长个数
        
        
      for(i=0;i<len4;i++) //从波长数据帧第6位开始每取4位字节,转化成浮点数,保存在f[i]中
      {
        
      q[0]=p[6+4*i];
      q[1]=p[7+4*i];
      q[2]=p[8+4*i];
      q[3]=p[9+4*i];
       
      WORD lowpart=MAKEWORD(q[0],q[1]);
      WORD highpart=MAKEWORD(q[2],q[3]);
      DWORD dwFinal=MAKEWPARAM(lowpart,highpart);    
      memcpy(&Spectrall,&dwFinal,sizeof(DWORD)); //转化成浮点数
      f[i]=Spectrall+1528;
      m_ctrlChart2.AddSeries(0);
    }
    }
      

  3.   

    比如说一桢数据,unsigned char型的。
    FE FE A2 0E 00 03 76 00 58 41 6E 4A B3 41 92 9C EC 41
    FE FE A2是帧头,0E是长度字节,00表示低增益,03是3个波长。
    76 00 58 41 第一个波长,6E 4A B3 41是第二个波长,92 9C EC 41是第三个波长。
    memcpy函数将76 00 58 41转成浮点数。
      

  4.   

    浮点数转换代码。
     for(i=0;i<len4;i++) //从波长数据帧第6位开始每取4位字节,转化成浮点数,保存在f[i]中
      {
        
      q[0]=p[6+4*i];
      q[1]=p[7+4*i];
      q[2]=p[8+4*i];
      q[3]=p[9+4*i];
        
      WORD lowpart=MAKEWORD(q[0],q[1]);
      WORD highpart=MAKEWORD(q[2],q[3]);
      DWORD dwFinal=MAKEWPARAM(lowpart,highpart);    
      memcpy(&Spectrall,&dwFinal,sizeof(DWORD)); //转化成浮点数
      f[i]=Spectrall+1528;
     }
      

  5.   

    76 00 58 41本身是16进制的整数,只是以 unsigned char表示而已。
      

  6.   

    76 00 58 41本身是16进制的整数,只是以 unsigned char表示而已。
    这4字节16进制整,表示的是一个浮点数。(转化使用的是浮点数IEEE754标准格式)
      

  7.   

    这样问吧,你ARM板上的波长是以整型还是浮点方式保存的
      

  8.   

    ARM那边浮点数转换成4字节16进制发送出来,然后PC这边再接收,转换成浮点数。
      

  9.   

    只有整型和浮点的区别,没有16进制这个概念,你看的16进制只是VS的IDE表示给你看的而已先不管概念问题了,memcpy(&Spectrall,&dwFinal,sizeof(DWORD))这句就有问题,Spectrall是double类型,是8个字节,并且没有初始化,你只复制4个字节过去,会导致Spectrall是个未知的值,f[i]=Spectrall+1528当然也就不对了。float是4字节的,既然你是使用的是float,那就把Spectrall申明为float
      

  10.   

    不好意思,代码上传有明显错误。Spectrall我之前是定义float的,可是问题一样的。
      

  11.   

    float Spectrall,依然出现问题: 接收到的波长数据99%,绝大部分显示,作图都是正常的,但是有时候波长会出现少量负数,而且有时候接收到的FBG数量不正常,。
      

  12.   

    你查看p里面的数据是正确的?比如是76 00 58 41,那么转换后的f[i]也是76 00 58 41么?
      

  13.   

    发送方是对的,在labview相同功能软件里面接收和显示都是没问题的。
      

  14.   

    p里面的数据不太正确。
    记录得到的错误的FBG数量 和错误的波长,好像是中间丢了帧一样的。为什么会这样呢?我的波特率设置是m_strSettings = _T("115200,n,8,1");
    m_Com.SetSettings(m_strSettings); //波特率9600,无校验,8个数据位,1个停止位
    m_Com.SetRThreshold(1);  
    //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
    m_Com.SetInputMode(1);
    m_Com.SetInputLen(0); //设置当前接收区数据长度为0
    m_Com.GetInput();//先预读缓冲区以清除残留数据 
    }错误的FBG数量 错误的波长
    205 -431600544.0000 0.0000 0.0000 0.0000  
    205 -431600544.0000 -431600544.0000 0.0000 0.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 0.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000  
    205 -431600544.0000 -431600544.0000 -431600544.0000 -431600544.0000