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

在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}");}
}

相关文章:

  • vue | 不同 vue 版本对复杂泛型的支持情况 · vue3.2 VS vue3.5
  • 文件【Linux操作系统】
  • JAVA猜数小游戏
  • Unity-无限滚动列表实现Timer时间管理实现
  • 不开启手机调试模式如何开发自动化脚本?
  • Linux程序地址空间
  • Git远程操作与标签管理
  • SpringCloud组件——Eureka
  • C语言对n进制的处理
  • Vue指令详解:从入门到精通
  • [创业之路-381]:企业法务 - 企业经营者,有哪些生产安全风险,哪些人承担责任?承担哪些责任?如何防范?
  • MySQL基本查询与数据操作全面解析
  • C++抽象基类定义与使用
  • 第四届商师校赛 web 1
  • Varjo-XR3在UE5中,头显中间有一个方块一直显示
  • 深度学习 从入门到精通 day_05
  • 学 Python 需要安装哪些软件?全面工具指南
  • C语言教程(十二):C 语言数组详解
  • Linux mmp文件映射补充(自用)
  • AlmaLinux 9.5 调整home和根分区大小
  • 水利部启动实施蓄滞洪区建设管理三年行动
  • 停止水资源共享、驱逐武官,印度对巴基斯坦宣布多项反制措施
  • 中华人民共和国和阿塞拜疆共和国关于建立全面战略伙伴关系的联合声明
  • 杨国荣丨《儒耶对话与中国现代思想的生成和发展》序
  • 深一度|王励勤二次创业从未停步,带领中国乒乓直面挑战
  • 从香料到文化,跟着陈晓卿寻味厦门