using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using GodSharp.SerialPort.Extensions; using GodSharp.SerialPort; using System.IO.Ports; using System.Text.RegularExpressions; namespace Soul2.SerialPort.utils { /// /// 串口通信工具类 /// public static class GodSerialPortUtils { private static GodSerialPort? gsp = null; public static bool debug = false; public static bool be_sending = false; private static byte[]? back_data; public class Messages { /// /// 645协议读取通信地址报文 /// public const string _645CommunicationAddress = "FE FE FE FE 68 AA AA AA AA AA AA 68 13 00 DF 16"; } /// /// 打印log /// /// private static void log(string log) { if (debug) { Debug.WriteLine("[GodSerialPortUtils] " + log); } } /// /// 查询所有可用串口 /// /// 串口名称数组 public static string[] find() => System.IO.Ports.SerialPort.GetPortNames(); /// /// 当前连接状态 /// /// public static bool status() => (gsp != null && gsp.IsOpen != false); /// /// 发送报文信息 /// /// 发送的内容 /// 回调函数,参数为byte[]类型的回信 /// 是否等待回信完成再执行回调函数,默认为否 /// public static void send(string data, Action callback = null, bool wait_complete = false) => send(data.HexToByte(), callback, wait_complete); /// /// 发送报文信息 /// /// 发送的内容 /// 回调函数,参数为byte[]类型的回信 /// 是否等待回信完成再执行回调函数,默认为否 /// public static void send(byte[] data, Action callback = null, bool wait_complete = false) { if (status() && !be_sending && gsp != null) { // 发送报文并启用 DataReceived 事件 void onBack(GodSerialPort _gsp, byte[] bytes) { string buffer = string.Join("", bytes.Select(b => b.ToString("X2"))); log("收到数据:" + buffer); be_sending = false; if (back_data != null) { back_data = back_data.Concat(bytes).ToArray(); } else { back_data = bytes; } if (!wait_complete || (back_data != null && back_data.Length > 0 && back_data[^1] == 0x16)) { callback?.Invoke(back_data); } } be_sending = true; gsp.Write(data); log($"发送数据:{data.ToHexString()}"); gsp.UseDataReceived(true, onBack); } else if (!status() || gsp == null) { // 连接未建立或者串口对象不存在,则抛出异常 throw new Exception("先连接再发送报文"); } else if (be_sending) { // 上一个报文还未收到回信,则抛出异常 throw new Exception("上一个报文还未收到回信!"); } // 清空 back_data 数组,避免数据混乱 back_data = null; } /// /// 打开串口通信 /// /// 串口名称 /// 波特率 /// 校验码 /// 数据位 /// 停止位 /// 握手协议 /// public static bool open(string name, int baudRate = 9600, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.None, Handshake handshake = Handshake.None) { if (gsp == null) { gsp = new GodSerialPort(name, baudRate, parity, dataBits, stopBits, handshake); } return gsp.Open() & status(); } /// /// 关闭连接 /// /// 是否已关闭 public static bool close() { if (gsp == null) { return true; } var r = gsp.Close(); gsp = null; return r; } /// /// 16进制加法计算 /// 2位,按空格分割,加负数来算减法 /// /// 16进制文本 /// 增加的值 /// 计算后的文本 public static string AddValueToHexString(string hexStr, int m) { // 检查输入字符串是否符合要求 if (!Regex.IsMatch(hexStr, @"^[\da-fA-F]{2}( [\da-fA-F]{2})*$")) { return "=="; } var hexBytes = hexStr.HexToByte(); for (int i = 0; i < hexBytes.Length; i++) { hexBytes[i] = (byte)((int)hexBytes[i] + m); } return hexBytes.ToHexString(); } /// /// 计算校验码 /// /// 当前报文,不应包含校验码的部分 /// public static string CalcChecksum(string msg) { if (msg.StartsWith("FE FE FE FE ")) { msg = msg.Replace("FE FE FE FE ", ""); } // 检查输入字符串是否符合要求 if (!Regex.IsMatch(msg, @"^[\da-fA-F]{2}( [\da-fA-F]{2})*$")) { return "=="; } var bts = msg.Split(' ').Select(b => Convert.ToInt32(b, 16)).ToArray(); var r = (bts.Sum() % 256).ToString("X2"); return r; } } }