From f4c65a2b0faa63fbb67baa06ac40262558c39d75 Mon Sep 17 00:00:00 2001
From: "747575620@qq.com" <747575620@qq.com>
Date: Thu, 22 Sep 2022 10:59:30 +0800
Subject: [PATCH] =?UTF-8?q?RS485=E8=AF=BB=E5=8D=A1=E5=99=A8=E6=A8=A1?=
=?UTF-8?q?=E5=9D=97=E7=BC=96=E5=86=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
UHFHelper/UHFCommon.cs | 71 +++++++++++-
UHFHelper/UHFHelper.csproj | 4 +
UHFHelper/UHF_RS485_Helper.cs | 197 ++++++++++++++++++++++++++++++++++
test/Form1.Designer.cs | 60 +++++++++++
test/Form1.cs | 39 ++++++-
5 files changed, 369 insertions(+), 2 deletions(-)
create mode 100644 UHFHelper/UHF_RS485_Helper.cs
diff --git a/UHFHelper/UHFCommon.cs b/UHFHelper/UHFCommon.cs
index 0d7227b..eb11577 100644
--- a/UHFHelper/UHFCommon.cs
+++ b/UHFHelper/UHFCommon.cs
@@ -1,11 +1,46 @@
-namespace UHFHelper
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace UHFHelper
{
+
+ public static class UHFHelper
+ {
+ ///
+ /// 解析数据
+ ///
+ ///
+ ///
+ public static string ByteArrayToHexString(this byte[] data)
+ {
+ StringBuilder sb = new(data.Length * 3);
+ foreach (byte b in data)
+ sb.Append(Convert.ToString(b, 16).PadLeft(2, '0'));
+ return sb.ToString().ToUpper();
+
+ }
+ }
+
public class Resultoutput
{
public bool Res { get; set; }
public string? ResMes { get; set; }
}
+
+
+ public class DKoutput
+ {
+ ///
+ /// 刷卡机地址
+ ///
+ public string? Address { get; set; }
+ ///
+ /// 刷卡器数据
+ ///
+ public string? ResData { get; set; }
+ }
+
///
/// 蜂鸣开关
///
@@ -15,4 +50,38 @@
open=0,
close=1,
}
+ ///
+ /// CRC算法
+ ///
+ public class CRC16
+ {
+ ///
+ /// CRC算法
+ ///
+ ///
+ ///
+ public static byte[] ToCRC16(byte[] pucY)
+ {
+ ushort uiCrcValue = 0xFFFF;
+ for ( int ucI = 0; ucI < pucY.Length; ucI++)
+ {
+ uiCrcValue = Convert.ToUInt16(uiCrcValue ^ pucY[ucI]);
+ for ( int ucJ = 0; ucJ < 8; ucJ++)
+ {
+ if ((uiCrcValue & 0x0001)==1)
+ {
+ uiCrcValue =Convert.ToUInt16((uiCrcValue >> 1) ^ 0x8408);
+ }
+ else
+ {
+ uiCrcValue = Convert.ToUInt16((uiCrcValue >> 1));
+ }
+ }
+ }
+ byte[] tem = new byte[2];
+ tem[0] = (byte)uiCrcValue;
+ tem[1] = (byte)(uiCrcValue >> 8);
+ return tem;
+ }
+ }
}
diff --git a/UHFHelper/UHFHelper.csproj b/UHFHelper/UHFHelper.csproj
index 14ee644..1b84fdc 100644
--- a/UHFHelper/UHFHelper.csproj
+++ b/UHFHelper/UHFHelper.csproj
@@ -7,6 +7,10 @@
AnyCPU;x86
+
+
+
+
..\lib\UHFReader18CSharp.dll
diff --git a/UHFHelper/UHF_RS485_Helper.cs b/UHFHelper/UHF_RS485_Helper.cs
new file mode 100644
index 0000000..2d2bec3
--- /dev/null
+++ b/UHFHelper/UHF_RS485_Helper.cs
@@ -0,0 +1,197 @@
+using System.Diagnostics;
+using System.IO.Ports;
+
+namespace UHFHelper
+{
+ public class UHF_RS485_Helper
+ {
+ private SerialPort? _serialPort;
+ private SerialParam? _serialParam;
+
+ ///
+ /// 单例模式
+ ///
+ 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)
+ {
+ _serialParam = param;
+ _serialPort = new SerialPort(_serialParam.PortName, _serialParam.BaudRate, _serialParam.PortParity, _serialParam.DataBits);
+ _serialPort.Open();
+
+ }
+ ///
+ /// 获取串口状态
+ ///
+ ///
+ public bool GetSerialPortState()
+ {
+ if (_serialPort!=null)
+ {
+ return _serialPort.IsOpen;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ ///
+ /// 关闭串口
+ ///
+ public void Close()
+ {
+ if (_serialPort == null) return;
+ _serialPort.Close();
+ _serialPort.Dispose();
+ _serialPort = null;
+ }
+ ///
+ /// 读卡方法,返回读卡器数据
+ ///
+ /// 设备读取地址
+ ///
+ public async Task ReadCard(int adr)
+ {
+ DKoutput dKoutput = new();
+ var readByte = ReadByte(adr);
+ var result = await SendMessageAsync(readByte, TimeSpan.FromSeconds(1), 18);
+ if (result == null)
+ {
+ return null;
+ }
+ else
+ {
+ //获取校验码
+ var crc = result.Skip(16).Take(2).ToArray();
+ //获取卡号
+ var cardNo = result.Skip(6).Take(16).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;
+ }
+ }
+ }
+ ///
+ /// 生成读取命令
+ ///
+ ///
+ 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, TimeSpan timeout, int count)
+ {
+ if (_serialPort == null) return null;
+ var stopwatch = Stopwatch.StartNew();
+ var originalWriteTimeout = _serialPort.WriteTimeout;
+ var originalReadTimeout = _serialPort.ReadTimeout;
+ try
+ {
+
+ _serialPort.WriteTimeout = (int)Math.Max((timeout - stopwatch.Elapsed).TotalMilliseconds, 0);
+ _serialPort.Write(msg, 0, msg.Length);
+
+ var tmpCount = count;
+ byte[] buffer = new byte[tmpCount];
+ int offset = 0;
+ while (tmpCount > 0)
+ {
+ _serialPort.ReadTimeout = (int)Math.Max((timeout - stopwatch.Elapsed).TotalMilliseconds, 0);
+ var readCount = _serialPort.Read(buffer, offset, tmpCount);
+ if (readCount==6)
+ {
+ tmpCount = 0;
+ continue;
+ }
+ offset += readCount;
+ tmpCount -= readCount;
+ }
+ _serialPort.DiscardInBuffer();
+ return buffer;
+ }catch(Exception ex)
+ {
+ return null;
+ }
+ finally
+ {
+ _serialPort.ReadTimeout = originalReadTimeout;
+ _serialPort.WriteTimeout = originalWriteTimeout;
+ }
+ }
+
+ ///
+ /// 发送数据
+ ///
+ /// 数据
+ /// 超时时间
+ /// 串口回复字节数
+ ///
+ 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)
+ {
+ throw new TimeoutException();
+ }
+ return await sendTask;
+ }
+ }
+
+ 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;
+ }
+}
diff --git a/test/Form1.Designer.cs b/test/Form1.Designer.cs
index aa02f2f..c69e3fd 100644
--- a/test/Form1.Designer.cs
+++ b/test/Form1.Designer.cs
@@ -34,6 +34,11 @@
this.button3 = new System.Windows.Forms.Button();
this.button4 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
+ this.button5 = new System.Windows.Forms.Button();
+ this.comboBox1 = new System.Windows.Forms.ComboBox();
+ this.button6 = new System.Windows.Forms.Button();
+ this.label2 = new System.Windows.Forms.Label();
+ this.textBox4 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// button1
@@ -92,11 +97,60 @@
this.textBox1.Size = new System.Drawing.Size(100, 23);
this.textBox1.TabIndex = 4;
//
+ // button5
+ //
+ this.button5.Location = new System.Drawing.Point(55, 323);
+ this.button5.Name = "button5";
+ this.button5.Size = new System.Drawing.Size(108, 23);
+ this.button5.TabIndex = 5;
+ this.button5.Text = "rs485打开串口";
+ this.button5.UseVisualStyleBackColor = true;
+ this.button5.Click += new System.EventHandler(this.button5_Click);
+ //
+ // comboBox1
+ //
+ this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboBox1.FormattingEnabled = true;
+ this.comboBox1.Location = new System.Drawing.Point(178, 323);
+ this.comboBox1.Name = "comboBox1";
+ this.comboBox1.Size = new System.Drawing.Size(121, 25);
+ this.comboBox1.TabIndex = 6;
+ //
+ // button6
+ //
+ this.button6.Location = new System.Drawing.Point(322, 323);
+ this.button6.Name = "button6";
+ this.button6.Size = new System.Drawing.Size(75, 23);
+ this.button6.TabIndex = 7;
+ this.button6.Text = "读取";
+ this.button6.UseVisualStyleBackColor = true;
+ this.button6.Click += new System.EventHandler(this.button6_Click);
+ //
+ // label2
+ //
+ this.label2.Location = new System.Drawing.Point(451, 324);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(266, 23);
+ this.label2.TabIndex = 8;
+ this.label2.Text = "label2";
+ //
+ // textBox4
+ //
+ this.textBox4.Location = new System.Drawing.Point(451, 369);
+ this.textBox4.Name = "textBox4";
+ this.textBox4.Size = new System.Drawing.Size(100, 23);
+ this.textBox4.TabIndex = 9;
+ //
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
+ this.Controls.Add(this.textBox4);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.button6);
+ this.Controls.Add(this.comboBox1);
+ this.Controls.Add(this.button5);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button4);
this.Controls.Add(this.label1);
@@ -105,6 +159,7 @@
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
+ this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
this.PerformLayout();
@@ -118,5 +173,10 @@
private Button button3;
private Button button4;
private TextBox textBox1;
+ private Button button5;
+ private ComboBox comboBox1;
+ private Button button6;
+ private Label label2;
+ private TextBox textBox4;
}
}
\ No newline at end of file
diff --git a/test/Form1.cs b/test/Form1.cs
index 7d8fae8..d95eff4 100644
--- a/test/Form1.cs
+++ b/test/Form1.cs
@@ -1,3 +1,4 @@
+using System.Text;
using UHFHelper;
namespace test
@@ -44,8 +45,44 @@ namespace test
private void button4_Click(object sender, EventArgs e)
{
- var res = UHFCardHelper.GetInstance().WriteCard(textBox1.Text);
+ var res = UHFCardHelper.GetInstance().WriteCard(textBox1.Text);
MessageBox.Show(res.ResMes);
}
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+
+ //// 鿴ô
+ //foreach (var val in UHF_RS485_Helper.GetLocalSerialPortNames())
+ //{
+ // this.comboBox1.Items.Add(val);
+ //}
+ }
+ UHF_RS485_Helper uHF_RS485_Helper;
+ private void button5_Click(object sender, EventArgs e)
+ {
+ // ʼ
+ UHF_RS485_Helper.GetInstance().Open(new SerialParam
+ {
+ PortName = "COM5",
+ BaudRate = 57600,
+ DataBits = 8
+ });
+ if (!UHF_RS485_Helper.GetInstance().GetSerialPortState())
+ {
+ MessageBox.Show("ʧ");
+ }
+ }
+
+ private async void button6_Click(object sender, EventArgs e)
+ {
+ if (UHF_RS485_Helper.GetInstance().GetSerialPortState())
+ {
+ var oldss = await UHF_RS485_Helper.GetInstance().ReadCard(01);
+ var sss = oldss?.ResData;
+ textBox4.Text = sss;
+ label2.Text = sss;
+ }
+ }
}
}
\ No newline at end of file