簡體   English   中英

使用C#從串行端口讀取所有緩沖區數據

[英]Read all buffer data from serial port with C#

我在C#中使用System.IO.Ports從串行端口讀取數據時遇到一些問題。 唯一有效的方法是“讀取”方法,但它只能讀取“已定義”的字符數,我需要讀取所有可用的數據,例如“ Tera Term”或“ Hercules”。 這是我的DLL方法讀取緩沖區:

public String ReadMessage(String port, int timeout, int dataSize)
{
    String res;

    try
    {
        _serial_port = new SerialPort();
        _serial_port.PortName = port;
        _serial_port.BaudRate = 19200;
        _serial_port.Parity = Parity.None;
        _serial_port.DataBits = 8;
        _serial_port.StopBits = StopBits.One;
        _serial_port.Handshake = Handshake.None;
        _serial_port.ReadTimeout = timeout;
        _serial_port.DtrEnable = true;
        _serial_port.RtsEnable = true;

        _serial_port.Open();
        _serial_port.DiscardInBuffer();

        int totalBytes = _serial_port.BytesToRead;

        if (totalBytes > 0)
        {
            byte[] buffer = new byte[totalBytes];
            _serial_port.Read(buffer, 0, totalBytes);
            res = ByteArrayToString(buffer);                   
        }
        else
        {
            byte[] buffer = new byte[dataSize];

            for (int len = 0; len < buffer.Length;)
            {
                len += _serial_port.Read(buffer, len, buffer.Length - len);
            }

            res = ByteArrayToString(buffer);                    
        }

        _serial_port.Close();

        return res;
    }
    catch (Exception ex)
    {
        if (ex is UnauthorizedAccessException || ex is TimeoutException)
        {
            _serial_port.Close();
        }

        return ex.ToString();
    }
}

我知道還有其他讀取數據的方法,例如:“ ReadByte”,“ ReadChar”,“ ReadExisting”,“ ReadLine”和“ ReadTo”,但是它們都不起作用,我在做錯什么嗎?

串行端口是一種流設備,它可以連續接收數據。 只要串行端口處於打開狀態,就需要設置一個計時器,以連續檢查緩沖區中是否有任何東西,並盡快將其復制到緩沖區或磁盤上的文件中,以防止緩沖區溢出。

您需要檢查數據內容以找出接收到的內容以及何時接收到所有數據。 這取決於發送者。 您不能只說接收所有要接收的內容,就串行端口而言,它是連續的。 實際數據需要指定協議,開始和停止條件。

編輯

這是我用來通過USB以5mbit / sec的速度將音頻數據通過USB捕獲到rs232設備的代碼片段:

    // Capture handler
    private void timer2_Tick(object sender, EventArgs e)
    {
        // Read data from serial port, poll every 10ms
        // If data is there, read a block and write it to array
        int bytestoread = 0;
        //byte buf;

        timer2.Stop();
        try
        {
            bytestoread = serialPort1.BytesToRead;
        }

        catch (InvalidOperationException ex)
        {
            tbr.Append("Serial connection lost. Exception type:" + ex.ToString());
            if ((uint)ex.HResult == 0x80131509)
            {
                timer2.Stop();
            }
        }

        if (serialPort1.IsOpen)
        {
            if (bytestoread != 0)
            {
                bytespersecond += bytestoread;

                byte[] temp = new byte[bytestoread];

                if (serialPort1.IsOpen)
                    serialPort1.Read(temp, 0, bytestoread);

                tempbuffer.Add(temp);
                processing.indexrxbuf += bytestoread;
                recentreadbuflength += bytestoread;

                //update the scatterplot, this may have a performance hit
                processing.rxbuf = tempbuffer.SelectMany(a => a).ToArray();
                rxbuf = processing.rxbuf;
                if (Setrxbufcontrol == null) return;
                Setrxbufcontrol();

            }
            timer2.Start();
        }
    }

串行端口的設置代碼。 我定義了大緩沖區以防止溢出:

        serialPort1.BaudRate = 5000000;
        serialPort1.NewLine = "\r\n";
        serialPort1.ReceivedBytesThreshold = 500000;
        serialPort1.ReadBufferSize = 1048576;

編輯2

從串行端口讀取的步驟:

  1. 定義接收的數據數組以保存數據
  2. 打開串口
  3. 設置計時器以連續讀取數據,直到用戶按下斷開連接按鈕為止
  4. 計時器滴答方法檢查串行緩沖區中的數據長度,然后將該長度讀取到步驟1中定義的接收緩沖區中。通過將串行緩沖區長度添加到靜態變量中來跟蹤接收的總數據。
  5. 在另一個計時器中,您可以檢查接收到的數據數組是否有新行。 將所有數據復制到字符串數組或文本框。 或者只是將數據作為字符串復制到文本框中以查看其中的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM