1

Stellaris uC と通信しようとしていますが、問題があります。uC は実際にはボーレート 115200 で COM4 にデータを送信しており、Putty でそれを見ることができます。

しかし、このコードを使用して C# で読み込もうとすると、何も得られません。

public class MySerialReader : IDisposable

{ 
private SerialPort serialPort;
private Queue<byte> recievedData = new Queue<byte>();

public MySerialReader()
{
    serialPort = new SerialPort("COM4", 115200, Parity.None, 8, StopBits.One);
    serialPort.Open();
    serialPort.DataReceived += serialPort_DataReceived;
}

void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e)
{
    byte[] data = new byte[serialPort.BytesToRead];
    serialPort.Read(data, 0, data.Length);
    processData();
}

void processData()
{
    // Determine if we have a "packet" in the queue
    if (recievedData.Count > 50)
    {
        var packet = Enumerable.Range(0, 50).Select(i => recievedData.Dequeue());
    }
}

public void Dispose()
{
    if (serialPort != null)
    {
        serialPort.Dispose();
    }
}
}

シリアル ポート オプションは正しく、イベントはトリガーされません。

Tnx。

編集:これは短いバージョンですが、まだ成功していません。

    _serialPort = new SerialPort("COM", 115200, Parity.None, 8
        , StopBits.One);

    _serialPort.Open();

    _serialPort.DataReceived += (sender, e) =>
        {
            SerialPort sp = (SerialPort)sender;
            string indata = sp.ReadLine();
            Console.WriteLine("Data Received:");
            Console.Write(indata);        
        };

EDIT2:

    public class SerialWrapper : IDisposable
    {
    private SerialPort _port = new SerialPort();
    private BaudRate _baudRate = BaudRate.Default;

    private Queue<byte> _serialQueue = new Queue<byte>();
    private object _lock = new object();

    public SerialWrapper(string portName, BaudRate baudRate)
    {
        try
        {
            _port.PortName = portName;
            _port.BaudRate = (int)baudRate;
        }
        catch (ArgumentNullException ex)
        {
            Debug.WriteLine(ex.Message);
        }            
    }

    /// <summary>
    /// Sends byte array to COM port
    /// </summary>
    /// <param name="buffer">Buffer to send</param>
    public void Send(byte[] buffer)
    {
        if (Open() && buffer != null && buffer.GetLength(0) > 0)
        {
            Monitor.Enter(_lock);
            _port.Write(buffer, 0, buffer.GetLength(0));
            Monitor.Exit(_lock);
        }
    }

    /// <summary>
    /// Send string as message to COM port
    /// </summary>
    /// <param name="message">String message to send</param>
    public void Send(string message)
    {
        if (Open() && !String.IsNullOrWhiteSpace(message))
        {
            ASCIIEncoding encoding = new ASCIIEncoding();
            _port.Write(message);
        }
    }

    public Queue<byte> Get()
    {
        Queue<byte> buffer = new Queue<byte>();

        Monitor.Enter(_lock);

        if (_serialQueue.Count == 0)
        {
            Monitor.Exit(_lock);
            return null;
        }

        for (int i = 0; i < _serialQueue.Count; i++)
        {
            buffer.Enqueue(_serialQueue.Dequeue());
        }

        return buffer;
    }

    /// <summary>
    /// Dispose the object
    /// </summary>
    public void Dispose()
    {
        try
        {
            _port.Close();
            _port.Dispose();
        }
        catch (IOException ex)
        {
            Debug.WriteLine("Error disposing: " + _port.PortName + ". " + ex.Message);
        }
    }

    /// <summary>
    /// Open the port.
    /// </summary>
    /// <returns></returns>
    public bool Open()
    {
        if (_port.IsOpen)
        {
            return true;
        }

        try
        {
            _port.Close();
        }
        catch (IOException ex)
        {
            Debug.WriteLine("Error closing: " + _port.PortName + "." + ex.Message);
            return false;
        }

        _port.DataBits = 8;
        _port.DiscardNull = false;
        _port.DtrEnable = false;
        _port.Encoding = Encoding.ASCII;
        _port.Handshake = Handshake.None;
        _port.Parity = Parity.None;
        _port.ReadBufferSize = 16384;
        _port.ReadTimeout = -1;
        _port.RtsEnable = false;
        _port.StopBits = StopBits.One;
        _port.WriteBufferSize = 16384;            
        _port.DataReceived += _port_DataReceived;

        try
        {
            _port.Open();
        }
        catch (IOException ex)
        {
            Debug.WriteLine("Error opening: " + _port.PortName + ". " + ex.Message);
            return false;
        }


        return true;
    }

    /// <summary>
    /// Event handler 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void _port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        Monitor.Enter(_lock);

        try
        {
            if (_port.IsOpen)
            {
                int itemsCount = _port.BytesToRead;
                if (itemsCount > 0)
                {
                    byte[] buffer = new byte[itemsCount];
                    _port.Read(buffer, 0, itemsCount);

                    _serialQueue.Clear();

                    for (int i = 0; i < itemsCount; i++)
                    {
                        _serialQueue.Enqueue(buffer[i]);
                    }

                }
            }
        }
        catch (Exception ex)
        {

        }

        Monitor.Exit(_lock);

    }


}
4

1 に答える 1

2

ハンドシェイクを適切に処理したかどうかは、スニペットからはまだ明らかではありません。日曜大工のアプローチの時間。SysInternals から入手できる非常に便利なユーティリティがあります。PortMon ツールは、シリアル ポート ドライバに設定されている低レベル コマンドを表示します。

Putty で動作しているので、最初に Putty セッションを実行します。PortMon トレースをテキスト ファイルにコピー アンド ペーストします。ここで独自のプログラムを実行し、引き続き PortMon でドライバー コマンドを監視します。これで、比較するものがあります。Putty トレースと自分のトレースの違いに注目してください。

コードの変更の違いをリバース エンジニアリングするのは少し難しい場合があります。ドライバー コマンドはかなりあいまいです。しかし、必ずコードを変更し、接続を確認するためにドライバー コマンドがどのように変更されるかを観察してください。したがって、Putty 構成を正確に複製して、通信を機能させることができるはずです。

于 2012-12-22T16:14:11.630 に答える