.NET SerialPort.Read skipps bytes

时间:2012-12-03 12:11:09

标签: .net serial-port overrun

解决方案

通过“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)); };

似乎我有一个超支。 .Net实现对于500k来说是否太慢或者是否存在错误?

原始问题

我构建了一个非常原始的oszilloscope(avr,它通过uart将adc数据发送到ftdi芯片)。在PC端,我有一个显示此数据的WPF程序。

Protokoll是:

两个同步字节(0xaffe) - 14个数据字节 - 两个同步字节--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++;
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

通过“port.ReadByte”以字节方式读取数据太慢,问题出在SerialPort类中。 我把它更改为通过“port.Read”读取更大的块,现在没有缓冲区溢出。