对于串口数据存在以 0D 0A(回车换行)作为结束符号的情况,可以按照以下步骤设计相应的处理逻辑:
一、定义数据包结构
首先定义一个数据包结构,包含数据包长度和实际数据内容两个部分。
示例代码:
public struct SerialPacket
{
public int Length;
public byte[] Data;
}
二、读取串口数据并缓存
在 SerialPort_DataReceived 事件中读取串口数据,并将其缓存在一个 List 中。
示例代码:
private List<byte> buffer = new List<byte>();
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int bytesRead = serialPort.Read(readBuffer, 0, readBuffer.Length);
buffer.AddRange(readBuffer.Take(bytesRead));
}
三、解析数据包
在缓存的数据中查找 0D 0A 结束符,并将完整的数据包提取出来。
示例代码:
private List<SerialPacket> ParseDataPackets()
{
List<SerialPacket> packets = new List<SerialPacket>();
int startIndex = 0;
while (true)
{
int endIndex = buffer.IndexOf(0x0D, startIndex);
if (endIndex == -1)
break;
if (endIndex + 1 < buffer.Count && buffer[endIndex + 1] == 0x0A)
{
int packetLength = endIndex - startIndex;
byte[] packetData = buffer.GetRange(startIndex, packetLength).ToArray();
packets.Add(new SerialPacket { Length = packetLength, Data = packetData });
startIndex = endIndex + 2; // 跳过结束符
}
else
{
startIndex = endIndex + 1;
}
}
// 将未处理的数据移到缓冲区开头
buffer.RemoveRange(0, startIndex);
return packets;
}
四、处理数据包
在获取到完整的数据包后,可以对其进行相应的处理。
示例代码:
private void ProcessDataPackets(List<SerialPacket> packets)
{
foreach (var packet in packets)
{
// 对数据包进行处理
ProcessPacket(packet.Data);
}
}
private void ProcessPacket(byte[] packetData)
{
// 对数据包进行解析和处理
// ...
}
五、定期清理缓存
如果缓存中一直存在未处理的数据,可以定期清理缓存以防止内存消耗过高。
示例代码:
private void CleanupBuffer()
{
if (buffer.Count > 1024 * 1024) // 缓存超过 1MB
{
buffer.Clear();
}
}
通过上述方法,您可以在 SerialPort_DataReceived 事件中持续读取串口数据,并在缓存中查找完整的数据包。在找到完整的数据包后,将其从缓存中移除并进行相应的处理。同时,您也可以定期清理缓存以防止内存消耗过高。
这种设计可以有效地处理串口数据中存在 0D 0A 结束符的情况,确保应用程序能够正确地接收和处理完整的数据包。
标签:0D0A,缓存,符号,buffer,List,startIndex,endIndex,串口,数据包 From: https://blog.csdn.net/weixin_38812575/article/details/141497573