解决方案
通过"port.ReadByte"按字节读取数据太慢,问题出在SerialPort类内部。我把它改为通过"port.Read"读取更大的块,现在没有缓冲区溢出。
虽然我自己找到了解决方案,但写下来对我有帮助,也许其他人也有同样的问题,并通过谷歌找到了这个。。。
(如何将其标记为已应答?)
编辑2
通过设置
port.ReadBufferSize = 2000000;
我可以把这个问题推迟30秒左右。看来,.Net真的太慢了。。。由于我的应用程序不是那么关键,我只是将缓冲区设置为20MB,但我仍然对原因感兴趣。
编辑
我刚刚测试了一些我以前没有想到的东西(我很惭愧):
port.ErrorReceived += (object self, SerialErrorReceivedEventArgs se_arg) => { Console.Write("| Error: {0} | ", System.Enum.GetName(se_arg.EventType.GetType(), se_arg.EventType)); };
而且我似乎有一个超支。对于500k来说,.Net的实现太慢了吗?还是我这边有错误?
原始问题
我构建了一个非常原始的oszilloscope(avr,它通过uart将adc数据发送到ftdi芯片)。在电脑端,我有一个显示这些数据的WPF程序。
Protokoll是:
两个同步字节(0xaffe)-14个数据字节-2个同步字节-14个数据比特-。。。
我使用16位的值,所以在14个数据字节中有7个通道(首先是lsb)。
我用hTerm验证了uC固件,它确实发送和接收了所有正确的东西。但是,如果我尝试用C#读取数据,有时会丢失一些字节。oszilloscop程序一团糟,但我创建了一个小样本应用程序,它也有同样的症状。
我添加了两个扩展方法:a)从COM端口读取一个字节并忽略-1(EOF)以及b)等待同步模式。
样本程序首先通过等待(0xaffe)同步到数据流上,然后将接收到的字节与期望值进行比较。循环运行几次,直到弹出断言失败消息。我在谷歌上找不到任何关于丢失字节的信息,如有任何帮助,不胜感激。
代码
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SerialTest
{
public static class SerialPortExtensions
{
public static byte ReadByteSerial(this SerialPort port)
{
int i = 0;
do
{
i = port.ReadByte();
} while (i < 0 || i > 0xff);
return (byte)i;
}
public static void WaitForPattern_Ushort(this SerialPort port, ushort pattern)
{
byte hi = 0;
byte lo = 0;
do
{
lo = hi;
hi = port.ReadByteSerial();
} while (!(hi == (pattern >> 8) && lo == (pattern & 0x00ff)));
}
}
class Program
{
static void Main(string[] args)
{
//500000 8n1
SerialPort port = new SerialPort("COM3", 500000, Parity.None, 8, StopBits.One);
port.Open();
port.DiscardInBuffer();
port.DiscardOutBuffer();
//Sync
port.WaitForPattern_Ushort(0xaffe);
byte hi = 0;
byte lo = 0;
int val;
int n = 0;
// Start Loop, the stream is already synced
while (true)
{
//Read 7 16-bit values (=14 Bytes)
for (int i = 0; i < 7; i++)
{
lo = port.ReadByteSerial();
hi = port.ReadByteSerial();
val = ((hi << 8) | lo);
Debug.Assert(val != 0xaffe);
}
//Read two sync bytes
lo = port.ReadByteSerial();
hi = port.ReadByteSerial();
val = ((hi << 8) | lo);
Debug.Assert(val == 0xaffe);
n++;
}
}
}
}
通过"port.ReadByte"按字节读取数据太慢,问题出在SerialPort类内部。我把它改为通过"port.Read"读取更大的块,现在没有缓冲区溢出。