串行端口缓冲/波特率/丢失数据

时间:2012-04-12 03:16:15

标签: c# serial-port buffer baud-rate

我正在使用以下代码段每秒一次在com端口发送gps数据:

serialPort = new SerialPort("COM4", 4800, Parity.None, 8, StopBits.One);
serialPort.Handshake = Handshake.None;
serialPort.WriteTimeout = 500;
serialPort.Open();

这一切都很好,但是当使用以下方法写入串口时:

serialPort.Write(theString);

使用theString == 504 charactors我的阅读程序,使用:

  while (true) {
      Console.Write(serialPort.ReadExisting());
  }

只会从该写入语句中读取254 bytes个数据。 腻子也是如此。

我尝试将写入状态分成254字节大小的块并写入两次,但看起来第二次写入操作虽然被我的编写器程序确认为运行,但读者程序从未读过。

我知道我的写缓冲区是4096 bytes,而我的读缓冲区是2048 bytes

我的字符串是这样的:

$GPGGA,191500.00,3351.6474,S,15112.6510,E,2,04,2.5,+0008,M,+020,M,00,0000*76
$GPVTG,057.3,T,,,000.0,N,000.0,K,A*41
$GPRMC,191500.00,A,3351.6474,S,15112.6510,E,000.0,057.3,120412,D*40
$GPGLL,3351.6474,S,15112.6510,E,191500.00,A,A*79
$GPGSA,A,3,,,,,,,,,,,,,2.5,1.3,2.1*34
$GPGSV,1,1,5,03,20,40,89,06,18,30,86,12,25,15,80,20,5,36,70*77
$GPDTM,999,,0.0,S,0.0,E,+0.0,W84*3B
$GPZDA,191500.00,11,04,12*60
$GPGBS,191500.00,+020.0,+020.0,+000.0,,0.00000,+0000.0,0000.0*63
$GPMSS,999,999,200.0,4800,*56

当我尝试在字符串中每行使用一个写入状态写入缓冲区时,它会将所有内容写入缓冲区,但是,两个写入操作将在读取器中进行隔行扫描,因此结果如下:

etc...
$GPGGA,191500.00,3351.6474,S,15112.6510,E,2,04,2.5,+0008,M,+020,M,00,0000*76
$GPDTM,999,,0.0,S,0.0,E,+0.0,W84*3B
$GPVTG,057.3,T,,,000.0,N,000.0,K,A*41
$GPZDA,191500.00,11,04,12*60
$GPRMC,191500.00,A,3351.6474,S,15112.6510,E,000.0,057.3,120412,D*40
$GPGBS,191500.00,+020.0,+020.0,+000.0,,0.00000,+0000.0,0000.0*63
$GPGLL,3351.6474,S,15112.6510,E,191500.00,A,A*79
$GPMSS,999,999,200.0,4800,*56
$GPGSA,A,3,,,,,,,,,,,,,2.5,1.3,2.1*34
$GPGSV,1,1,5,03,20,40,89,06,18,30,86,12,25,15,80,20,5,36,70*77
etc...

这对我来说都没有意义,虽然在9600波特率下不会发生隔行扫描问题,(我假设因为4800 baud == 480bytes/s),改变波特率不是一个选项,并且不知何故正常的GPS能够在一个突发中传输所有这些数据。

问题:

当我向流中写入504字节的数据时,有谁知道为什么我的读取只能读取254字节的数据?

是否有一些限制
serialPort.Write(Byte[], int offset, int count);

不允许超过254个字节? (这不能解释第二次写操作没有完成)。

甚至。有没有人知道更好的方法来写入串口?


此方法似乎适用于所提供的数据(尽管我原来的问题仍然存在):

string Sentence = "";
for (int i = 0; i < block_list[total_block].Count; i+=2) {
    Sentence = block_list[total_block][i] + block_list[total_block][i+1];
    serialPort.Write(Sentence);
}

1 个答案:

答案 0 :(得分:2)

坚持,你声明你使用了一秒钟的超时,但你的代码是:

serialPort.WriteTimeout = 500;

这是发送方的半秒超时。并且以4.8Kbps(大约每秒480个字符,如你所述),只有足够的时间发送大约240个字符。

可能是GPS可以执行此操作,因为它没有半秒超时。

尝试稍微提高一下超时并看看会发生什么 - 五秒钟应该为你提供足够的呼吸空间用于测试。在4.8Kbps时,504字节需要一点多于一秒的时间才能完全传输。

确定真的不想要任何握手?缺乏这一点也可能导致数据流失。