none
Serialport无法及时读取数据 RRS feed

  • 问题

  •       我用VB2010开发串口通信程序的时候,开了一个Background,这个线程只负责查询SerialPort的接收区有无数据,有就立刻接收。如果有发送需求,也会第一时间处理。

    SerialPort设定如下:

              SerialPort2.PortName = ComboBox1.SelectedItem.ToString
              SerialPort2.BaudRate = 19200
              SerialPort2.DataBits = 8
              SerialPort2.Parity = Ports.Parity.Even
              SerialPort2.ReceivedBytesThreshold = 1
              SerialPort2.StopBits = Ports.StopBits.One

    Background2程序如下:

              While SerialPort2.IsOpen
                   ByteCount = SerialPort2.BytesToRead
                   If ByteCount > 0 Then
                     If ByteCount + RX_Buffer.BytesInBuffer > 300 Then
                        ByteCount = 300 - RX_Buffer.BytesInBuffer
                     End If
                     SerialPort2.Read(ReadByte, 0, ByteCount)
                     While RW.Thread_1_Writing
                        RW.Thread_2_Writing = False
                        System.Threading.Thread.Sleep(1)
                     End While
                     RW.Thread_2_Writing = True
                     Try
                        For i = 0 To ByteCount - 1
                           RX_Buffer.ByteArray(RX_Buffer.BytesInBuffer + i) = ReadByte(i)
                        Next
                        RX_Buffer.BytesInBuffer = RX_Buffer.BytesInBuffer + ByteCount
                     Finally
                        RW.Thread_2_Writing = False
                     End Try
                 End If
                 System.Threading.Thread.Sleep(1)
                 If SendReady Then
                    Try
                       If Not SerialPort2.IsOpen Then
                         SerialPort2.Open()
                       End If
                       If SerialPort2.IsOpen Then
                          SerialPort2.Write(Send_Array, 0, Send_Frame.Count + 3)
                          SendReady = False
                          Sended_Frame.Event_Count = Send_Frame.Event_Count
                          Sended_Frame.Count = Send_Frame.Count
                          Sended_Frame.Station = Send_Frame.Station
                          Sended_Frame.Function_Code = Send_Frame.Function_Code
                          Sended_Frame.Number = Send_Frame.Number
                          Sended_Frame.Type = Send_Frame.Type
                          Sended_Frame.Start = Send_Frame.Start
                       End If
                       WaitResponse = True
                       WaitCount = 0
                   Catch err As Exception
                       MessageBox.Show(err.Message)
                   End Try
                   System.Threading.Thread.Sleep(1)
               End If
           End While

          问题是,虽然这个过程是一刻不停的循环进行的,但却总是在很多次查询到SerialPort.Bytestoread为0,然后等查询到SerialPort.Bytestoread不为0的时候,接收区已经有好多字节的数据了。

    2015年5月22日 2:58

