在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}");
    }
}
    
相关推荐
LuminousCPP4 小时前
单链表专题(四)-刷题复盘篇-LeetCode 138 随机链表复制|原地拷贝法突破复杂指针操作
数据结构·笔记·算法·leetcode·链表
chuan.bai4 小时前
Java RAG 实战(第 8 篇):Spring Boot RAG 查询 API
java·spring boot·贪心算法
FlyWIHTSKY4 小时前
idea中集成claude功能
java·ide·人工智能·intellij-idea·cloudera
Java成神之路-4 小时前
Spring AI 统一结构化返回:ChatModel / ChatClient 两种实现方式
java·springaialibaba
Mr. zhihao4 小时前
深度解析:为什么Java序列化需要搭配ByteArrayOutputStream?IO装饰器模式的精妙设计
java·开发语言·装饰器模式
逆境不可逃4 小时前
【LeetCode 912】排序数组——随机化快速排序详解
数据结构·算法·排序算法
Coder-magician4 小时前
《代码随想录》刷题打卡day31:动态规划-背包问题part02
算法·动态规划
薛定e的猫咪4 小时前
从因果视角解决多智能体协作:细读 SCIC 算法
算法
存在morning4 小时前
【Python 开发实践 一】Python vs Go vs Java 三门语言对比
java·python·golang
c238564 小时前
《算法武林谱:四大排序神功与二分寻宝术全解》
数据结构·算法·排序算法