我正在尝试与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);
}
}
从您的片段中仍然不清楚您是否正确处理了握手。 是时候自己动手了。 SysInternals提供了一个非常有用的实用程序,PortMon工具向您展示了设置为串行端口驱动程序的低级命令。
由于您有它与 Putty 配合使用,因此请先运行 Putty 会话。 将 PortMon 跟踪复制并粘贴到文本文件中。 现在运行你自己的程序,仍然使用 PortMon 观察驱动程序命令。 您现在有一些东西可以比较,专注于腻子痕迹与您的痕迹的差异。
对代码更改的差异进行逆向工程可能有点棘手,驱动程序命令非常晦涩难懂。 但一定要在代码中进行更改,并观察它如何更改驱动程序命令以查看连接。 因此,您应该能够完全复制 Putty 配置并使通信正常工作。