Soul2的通用c#类库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
5.3 KiB

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.General.utils {
/// <summary>
/// 串口通信工具类
/// 需要TimerUtils
/// </summary>
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 {
/// <summary>
/// 645协议读取通信地址报文
/// </summary>
public const string _645CommunicationAddress = "FE FE FE FE 68 AA AA AA AA AA AA 68 13 00 DF 16";
}
/// <summary>
/// 打印log
/// </summary>
/// <param name="log"></param>
private static void log(string log) {
if (debug) {
Debug.WriteLine("[GodSerialPortUtils] " + log);
}
}
/// <summary>
/// 查询所有可用串口
/// </summary>
/// <returns>串口名称数组</returns>
public static string[] find() {
return SerialPort.GetPortNames();
}
/// <summary>
/// 当前连接状态
/// </summary>
/// <returns></returns>
public static bool status() {
return gsp != null && gsp.IsOpen != false;
}
/// <summary>
/// 发送报文信息
/// </summary>
/// <param name="data">发送的内容</param>
/// <param name="callback">回调函数,参数为byte[]类型的回信</param>
/// <param name="wait_complete">是否等待回信完成再执行回调函数,默认为否</param>
/// <exception cref="Exception"></exception>
public static void send(byte[] data, Action<byte[]> 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;
}
/// <summary>
/// 打开串口通信
/// </summary>
/// <param name="name">串口名称</param>
/// <param name="baudRate">波特率</param>
/// <param name="parity">校验码</param>
/// <param name="dataBits">数据位</param>
/// <param name="stopBits">停止位</param>
/// <param name="handshake">握手协议</param>
/// <returns></returns>
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();
}
/// <summary>
/// 关闭连接
/// </summary>
/// <returns>是否已关闭</returns>
public static bool close() {
if (gsp == null) {
return true;
}
var r = gsp.Close();
gsp = null;
return r;
}
/// <summary>
/// 16进制加法计算
/// 2位,按空格分割,加负数来算减法
/// </summary>
/// <param name="hexStr">16进制文本</param>
/// <param name="m">增加的值</param>
/// <returns>计算后的文本</returns>
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();
}
}
}