全部回复

  • 下面是监控的数据(Debug.writeline,上面程序没写出来)

    Thread 1 Send意味着Background 1给出了要发送的数据

    Thread 2 Sleep 1ms after write serialport意味着Background 2发送了数据,并已sleep 1ms

    Thread 2 Received : 0意味着Background 2已意味着Background 2已查询SerialPort的输入数据

    Thread 2 Sleep 1ms after read serialport意味着Background 2查询SerialPort后已Sleep 1ms

    08:55:02.9680992 Thread 1 Send
    08:55:02.9690992 Thread 2 Sleep 1ms after write serialport
    08:55:02.9700992 Thread 2 Received : 0
    08:55:02.9720992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9720992 Thread 2 Received : 0
    08:55:02.9740992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9740992 Thread 2 Received : 0
    08:55:02.9760992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9760992 Thread 2 Received : 0
    08:55:02.9780992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9780992 Thread 2 Received : 0
    08:55:02.9800992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9800992 Thread 2 Received : 0
    08:55:02.9820992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9820992 Thread 2 Received : 0
    08:55:02.9840992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9840992 Thread 2 Received : 0
    08:55:02.9860992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9860992 Thread 2 Received : 0
    08:55:02.9870992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9870992 Thread 2 Received : 0
    08:55:02.9880992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9880992 Thread 2 Received : 0
    08:55:02.9900992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9900992 Thread 2 Received : 0
    08:55:02.9920992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9920992 Thread 2 Received : 0
    08:55:02.9940992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9940992 Thread 2 Received : 0
    08:55:02.9960992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9960992 Thread 2 Received : 0
    08:55:02.9980992 Thread 2 Sleep 1ms after read serialport
    08:55:02.9980992 Thread 2 Received : 0
    08:55:03.0000992 Thread 2 Sleep 1ms after read serialport
    08:55:03.0000992 Thread 2 Received : 0
    08:55:03.0050992 Thread 2 Sleep 1ms after read serialport
    08:55:03.0050992 Thread 2 Received : 14

    2015年5月22日 3:04
  • 我想知道,BackGround 2一直在循环,每个循环只Sleep了1ms(如果没有发送数据的话,如果有发送数据就会多Sleep 1ms),等于每1ms都在查询SerialPort的输入缓冲区,却为什么这个循环查不到数据,下个循环就突然出现那么多数据呢?

    还有,前面监控数据可以看到,08:55:03.0050992和08:55:03.0050992之间有5ms的间隔,也就是说这5ms Background 2啥也没干,为什么会这样呢?

    2015年5月22日 3:10
  • 首先你这种使用Serialport的方式不对,因为Serialport是争用资源因此最好是在一个线程中完成收发工作,还有不要过去频繁的访问Serialport,否则会引发各种问题。

    对于你的问题原因是Serialport只是一个代理类,他间接了完成了Windows API访问系统串口资源的工作,因此其中接收数据是有延时,还有你的波特率很高19200传输速度很快,这样也就发生了你所描述的情况,上1ms没有数据,下1ms就产生了很多数据。这其中有很多不确定因素,有可能是设备真的传输了过来,也有可能硬件层还没有获取到相应的信息。

    2015年5月22日 5:44
  • 我的收发其实是在一个线程里的,只是发送数据的准备是在另一个线程里。

    19200波特率,传送1个字节需要0.55毫秒,因此像上面这种一下子收14个的的就意味着有8ms的数据在一毫秒里收到,不合理啊。

    更厉害的还有一次收到40个字节的时候,这个太过了。

    我的应用对实时性要求比较高,串口通信必须及时处理,所以必须解决这个问题。

    大侠们有什么办法,我先谢谢了!

    2015年5月22日 9:23
  • 下面是一段串口监控的数据:

    19 17:43:05.835 0.00010734 IRP_MJ_WRITE         Length: 6, Data: 82 96 03 01 65 67 
    20 17:43:05.855 0.01580148 IOCTL_SERIAL_WAIT_ON_MASK           
    21 17:43:05.855 0.00000556 IRP_MJ_READ           Length: 9, Data: 82 96 0B 01 65 0A 00 00 00 

    22 17:43:05.871 0.11179881 IOCTL_SERIAL_WAIT_ON_MASK

    23 17:43:05.871 0.00000385 IRP_MJ_READ            Length: 5, Data: 00 00 51 00 34

    IOCTL_SERIAL_WAIT_ON_MASK是什么鬼?

    2015年5月22日 9:52
  • 下面是通信初始化的信息,不知有没有帮助

    1 17:43:04.811 0.02515536 IRP_MJ_CREATE                       Port Opened
    2 17:43:04.837 0.00045202 IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 19200
    3 17:43:04.837 0.00098316 IOCTL_SERIAL_CLR_RTS                
    4 17:43:04.838 0.00099599 IOCTL_SERIAL_CLR_DTR                
    5 17:43:04.839 0.00097204 IOCTL_SERIAL_SET_LINE_CONTROL       StopBits: 1, Parity: Even, DataBits: 8
    6 17:43:04.840 0.00000428 IOCTL_SERIAL_SET_CHARS              EofChar: 0x1A, ErrorChar: 0x3F, BreakChar: 0x3F, EventChar: 0x1A, XonChar: 0x11, XoffChar: 0x13
    7 17:43:04.840 0.00095878 IOCTL_SERIAL_SET_HANDFLOW       ControlHandShake: 0x0, FlowReplace: 0x4, XonLimit: 1024, XoffLimit: 1024
    8 17:43:04.841 0.00087539 IOCTL_SERIAL_SET_BAUD_RATE       Baud Rate: 19200
    9 17:43:04.842 0.00097418 IOCTL_SERIAL_CLR_RTS                
    10 17:43:04.843 0.00097973 IOCTL_SERIAL_CLR_DTR                
    11 17:43:04.844 0.00099855 IOCTL_SERIAL_SET_LINE_CONTROL      StopBits: 1, Parity: Even, DataBits: 8
    12 17:43:04.845 0.00000513 IOCTL_SERIAL_SET_CHARS               EofChar: 0x1A, ErrorChar: 0x3F, BreakChar: 0x3F, EventChar: 0x1A, XonChar: 0x11, XoffChar: 0x13
    13 17:43:04.845 0.00095964 IOCTL_SERIAL_SET_HANDFLOW           ControlHandShake: 0x0, FlowReplace: 0x4, XonLimit: 1024, XoffLimit: 1024
    14 17:43:04.846 0.00086427 IOCTL_SERIAL_CLR_DTR                
    15 17:43:04.849 0.00000727 IOCTL_SERIAL_SET_TIMEOUTS           ReadIntervalTimeout: -1, ReadTotalTimeoutMultiplier: -1, ReadTotalTimeoutConstant: -2, WriteTotalTimeoutMultiplier: 0, WriteTotalTimeoutConstant: 0
    16 17:43:04.849 0.00012658 IOCTL_SERIAL_SET_WAIT_MASK           Mask: RXCHAR RXFLAG CTS DSR RLSD BREAK ERR RING
    17 17:43:04.851 0.00000855 IOCTL_SERIAL_SET_QUEUE_SIZE         InSize: 4096, OutSize: 2048

    2015年5月22日 9:56