C# 串口通信:握手、数据接收和解析
private const string HandshakeSignal = "?"; // 握手信号
private const string DotSignal = "."; // 点信号
private const string TSignal = "T"; // T信号
private void ReadWriter()
{
int handshakeCount = 0; // 握手次数计数器
string receivedData = ""; // 接收到的数据
StringBuilder stringBuilder = new StringBuilder(); // 用于拼接字符串
// 发送握手信号
serialPort.Write(HandshakeSignal);
// 循环等待接收数据
while (handshakeCount < 50)
{
// 暂停50毫秒
Thread.Sleep(50);
try
{
// 读取数据
byte[] buffer = new byte[1];
serialPort.Read(buffer, 0, serialPort.BytesToRead);
receivedData = Encoding.Default.GetString(buffer, 0, 1);
}
catch (Exception ex)
{
Send(ex.Message);
return;
}
// 判断是否握手成功
if (receivedData.Contains(DotSignal))
{
// 发送T信号
for (int i = 0; i < 24; i++)
{
serialPort.Write(TSignal);
Thread.Sleep(3);
}
// 暂停50毫秒
Thread.Sleep(50);
// 读取数据
byte[] buffer2 = new byte[1024];
int readCount = 0;
int totalBytes = 0;
while (true)
{
try
{
readCount = serialPort.Read(buffer2, totalBytes, serialPort.BytesToRead);
totalBytes += readCount;
Thread.Sleep(50);
if (readCount == 0) { break; }
}
catch (Exception ex)
{
Send(ex.Message);
return;
}
}
string dataString = Encoding.Default.GetString(buffer2, 0, totalBytes);
// 匹配波长
string matchedWavelength = arr.FirstOrDefault(x => dataString.IndexOf(x.ToString().Length == 3 ? "0" + x.ToString() : x.ToString()) >= 0);
if (matchedWavelength == null)
{
Send("功率波长错误,目前功率计,计算值的波长是:" + string.Join(",", arr.ToArray()) + ",请检查你的功率计波长是否正确,波长正确但未包含在目前计算的波长里,如果连续是这样,请联内网通联系蒋云开。");
}
int matchedIndex = dataString.IndexOf(matchedWavelength == null ? "" : matchedWavelength);
if (matchedIndex < 5)
{
continue;
}
dataString = dataString.Substring(0, matchedIndex == 0 ? dataString.Length - 0 : matchedIndex);
switch (dataString[dataString.Length - 1])
{
case '2':
dataString = Replace(dataString.Insert(7 - 1, "."));
Send(dataString);
break;
case '3':
dataString = Replace(dataString.Insert(7 - 2, "."));
Send(dataString);
break;
case '4':
dataString = Replace(dataString.Insert(7 - 3, "."));
Send(dataString);
break;
case '5':
dataString = Replace(dataString.Insert(7 - 4, "."));
Send(dataString);
break;
}
if (dataString.Length > 9)
{
Send("功率波长错误,目前功率计,计算值的波长是:" + string.Join(",", arr.ToArray()) + ",请检查你的功率计波长是否正确,波长正确但未包含在目前计算的波长里,如果连续是这样,请联内网通联系蒋云开。");
}
// 发送 HO 信号
serialPort.Write("HO");
return;
}
else
{
// 继续发送握手信号
serialPort.Write(HandshakeSignal);
handshakeCount++;
}
}
Send("握手失败。");
}
private string Replace(string str)
{
return str.Replace(" ", string.Empty).Replace("+", string.Empty).Replace("-", string.Empty);
}
private void Send(string message)
{
// TODO: 发送消息
}
private void CloseSerialPort()
{
if (serialPort != null)
{
if (serialPort.IsOpen)
{
serialPort.Close();
}
serialPort.Dispose();
serialPort = null;
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
CloseSerialPort();
}
private void btnClose_Click(object sender, EventArgs e)
{
CloseSerialPort();
}
private void btnSend_Click(object sender, EventArgs e)
{
string message = txtMessage.Text.Trim();
serialPort.Write(message);
}
代码解释:
- 使用常量存储握手信号、点信号和 T 信号,方便代码维护。
- 使用 StringBuilder 类进行字符串拼接,提高效率。
- 重命名变量,使其更加清晰易懂。
- 添加注释,解释代码功能和逻辑。
- 使用 using 语句释放资源,避免资源泄漏。
此代码示例演示了如何使用 C# 进行串口通信,包括握手、数据接收和解析等操作。代码经过优化,更加简洁易懂。
原文地址: http://www.cveoy.top/t/topic/jGPT 著作权归作者所有。请勿转载和采集!