在C#串口通信中,一发一收的场景,如何处理不同功能码的帧数据比较合理,代码结构好

在 C# 串口通信的一发一收场景里,处理不同功能码的帧数据可采用以下合理的代码结构,它能让代码更具可读性、可维护性和可扩展性。

实现思路

  1. 定义帧结构:创建一个类来表示通信帧,其中包含功能码、数据等信息。
  2. 功能码处理逻辑 :使用字典或者switch语句来根据不同的功能码执行相应的处理逻辑。
  3. 数据接收与解析:在串口接收事件中解析接收到的数据,并根据功能码调用对应的处理方法。
cs 复制代码
using System;
using System.Collections.Generic;
using System.IO.Ports;

// 定义通信帧类
public class CommunicationFrame
{
    public byte FunctionCode { get; set; }
    public byte[] Data { get; set; }

    public CommunicationFrame(byte functionCode, byte[] data)
    {
        FunctionCode = functionCode;
        Data = data;
    }
}

// 定义串口通信类
public class SerialCommunication
{
    private SerialPort serialPort;
    private readonly Dictionary<byte, Action<CommunicationFrame>> frameHandlers = new Dictionary<byte, Action<CommunicationFrame>>();

    public SerialCommunication(string portName, int baudRate)
    {
        serialPort = new SerialPort(portName, baudRate);
        serialPort.DataReceived += SerialPort_DataReceived;
    }

    // 注册功能码处理方法
    public void RegisterHandler(byte functionCode, Action<CommunicationFrame> handler)
    {
        if (!frameHandlers.ContainsKey(functionCode))
        {
            frameHandlers.Add(functionCode, handler);
        }
    }

    // 打开串口
    public void Open()
    {
        if (!serialPort.IsOpen)
        {
            serialPort.Open();
        }
    }

    // 关闭串口
    public void Close()
    {
        if (serialPort.IsOpen)
        {
            serialPort.Close();
        }
    }

    // 发送数据
    public void Send(CommunicationFrame frame)
    {
        if (serialPort.IsOpen)
        {
            byte[] dataToSend = new byte[1 + frame.Data.Length];
            dataToSend[0] = frame.FunctionCode;
            Array.Copy(frame.Data, 0, dataToSend, 1, frame.Data.Length);
            serialPort.Write(dataToSend, 0, dataToSend.Length);
        }
    }

    // 数据接收处理
    private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            if (serialPort.BytesToRead > 0)
            {
                byte functionCode = (byte)serialPort.ReadByte();
                int dataLength = serialPort.BytesToRead;
                byte[] data = new byte[dataLength];
                serialPort.Read(data, 0, dataLength);

                CommunicationFrame frame = new CommunicationFrame(functionCode, data);
                if (frameHandlers.TryGetValue(functionCode, out var handler))
                {
                    handler(frame);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error receiving data: {ex.Message}");
        }
    }
}

class Program
{
    static void Main()
    {
        SerialCommunication serialComm = new SerialCommunication("COM1", 9600);

        // 注册功能码处理方法
        serialComm.RegisterHandler(1, HandleFunctionCode1);
        serialComm.RegisterHandler(2, HandleFunctionCode2);

        serialComm.Open();

        // 发送示例数据
        byte[] data = { 0x01, 0x02, 0x03 };
        CommunicationFrame frameToSend = new CommunicationFrame(1, data);
        serialComm.Send(frameToSend);

        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();
        serialComm.Close();
    }

    // 处理功能码 1 的方法
    static void HandleFunctionCode1(CommunicationFrame frame)
    {
        Console.WriteLine($"Received frame with function code 1. Data length: {frame.Data.Length}");
    }

    // 处理功能码 2 的方法
    static void HandleFunctionCode2(CommunicationFrame frame)
    {
        Console.WriteLine($"Received frame with function code 2. Data length: {frame.Data.Length}");
    }
}
    
相关推荐
Dcs9 分钟前
gRPC性能陷阱:低延迟网络下的客户端瓶颈揭秘
java
探索java20 分钟前
深入解析 Spring 获取 XML 验证模式的过程
xml·java·spring
找不到、了24 分钟前
Java设计模式之<装饰器模式>
java·设计模式·装饰器模式
YouQian77235 分钟前
(AC)Playlist
算法
java叶新东老师36 分钟前
解决windows系统下 idea、CLion 控制台中文乱码问题
java·windows·intellij-idea
算法_小学生1 小时前
决策树(Decision Tree)完整解析:原理 + 数学推导 + 剪枝 + 实战
算法·决策树·剪枝
岁忧1 小时前
(LeetCode 面试经典 150 题 ) 155. 最小栈 (栈)
java·c++·算法·leetcode·面试·go
yourkin6661 小时前
为什么现在 Spring Boot 默认使用 CGLIB 了?
java·开发语言·jvm
这就是佬们吗2 小时前
初识 docker [上]
java·开发语言·笔记·docker·容器
阿华的代码王国2 小时前
【Android】卡片式布局 && 滚动容器ScrollView
android·xml·java·前端·后端·卡片布局·滚动容器