1

我正在尝试与 Stellaris uC 通信,但遇到了问题。uC 实际上是以波特率向 COM4 发送数据:115200,我可以在 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();
    }
}
}

串行端口选项正确且事件未触发。

肿瘤坏死因子。

编辑:这是较短的版本,但仍然没有成功。

    _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);        
        };

编辑2:

    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 回答