在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}");
    }
}
    
相关推荐
To_OC7 小时前
LC 51 N 皇后:我以为难的是回溯,结果栽在了对角线下标
javascript·算法·leetcode
腻害兔7 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
2401_841495647 小时前
【操作系统】进程同步与互斥实验报告
c++·算法·操作系统·进程·并发·同步·互斥
码智社8 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
萧瑟余晖9 小时前
JDK 26 新特性详解
java·开发语言
马优晨9 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
爱刷碗的苏泓舒11 小时前
PPP-AR 中的参考星选取:数学原理、评价指标与切换处理
算法·gnss·模糊度固定·ppp-ar·星间单差·参考星·卫星端偏差
维天说12 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zane199412 小时前
并发 vs 并行:别再傻傻分不清了,一文讲透 Java 并发编程的第一课
java·后端