소스 검색

RS485读卡器模块编写

Lishi
747575620@qq.com 2 년 전
부모
커밋
f4c65a2b0f
5개의 변경된 파일369개의 추가작업 그리고 2개의 파일을 삭제
  1. +70
    -1
      UHFHelper/UHFCommon.cs
  2. +4
    -0
      UHFHelper/UHFHelper.csproj
  3. +197
    -0
      UHFHelper/UHF_RS485_Helper.cs
  4. +60
    -0
      test/Form1.Designer.cs
  5. +38
    -1
      test/Form1.cs

+ 70
- 1
UHFHelper/UHFCommon.cs 파일 보기

@@ -1,11 +1,46 @@
namespace UHFHelper
using System.Runtime.InteropServices;
using System.Text;

namespace UHFHelper
{

public static class UHFHelper
{
/// <summary>
/// 解析数据
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
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
{
/// <summary>
/// 刷卡机地址
/// </summary>
public string? Address { get; set; }
/// <summary>
/// 刷卡器数据
/// </summary>
public string? ResData { get; set; }
}

/// <summary>
/// 蜂鸣开关
/// </summary>
@@ -15,4 +50,38 @@
open=0,
close=1,
}
/// <summary>
/// CRC算法
/// </summary>
public class CRC16
{
/// <summary>
/// CRC算法
/// </summary>
/// <param name="pucY"></param>
/// <returns></returns>
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;
}
}
}

+ 4
- 0
UHFHelper/UHFHelper.csproj 파일 보기

@@ -7,6 +7,10 @@
<Platforms>AnyCPU;x86</Platforms>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.IO.Ports" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
<Reference Include="UHFReader18CSharp">
<HintPath>..\lib\UHFReader18CSharp.dll</HintPath>


+ 197
- 0
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;

/// <summary>
/// 单例模式
/// </summary>
private static UHF_RS485_Helper? Instance { get; set; }
public static UHF_RS485_Helper GetInstance()
{
if (Instance == null)
{
Instance = new UHF_RS485_Helper();
}
return Instance;
}
/// <summary>
/// 打开串口
/// </summary>
/// <param name="param"></param>
public void Open(SerialParam param)
{
_serialParam = param;
_serialPort = new SerialPort(_serialParam.PortName, _serialParam.BaudRate, _serialParam.PortParity, _serialParam.DataBits);
_serialPort.Open();
}
/// <summary>
/// 获取串口状态
/// </summary>
/// <returns></returns>
public bool GetSerialPortState()
{
if (_serialPort!=null)
{
return _serialPort.IsOpen;
}
else
{
return false;
}
}
/// <summary>
/// 关闭串口
/// </summary>
public void Close()
{
if (_serialPort == null) return;
_serialPort.Close();
_serialPort.Dispose();
_serialPort = null;
}
/// <summary>
/// 读卡方法,返回读卡器数据
/// </summary>
/// <param name="adr">设备读取地址</param>
/// <returns></returns>
public async Task<DKoutput?> 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;
}
}
}
/// <summary>
/// 生成读取命令
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// 获取本机可用串口
/// </summary>
/// <returns></returns>
public string[] GetLocalSerialPortNames()
{
return SerialPort.GetPortNames();
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="msg">数据</param>
/// <param name="timeout">超时时间</param>
/// <param name="count">串口回复字节数</param>
/// <returns></returns>
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;
}
}

/// <summary>
/// 发送数据
/// </summary>
/// <param name="msg">数据</param>
/// <param name="timeout">超时时间</param>
/// <param name="count">串口回复字节数</param>
/// <returns></returns>
public async Task<byte[]> 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;
}
}

+ 60
- 0
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;
}
}

+ 38
- 1
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;
}
}
}
}

불러오는 중...
취소
저장