|
|
|
@ -0,0 +1,146 @@ |
|
|
|
|
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(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |