gpt4 book ai didi

c# - 用C#从串口读取所有缓冲区数据

转载 作者:行者123 更新时间:2023-11-30 21:40:42 28 4
gpt4 key购买 nike

我在 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”,但它们都不起作用,我做错了什么吗?

最佳答案

串口是一个流设备,它可以连续接收数据。只要串口打开,您就需要设置一个计时器,以不断检查缓冲区中是否有任何内容,并尽快将其复制到磁盘上的缓冲区或文件中,以防止缓冲区溢出。

您需要检查数据内容以了解收到的内容以及全部收到的时间。这取决于发件人。你不能只是说接收所有要接收的东西,就串行端口而言,它是一个连续的流。实际数据需要指定协议(protocol)、启动和停止条件。

编辑

下面是我用来通过 USB 转 RS232 设备以 5 兆位/秒的速度捕获软盘数据的代码片段:

    // 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. 在另一个计时器中,您可以检查接收到的数据数组中是否有新行。将所有数据复制到字符串数组或文本框。或者只是将数据作为字符串复制到文本框中以查看其中的内容。

关于c# - 用C#从串口读取所有缓冲区数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44378327/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com