当前位置: 首页 > ds >正文

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

 

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

实现思路

  1. 定义帧结构:创建一个类来表示通信帧,其中包含功能码、数据等信息。
  2. 功能码处理逻辑:使用字典或者switch语句来根据不同的功能码执行相应的处理逻辑。
  3. 数据接收与解析:在串口接收事件中解析接收到的数据,并根据功能码调用对应的处理方法。
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}");}
}

http://www.xdnf.cn/news/1355.html

相关文章:

  • Transformer:引领深度学习新时代的架构
  • 深入探究Python中`__init__.py`文件的奥秘
  • SOA半导体光放大器在光纤光栅解调系统中的应用分析
  • python三维矩阵的维度
  • 将输入帧上下文打包到下一个帧的预测模型中用于视频生成
  • 什么是区块?
  • 【Java】Hibernate的检索方式的概述
  • pytest心得体会
  • Linux避免文件误删详解(Linux Avoids File Deletion Errors with Detailed Explanation)
  • 深入剖析TCP协议(内容一):从OSI与TCP/IP网络模型到三次握手、四次挥手、状态管理、性能优化及Linux内核源码实现的全面技术指南
  • Python----深度学习(神经网络的过拟合解决方案)
  • 单调栈-每日温度
  • 1、AI及LLM基础:OpenAI 开发
  • 手写深拷贝函数
  • 基于RabbitMQ实现订单超时自动处理
  • 服务器编译环境配置及数据接收脚本编写(11)
  • 蓝桥杯 19. 最大比例
  • 【3】CICD持续集成-k8s集群中安装Jenkins-agent(主从架构)
  • 【数据可视化-24】巧克力销售数据的多维度可视化分析
  • 解读大型语言模型:从Transformer架构到模型量化技术
  • 3小时速通Python-Python学习总部署、总预览(一)
  • transformer 解码器和输出部分结构
  • gradle可用的下载地址(免费)
  • Linux 内核中 cgroup 子系统 cpuset 是什么?
  • nodejs模块暴露数据的方式,和引入(导入方式)方式
  • 高级java每日一道面试题-2025年4月21日-基础篇[反射篇]-如何使用反射获取一个类的所有方法?
  • 移动通信运营商对MTU的大小设置需求
  • 【codeforces思维题】前缀和的巧妙应用(2053B)
  • 【AI News | 20250422】每日AI进展
  • 计算机组成原理---总线系统的详细概述