using System.Diagnostics; using System.IO.Ports; namespace UHFHelper { public class UHF_RS485_Helper { private SerialPort? _serialPort; private SerialParam? _serialParam; public Action OpenOk { get; set; } public Action DisConnect { get; set; } /// /// 单例模式 /// private static UHF_RS485_Helper? Instance { get; set; } public static UHF_RS485_Helper GetInstance() { if (Instance == null) { Instance = new UHF_RS485_Helper(); } return Instance; } /// /// 打开串口 /// /// public void Open(SerialParam param) { if (SerialPort.GetPortNames().Contains(param.PortName)) { _serialParam = param; _serialPort = new SerialPort(_serialParam.PortName, _serialParam.BaudRate, _serialParam.PortParity, _serialParam.DataBits); try { _serialPort.Open(); if (_serialPort.IsOpen) OpenOk?.Invoke(); } catch (Exception) { } } } /// /// 获取串口状态 /// /// public bool GetSerialPortState() { if (_serialPort != null) { return _serialPort.IsOpen; } else { DisConnect?.Invoke(); return false; } } /// /// 关闭串口 /// public void Close() { if (_serialPort == null) return; _serialPort.Close(); _serialPort.Dispose(); _serialPort = null; } private object async = new object(); /// /// 读卡方法,返回读卡器数据 /// /// 设备读取地址 /// public DKoutput? ReadCard(int adr) { lock (async) { try { if (_serialPort == null) return null; DKoutput dKoutput = new(); var readByte = ReadByte(adr); _serialPort.Write(readByte, 0, readByte.Length); var result = SendMessage(readByte, 150, 18); if (result == null) { return null; } else { //获取校验码 var crc = result.Skip(16).Take(2).ToArray(); //获取卡号 var cardNo = result.Skip(6).Take(10).ToArray(); //获取读卡器数据 var readData = result.Skip(0).Take(16).ToArray(); //获取读卡器地址 var address = result.Skip(1).Take(1).ToArray(); //判断数据是否合法 var temcrc = CRC16.ToCRC16(readData); if (crc.ByteArrayToHexString() == temcrc.ByteArrayToHexString()) { dKoutput.Address = address.ByteArrayToHexString(); dKoutput.ResData = cardNo.ByteArrayToHexString(); return dKoutput; } else { return null; } } } catch (Exception ex) { return null; } } } /// /// 生成读取命令 /// /// private byte[] ReadByte(int adr) { //根据读取地址生成读取命令 byte[] data1 = new byte[3] { 04, (byte)adr, 01 }; //生成crc校验码 byte[] data2 = CRC16.ToCRC16(data1); byte[] data3 = new byte[data1.Length + data2.Length]; data1.CopyTo(data3, 0); data2.CopyTo(data3, data1.Length); return data3; } /// /// 获取本机可用串口 /// /// public string[] GetLocalSerialPortNames() { return SerialPort.GetPortNames(); } /// /// 发送数据 /// /// 数据 /// 超时时间 /// 串口回复字节数 /// public byte[]? SendMessage(byte[] msg, long timeout, int count) { if (_serialPort == null) return null; var stopwatch = Stopwatch.StartNew(); try { _serialPort.DiscardInBuffer(); _serialPort.Write(msg, 0, msg.Length); var tmpCount = count; byte[] buffer = new byte[tmpCount]; int offset = 0; while (tmpCount > 0) { if (stopwatch.ElapsedMilliseconds >= timeout) { return null; } int res = _serialPort.BytesToRead; if (res > 0) { var readCount = _serialPort.Read(buffer, offset, tmpCount); if (buffer.Skip(0).Take(1).ToArray().ByteArrayToHexString() == "05") { return null; } offset += readCount; tmpCount -= readCount; } } return buffer; } catch (Exception ex) { return null; } } /// /// 发送数据 /// public void SendMessage(int adr) { var readByte = ReadByte(adr); if (_serialPort == null) return; _serialPort.Write(readByte, 0, readByte.Length); } /// /// 读取数据 /// /// public byte[]? GetMessage(int count, long timeout) { if (_serialPort == null) return null; var stopwatch = Stopwatch.StartNew(); try { _serialPort.DiscardInBuffer(); var tmpCount = count; byte[] buffer = new byte[tmpCount]; int offset = 0; while (tmpCount > 0) { var readCount = _serialPort.Read(buffer, offset, tmpCount); if (readCount == 6) { tmpCount = 0; continue; } offset += readCount; tmpCount -= readCount; if (stopwatch.ElapsedMilliseconds >= timeout) { return null; } } return buffer; } catch (Exception ex) { return null; } } private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { throw new NotImplementedException(); } ///// ///// 发送数据 ///// ///// 数据 ///// 超时时间 ///// 串口回复字节数 ///// //public async Task SendMessageAsync(byte[] msg, TimeSpan timeout, int count) //{ // var sendTask = Task.Run(() => SendMessage(msg, timeout, count)); // //try // //{ // // await Task.WhenAny(sendTask, Task.Delay(timeout)); // //} // //catch (TaskCanceledException) // //{ // // return null; // //} // return await sendTask; //} /// /// 发出蜂鸣声音3次,代表扣款成功! /// public void OpenBeep(int addr) { //byte[] sendData = new byte[] { 0x07, (byte)addr, 0x33, 0x08, 0x02, 0x03, 0x33, 0xB1 }; byte[] data1 = new byte[6] { 0x07, (byte)addr, 0x33, 0x08, 0x02, 0x03 }; //生成crc校验码 byte[] data2 = CRC16.ToCRC16(data1); byte[] data3 = new byte[data1.Length + data2.Length]; data1.CopyTo(data3, 0); data2.CopyTo(data3, data1.Length); if (_serialPort != null) { _serialPort.DiscardInBuffer(); _serialPort.Write(data3, 0, data3.Length); } } } public class SerialParam { public string PortName { get; set; } = "COM3"; public int BaudRate { get; set; } = 57600; public int DataBits { get; set; } = 8; public Parity PortParity { get; set; } = Parity.None; public StopBits PortStopBits { get; set; } = StopBits.One; } }