我现在明确知道一台电脑的串口是输出double类型数据,我想通过利用一条串口线将这台电脑与另一台电脑的串口相连,然后在另一台电脑里面写程序读出串口的数据,请教高手是否可以实现这样的功能,我尝试使用mscomm的控件,可是怎么也接收不到数据。希望能有高手指明方向!谢谢。

解决方案 »

  1.   

    我用测试精灵和我自己写的程序通过两台机器测试可以通信,不过有时候可以,有时候不行。但是用来接受double的数据就接受不到。我用的mscomm控件,请问它可以实现这样的功能吗?
      

  2.   

    double数据就是从变量地址开始发8个字节而已,没什么特别的。
      

  3.   

    我在上位机上运行了一个程序,每22ms发送一次数据,发送的数据是double类型的,然后在下位机上运行下面这段代码。可是怎么也接收不到数据,不知道是什么地方的问题。
    请教高手,如果搞定,马上给分.并不胜感激! //initial com1
    m_MSCommCom1.SetCommPort(1);
    m_MSCommCom1.SetInputMode(1);
    m_MSCommCom1.SetInBufferSize(1024);
    m_MSCommCom1.SetOutBufferSize(512);
    m_MSCommCom1.SetSettings("19200,n,8,1");
    m_MSCommCom1.SetHandshaking(2);
    m_MSCommCom1.SetEOFEnable(false);
    //m_MSCommCom1.SetCTSHolding(false);
    // m_MSCommCom1.SetDSRHolding(false);
    // m_MSCommCom1.SetRTSEnable(false);// m_MSCommCom1.SetCTSHolding(true);// m_MSCommCom1.SetDTREnable(true); m_MSCommCom1.SetRThreshold(1);
    m_MSCommCom1.SetSThreshold(1);
    if( !m_MSCommCom1.GetPortOpen())
    {
    m_MSCommCom1.SetPortOpen(true);
    }
    else
    {
    m_MSCommCom1.SetOutBufferCount(0);
    m_MSCommCom1.SetInBufferCount(0);
    }
    m_MSCommCom1.SetInputLen(0);
    m_MSCommCom1.GetInput();void CTestDlg::OnCommMscomm1() 
    {
    // TODO: Add your control notification handler code here
    VARIANT varient_inp;
    COleSafeArray safearray_inp;
    LONG len,k;
    BYTE rxdata[2048];
    CString strtemp;
    int test = m_MSCommCom1.GetCommEvent();
    if(m_MSCommCom1.GetCTSHolding())
    MessageBox("cts true",MB_OK);
    if(m_MSCommCom1.GetDSRHolding())
    MessageBox("dsr true",MB_OK);

    if(test==1)
    MessageBox("发送",MB_OK);

    else if(test==2)
    {
    varient_inp = m_MSCommCom1.GetInput();
    safearray_inp = varient_inp;
    len = safearray_inp.GetOneDimSize();

    for(k=0; k<len; k++)
    {
    safearray_inp.GetElement( &k,rxdata+k);
    }
    for(k=0; k<len; k++)
    {
    BYTE bt = *(char *)(rxdata+k);
    strtemp.Format("%c",bt);
    m_com1RxData += strtemp;

    }
    //MessageBox("接到数据",MB_OK);
    UpdateData(false);
    }
    else
    {
    MessageBox("串口没有消息",MB_OK);
    }
      

  4.   

    你执行这段代码的结果如何?调试一下看执行到哪里出问题。for(k=0; k <len; k++) 

    BYTE bt = *(char *)(rxdata+k); 
    strtemp.Format("%c",bt); 
    m_com1RxData += strtemp; 

    这段代码是不对的。
    如果接收的是字符串,可以这样写:
    strtemp = (LPTSTR)rxdata;
    如果接收的是数值,例如double型数值,可以这样写:
    strtemp.Format("%Lf", *(double*)rxdata);
      

  5.   

    现在我只有一台机器可以试验,我短接2.3针,然后按照你的提示,把那行代码改写了,现在能接受到一串不正确的数据,比如我输入0.1,却收到-92559631232869445000000000000000000000000000000000000000000000.000000-92559631232869445000000000000000000000000000000000000000000000.000000-92559631232869445000000000000000000000000000000000000000000000.000000
    的数据,另外commevent却依次出现为2,3,4,5,6,3,4,5,6,3,4,5,6,1
    另外,很惭愧的是,我在使用断点调试的时候,经常走到一些类似汇编语言的地方,就走不下去了,请指点以下。感激不尽!
      

  6.   

    对了,现在跟踪发现 
    varient_inp = m_MSCommCom1.GetInput()
    这个地方读到的数据已经是乱码了,该怎么处理它 呢?
      

  7.   

    double型占据8个字节。这样:1、发送端代码:double dbVal = 0.1;
    BYTE   *p = (BYTE*)&dbVal;
    SerialPort.Sent(p, 8);
    2、接收端代码:BYTE   pRcv[20];
    memset(pRcv, 0, sizeof(pRcv));
    SerialPort.Recive(pRcv, 8);
    double *pdbVal = (double*)pRcv;
    ASSERT( fabs(*pdbVal - .1) < 1e-6 );
      

  8.   

    我现在找到两台机器了,在上位机上运行一个vb程序,上面有4个通道,分别对应4个double类型的数据,然后将它们发到串口上面,我用一根串口线联到下位机上,然后再下位机运行接受数据的程序,就想实现这么一个功能,现在的问题是在下位机上面检测不到commevent.好像就没有数据发送出来似的。上位机vb代码如下
    Option ExplicitDim PortIsOpen As Integer
    Dim NumberOfActiveChannels As IntegerDim ChannelValueArray(7) As String * 1Private Sub cboSetActiveChannels_Click() '
    Dim Count As Integer
    Let Count% = 0                                                                  'Set up a channel counter loop
    Let NumberOfActiveChannels% = (Form01.cboSetActiveChannels.ListIndex + 1)       'and the No. of Active Chans.'
    Do
     If Count% < NumberOfActiveChannels% Then                               'This loop runs 4 times and
      Let Form01.hsbChannelValue(Count%).Enabled = True                     'for Active Channels enables
      Call hsbChannelValue_Scroll(Count%)                                   'the corresponding slider and
     Else                                                                   'updates the displayed value.
      Let Form01.hsbChannelValue(Count%).Enabled = False                    'For Inactive Channels the
      Let Form01.lblChannelValue(Count%).Caption = ""                       'slider bar is disabled and
     End If                                                                 'the displayed value cleared.
     Let Count% = (Count% + 1)
    Loop Until Count% = 8
    End SubPrivate Sub cmdCommPortAction_Click()Dim Count As Integer
    Select Case PortIsOpen%
     Case False                                                           'COM Port is currently not Open.
      On Error GoTo CommErrorHandler                                      'Set up an error handler.  If Form01.optCommPortSelect(0).Value = True Then                   'Depending on the users choice first
       Let Form01.Comm1.CommPort = 1                                     'set the appropriate COM Port, 1 or 2.
      Else
       Let Form01.Comm1.CommPort = 2
      End If
      Let Form01.Comm1.Settings = "19200,N,8,1"                           'The set the transmission parameters,
      Let Form01.Comm1.Handshaking = 2                                    'sets handshaking method to 'RTS/CTS'
      Let Form01.Comm1.PortOpen = True                                    'and attempts to open the port.
      Let Form01.Comm1.RTSEnable = True                                   'If Port Open = OK then power up the
      Let Form01.cmdCommPortAction.Caption = "Close Port"                'interface hardware, alter the caption
      Let Form01.cmdQuit.Enabled = False                                 'on the button, disable Quit button,
      Let PortIsOpen% = True                                             'and set the Port State variable.  Let Form01.Comm1.InBufferCount = 0                                 'Because the slider values may have
      For Count% = 0 To (NumberOfActiveChannels% - 1)                    'changed while the Port was closed an
       Let Form01.Comm1.Output = ChannelValueArray(Count%)               'update is performed to ensure the
      Next Count%                                                        'hardware reflects the current values.
      Exit Sub                                                           'Note the purge of the receive buffer.CommErrorHandler:                                                    'Here if an error occured opening the
      Let Form01.cmdCommPortAction.Caption = "Open Port"                 'COM Port. Ensure that the button
      Let Form01.cmdQuit.Enabled = True                                  'caption, the Quit button and the
      Let PortIsOpen% = False                                            'Port State variable are correctly
    Beep:   Beep                                                         'set. Sound to alert the user.
      Exit Sub Case True                                                           'Here if the port is already Open so
      Let Form01.Comm1.RTSEnable = False                                 'power down the interface hardware
      Let Form01.Comm1.PortOpen = False                                  'and close it, change the caption on
      Let Form01.cmdCommPortAction.Caption = "Open Port"                 'the button, re-enable Quit button
      Let Form01.cmdQuit.Enabled = True                                   'stop the Channel Value Write timer
      Let PortIsOpen% = False                                             'and set the Port State variable.
    End Select
    End SubPrivate Sub cmdQuit_Click()
    End
    End SubPrivate Sub Form_Load()Dim RetVal As Integer
    Dim Count As Integer
    Dim ReturnString As StringIf App.PrevInstance = True Then End                                   'Only permit a single instance.Let Form01.Left = ((Screen.Width - Form01.Width) / 2)                 'Centralise the form on screen.
    Let Form01.Top = ((Screen.Height - Form01.Height) / 2)For Count% = 0 To 7                                                   'Set all channel values to the mid
     Let Form01.hsbChannelValue(Count).Value = 125                        'position ie 1.5ms.
    Next Count%Form01.cboSetActiveChannels.AddItem "Ch1  Only"                       'Set up options in the Active
    Form01.cboSetActiveChannels.AddItem "Ch1 - Ch2"                       'Channels selection and set to
    Form01.cboSetActiveChannels.AddItem "Ch1 - Ch3"                        'default value of Ch1 to Ch4.
    Form01.cboSetActiveChannels.AddItem "Ch1 - Ch4"Let Form01.cboSetActiveChannels.ListIndex = 3Let PortIsOpen = False                                                'Initialise any variables.Form01.Show
    End SubPrivate Sub hsbChannelValue_Change(Index As Integer)Call hsbChannelValue_Scroll(Index%)
    End SubPrivate Sub hsbChannelValue_Scroll(Index As Integer)Dim Count As IntegerLet Form01.lblChannelValue(Index%).Caption = Format$((((Form01.hsbChannelValue(Index%).Value * 4) + 1000) / 1000), "0.000")
    Let ChannelValueArray(Index%) = Chr$(Form01.hsbChannelValue(Index%).Value)If PortIsOpen% = True Then                                          'If Port is Open then check for a
     While Form01.Comm1.CTSHolding = True: Wend                         'transmission in progress and wait
     Let Form01.Comm1.OutBufferCount = 0                                'if so. Purge the Transmit buffer
     Let Form01.Comm1.InBufferCount = 0                                 'and Receive buffer.
     For Count% = 0 To (NumberOfActiveChannels% - 1)                    'Load the new set of values
      Let Form01.Comm1.Output = ChannelValueArray(Count%)               'for the Active Channels only
     Next Count%                                                        'into the Transmit buffer.
    End If
    End Sub
      

  9.   

    从上面的代码中看不出double型数据是怎么发出去的。主要是要知道是按8字节数值发的还是按照"0.1"这个字符串发的。
      

  10.   

    非常感谢楼上一直以来的帮助,使我对问题的认识也逐渐发生了变化。我现在的问题是,不论是尝试接受数值型的数据,还是字符型的数据。都好像没有commevent产生。我在上位机上运行的程序是从http://www.rc-electronics.co.uk/pcbuddy.htm这个网站上下载回来的一个demo,而且用这个demo控制遥控器,能正常工作,说明确实是有数据送到串口上了,可是在下位机上却一直没有动静,就是没有触发oncomm事件。请教楼上的,串口上面还可能有其他的数据格式工作吗?如果可以的话,能不能请楼上的下载这个demo试验一下。实在感激不尽!
      

  11.   

    原来,当我用串口线连接两台机器的串口时,在上位机上就没有发送数据,在上位机上面的串口驱动中间运行了如下这么一段代码
    请教下面这段代码什么意思,为什么status 的值只是0 或者3 ,而且大多都是3。 如果我想在下位机上面接受上位机器传出来的数据。应该怎么设置下位机的串口属性。 另外在上位机上是多线程的发送,在下位机上一定也要用多线程的接收吗?
        while(1)
        {
              int status = 0;
      while (!(status & TIOCM_CTS)) {
    ioctl(fd_ser, TIOCMGET, &status);
      }   if ( write(fd_ser, intdata,4) < 0)
        SetAsyncSendIconError  (errno, SendID);
      else
        SetAsyncSendIconError  (0, SendID);
              tcdrain(fd_ser);
      status=0;
         }
      

  12.   

    这段代码看起来是向Modem发送数据的。
    串口要按照上位程序中的"19200,N,8,1"来设置,波特率19200,偶校验,8数据位,1停止位。
    下位机不用多线程。
      

  13.   

    我是这样设置的啊,可是没有commevent 产生。而且上位机一直处在那个循环里面,就刚开始两个0然后,status一直都是3,应该怎么触发,让它能够发出数据呢?
      

  14.   

    对了,不是偶校验,一直都是19200,N,8,1。上位机的程序动不了,下位机能通过设置RTS enable,来改变上位机的CTS引脚的值吗?
      

  15.   

    我一般用不到串口,所以很多细节也不太清楚。
    我的意思是你自己做两个程序,一个上位机和一个下位机。既然用MsComm控件来做,在控件属性上面设置一下,两个程序设置一样就可以了。
      

  16.   

    我一般用不到串口,所以很多细节也不太清楚。 
    我的意思是你自己做两个程序,一个上位机和一个下位机。既然用MsComm控件来做,在控件属性上面设置一下,两个程序设置一样就可以了
    ============
    .
      

  17.   

    你这样交换我知道行不行,如果只有一台电脑,可以把Com1和Com2连上,或者用虚拟机通过pipe模拟。
      

  18.   

    那样是可以通信的。但是是单工的通信,按双工使用有一端就出错了,而且不能使用硬件握手协议。郁闷ing!