代码拉取完成,页面将自动刷新
using System;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;
using System.Collections.Generic;
namespace UHFReaderDemo
{
public class UHFReader
{
#region PrivateProperty
private static SerialPort serialport;
private static Thread RcvThread;
private static System.Threading.EventWaitHandle ewh;
private static Byte temp_Command, temp_Status;
private static Byte[] temp_Payload;
///////////////////////////////////////////////////////////////
private static Thread ReportThread;
private static String tempDirection;
private static Byte[] tempFrameData;
private static System.Threading.EventWaitHandle ewh1;
///////////////////////////////////////////////////////////////
#endregion
#region PublicProperty
/// <summary>
/// 用于指示与读写器连接的串口是否打开。
/// </summary>
public static Boolean IsOpen
{
get
{
try
{
if (serialport == null) return false;
return serialport.IsOpen;
}
catch { return false; }
}
}
#endregion
#region Public Event
public delegate void TagDetectedDel(Byte Command, Byte Status, Byte[] TagUII);
public static event TagDetectedDel TagDetected;
public delegate void ReturnSelectRecordDel(Byte Command, Byte Status, Byte[] SelectRecord);
public static event ReturnSelectRecordDel ReturnSelectRecord;
public delegate void AdvancedInventoryCompleteDel(Byte Command, Byte Status, Int32 TagNumber);
public static event AdvancedInventoryCompleteDel AdvancedInventoryComplete;
public delegate void ReturnTagRecordDel(Byte Command, Byte Status, Byte[] TagRecord);
public static event ReturnTagRecordDel ReturnTagRecord;
////////////////////////////////////////////////////
public delegate void SendAndReceiveDel(String Direction, Byte[] Frame);
public static event SendAndReceiveDel SendAndReceive;
////////////////////////////////////////////////////
#endregion
#region PublicMethod
/// <summary>
/// 打开与设备连接的串口
/// </summary>
/// <param name="PortName">串口号,如"COM3"</param>
/// <param name="BaudRate">波特率,默认为57600</param>
/// <returns>0x00:打开成功;0x01:打开失败,原因是已经处于打开状态;0x02:打开失败,原因是串口不存在等等。
/// </returns>
public static ErrorCode OpenAndConnect(String PortName, Int32 BaudRate)
{
if (IsOpen)
{ return ErrorCode.AllDone; }
try
{
serialport = new SerialPort(PortName, BaudRate, Parity.None, 8, StopBits.One);
serialport.ReadTimeout = 500;
serialport.Open();
if (IsOpen)
{
ewh = new System.Threading.EventWaitHandle(false, EventResetMode.ManualReset);
RcvThread = new Thread(new ThreadStart(RcvData));
RcvThread.IsBackground = true;
RcvThread.Start();
/////////////////////////////////////////////////////
ewh1 = new System.Threading.EventWaitHandle(false, EventResetMode.AutoReset);
ReportThread = new Thread(new ThreadStart(ReportFrame));
ReportThread.IsBackground = true;
ReportThread.Start();
/////////////////////////////////////////////////////
return ErrorCode.AllDone;
}
else
{ return ErrorCode.SerialPortError; }
}
catch { return ErrorCode.SerialPortError; }
}
public static ErrorCode OpenAndConnect(String PortName)
{
return OpenAndConnect(PortName, 57600);
}
/// <summary>
/// 关闭串口
/// </summary>
/// <returns>0x00:关闭成功;0x01:关闭失败,原因是尚未打开;0x02:关闭操作执行失败。
/// </returns>
public static ErrorCode CloseAndDisconnect()
{
if (!IsOpen)
{
return ErrorCode.AllDone;
}
try
{
serialport.Close();
if (!IsOpen)
{ return ErrorCode.AllDone; }
else
{ return ErrorCode.SerialPortError; }
}
catch
{ return ErrorCode.SerialPortError; }
}
/// <summary>
/// 读取与读写器的连接状态
/// </summary>
/// <param name="PaStatus">布尔型,用于指示是否连接成功</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode GetPaStatus(out Boolean PaStatus, Boolean CRCFlag)
{
PaStatus = false;
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//封装命令帧
Byte[] Frame = EncapFrame(0x00, new Byte[0], CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer();
ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
//if (Command != 0x00)
//{ return ErrorCode.CommandError; }
//if (Payload.Length != 0x00)
//{ return ErrorCode.PayloadError; }
//if ((Status & 0x81) == 0)
//{}
PaStatus = true;
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 获取读写器功率设置
/// </summary>
/// <param name="Power">
/// 读写器返回的功率字节
/// 最高位表示功率控制方式:0代表手动,1代表自动
/// 低7位为输出功率,单位dbm
/// </param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode GetPower(out Byte Power, Boolean CRCFlag)
{
Power = 0x00;
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//封装命令帧
Byte[] Frame = EncapFrame(0x01, new Byte[0], CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer();
ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x01)
{ return ErrorCode.CommandError; }
if (Status != 0x00)
{ return ErrorCode.StatusError; }
if (Payload.Length != 0x01)
{ return ErrorCode.PayloadError; }
Power = Payload[0];
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 设置读写器功率
/// </summary>
/// <param name="Power">
/// 读写器的功率字节
/// 最高位表示功率控制方式:0代表手动,1代表自动
/// 低7位为输出功率,单位dbm
/// </param>
/// <param name="Option">
/// 功率设置控制字节
/// 最低位为输出功率控制位:1表示POWER字节的Bit6~0有效,0表示POWER字节的Bit6~0无效
/// 次低位为功率控制模式控制位:1表示POWER字节的Bit7有效,0表示POWER字节的Bit7无效
/// </param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode SetPower(Byte Power, Byte Option, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//封装命令帧
Byte[] Frame = EncapFrame(0x02, new Byte[] { Option, Power }, CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer();
ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x02)
{ return ErrorCode.CommandError; }
if (Payload.Length != 0x00)
{ return ErrorCode.PayloadError; }
if (Status != 0x00)
{ return ErrorCode.StatusError; }
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 获取读写器频率设置
/// </summary>
/// <param name="Frequency">
/// 读写器的频率设置,长7字节,其中
/// 1:频率工作模式Frequency Mode;
/// 2:频率基数Frequency Base;
/// 3 4:起始频率Begin Frequency;
/// 5:频道数Count;
/// 6:频道带宽SPC;
/// 7:调频顺序方式FREHOP.
/// </param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode GetFrequency(out Byte[] Frequency, Boolean CRCFlag)
{
Frequency = new Byte[0];
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//封装命令帧
Byte[] Frame = EncapFrame(0x05, new Byte[0], CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x05)
{ return ErrorCode.CommandError; }
if (Status != 0x00)
{ return ErrorCode.StatusError; }
if (Payload.Length != 0x07)
{ return ErrorCode.PayloadError; }
Frequency = Payload;
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 设置读写器频率
/// </summary>
/// <param name="Frequency">
/// 读写器的频率设置,长7字节,其中
/// 1:频率工作模式Frequency Mode;
/// 2:频率基数Frequency Base;
/// 3 4:起始频率Begin Frequency;
/// 5:频道数Count;
/// 6:频道带宽SPC;
/// 7:调频顺序方式FREHOP.
/// </param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode SetFrequency(Byte[] Frequency, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//封装命令帧
Byte[] Frame = EncapFrame(0x06, Frequency, CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x06)
{ return ErrorCode.CommandError; }
if (Status != 0x00)
{ return ErrorCode.StatusError; }
if (Payload.Length != 0x00)
{ return ErrorCode.PayloadError; }
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 启动读写器的识别循环
/// </summary>
/// <param name="AntiFlag">
/// 是否启用防碰撞识别功能
/// True:启用防碰撞识别多标签
/// False:不启用防碰撞识别
/// </param>
/// <param name="InitQ">
/// 防碰撞时的初始Q值
/// 仅在启用防碰撞识别时有效
/// 允许的值为0~15,默认值为3
/// </param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode Inventory(Boolean AntiFlag, Byte InitQ, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//封装命令帧
Byte[] Frame;
if (AntiFlag)
{
Frame = EncapFrame(0x11, new Byte[] { InitQ }, CRCFlag);
}
else
{
Frame = EncapFrame(0x10, new Byte[0], CRCFlag);
}
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (!((Command == 0x10) || (Command == 0x11)))
{ return ErrorCode.CommandError; }
if (Status != 0x01)
{ return ErrorCode.StatusError; }
if (Payload.Length != 0x00)
{ return ErrorCode.PayloadError; }
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
///// <summary>
///// 读取读写器返回的标签UII
///// </summary>
///// <param name="UII">读写器返回的标签UII</param>
///// <returns>命令执行情况</returns>
//public static ErrorCode GetReceived(out Byte[] UII)
//{
// UII = new Byte[0];
// if (!IsOpen)
// { return ErrorCode.NotOpenError; }
// Byte Command, Status;
// Byte[] Payload;
// ErrorCode ec = RcvFrame(out Command, out Status, out Payload);
// if (ec != ErrorCode.AllDone)
// { return ec; }
// //分析响应帧数据
// if ((Command != 0x10) || (Command != 0x11))
// { return ErrorCode.CommandError; }
// if (Status != 0x00)
// { return ErrorCode.StatusError; }
// UII = Payload;
// return ErrorCode.AllDone;
//}
/// <summary>
/// 单步识别标签,并读取标签UII
/// </summary>
/// <param name="UII">读写器返回的标签UII</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode InventorySingle(out Byte[] UII, Boolean CRCFlag)
{
UII = new Byte[0];
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//封装命令帧
Byte[] Frame = EncapFrame(0x18, new Byte[0], CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x18)
{ return ErrorCode.CommandError; }
if (Status != 0x00)
{ return ErrorCode.StatusError; }
UII = Payload;
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 停止读写器的当前操作(主要用于停止读写器的Inventory操作)
/// </summary>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode StopInventory(Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//封装命令帧
Byte[] Frame = EncapFrame(0x12, new Byte[0], CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
return ErrorCode.AllDone;
//if (ewh.WaitOne(500, false))
//{
// Byte Command = temp_Command;
// Byte Status = temp_Status;
// Byte[] Payload = temp_Payload;
// //分析响应帧数据
// if (Command != 0x12)
// { return ErrorCode.CommandError; }
// if (Status != 0x00)
// { return ErrorCode.StatusError; }
// return ErrorCode.AllDone;
//}
//else
//{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 读取标签数据(指定UII)
/// </summary>
/// <param name="AccessPassword">访问密钥,4个字节</param>
/// <param name="Bank">数据区类型</param>
/// <param name="Pointer">起始地址的偏移量</param>
/// <param name="Count">数据长度,以字(2Byte)为单位</param>
/// <param name="UII">标签的 UII</param>
/// <param name="Data">返回值,读取到的数据</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode ReadData(Byte[] AccessPassword, Byte Bank, Int32 Pointer, Byte Count, Byte[] UII, out Byte[] Data, Boolean CRCFlag)
{
Data = new Byte[0];
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//把Pointer转换成EBV数据
Byte[] PTR = Int32ToEBV(Pointer);
//构成命令帧payload
List<Byte> CMDPayload = new List<byte>();
for (Int32 i = 0; i < 4; i++)
{ CMDPayload.Add(AccessPassword[i]); }
CMDPayload.Add(Bank);
for (Int32 i = 0; i < PTR.Length; i++)
{ CMDPayload.Add(PTR[i]); }
CMDPayload.Add(Count);
for (Int32 i = 0; i < UII.Length; i++)
{ CMDPayload.Add(UII[i]); }
//封装命令帧
Byte[] Frame = EncapFrame(0x13, CMDPayload.ToArray(), CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
//分析响应帧数据
if (Command != 0x13)
{ return ErrorCode.CommandError; }
if (Status != 0x00)
{
if ((Status == 0x81) && (Payload.Length == 1))
{
switch (Payload[0])
{
case 0x00:
return ErrorCode.OtherErrorCode;
case 0x03:
return ErrorCode.OverflowErrorCode;
case 0x04:
return ErrorCode.LockErrorCode;
case 0x0B:
return ErrorCode.PowerLackErrorCode;
default:
return ErrorCode.UnknownErrorCode;
}
}
else
{
return ErrorCode.StatusError;
}
}
//获取数据
if (Count > 0)
{ Data = Payload; }
else
{
if (Payload.Length > 2)
{
Data = new Byte[Payload.Length - 2];
for (Int32 i = 0; i < Data.Length; i++)
{ Data[i] = Payload[2 + i]; }
}
else
{ Data = Payload; }
}
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 读取标签数据(不指定UII)
/// </summary>
/// <param name="AccessPassword">访问密钥,4个字节</param>
/// <param name="Bank">数据区类型</param>
/// <param name="Pointer">起始地址的偏移量</param>
/// <param name="Count">数据长度,以字(2Byte)为单位</param>
/// <param name="UII">返回值,标签的UII</param>
/// <param name="Data">返回值,读取到的数据</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode ReadDataSingle(Byte[] AccessPassword, Byte Bank, Int32 Pointer, Byte Count, out Byte[] UII, out Byte[] Data, Boolean CRCFlag)
{
Data = new Byte[0];
UII = new Byte[0];
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//把Pointer转换成EBV数据
Byte[] PTR = Int32ToEBV(Pointer);
//构成命令帧payload
List<Byte> CMDPayload = new List<byte>();
for (Int32 i = 0; i < 4; i++)
{ CMDPayload.Add(AccessPassword[i]); }
CMDPayload.Add(Bank);
for (Int32 i = 0; i < PTR.Length; i++)
{ CMDPayload.Add(PTR[i]); }
CMDPayload.Add(Count);
for (Int32 i = 0; i < UII.Length; i++)
{ CMDPayload.Add(UII[i]); }
//封装命令帧
Byte[] Frame = EncapFrame(0x20, CMDPayload.ToArray(), CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x20)
{ return ErrorCode.CommandError; }
if (Status != 0x00)
{
if ((Status == 0x81) && (Payload.Length == 1))
{
switch (Payload[0])
{
case 0x00:
return ErrorCode.OtherErrorCode;
case 0x03:
return ErrorCode.OverflowErrorCode;
case 0x04:
return ErrorCode.LockErrorCode;
case 0x0B:
return ErrorCode.PowerLackErrorCode;
default:
return ErrorCode.UnknownErrorCode;
}
}
else
{
return ErrorCode.StatusError;
}
}
//获取数据
if (Count > 0)
{
Data = new Byte[Count * 2];
for (Int32 i = 0; i < Data.Length; i++)
{ Data[i] = Payload[i]; }
UII = new Byte[Payload.Length - Data.Length];
for (Int32 i = 0; i < UII.Length; i++)
{ UII[i] = Payload[Data.Length + i]; }
}
else
{
Int32 DataLength = Payload[0] * 256 + Payload[1];
Data = new Byte[DataLength];
for (Int32 i = 0; i < Data.Length; i++)
{ Data[i] = Payload[2 + i]; }
UII = new Byte[Payload.Length - DataLength - 2];
for (Int32 i = 0; i < UII.Length; i++)
{ UII[i] = Payload[Data.Length + 2 + i]; }
}
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 写入标签数据(指定UII)
/// </summary>
/// <param name="AccessPassword">访问密钥,4个字节</param>
/// <param name="Bank">数据区类型</param>
/// <param name="Pointer">起始地址的偏移量</param>
/// <param name="Count">数据长度,以字(2Byte)为单位</param>
/// <param name="UII">标签的UII</param>
/// <param name="Data">待写入的数据,长度不小于Count*2</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode WriteData(Byte[] AccessPassword, Byte Bank, Int32 Pointer, Byte Count, Byte[] UII, Byte[] Data, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
if (Data.Length < (Count * 2))
{ return ErrorCode.DataLengthError; }
//把Pointer转换成EBV数据
Byte[] PTR = Int32ToEBV(Pointer);
//构成命令帧payload
List<Byte> CMDPayload = new List<byte>();
for (Int32 i = 0; i < 4; i++)
{ CMDPayload.Add(AccessPassword[i]); }
CMDPayload.Add(Bank);
for (Int32 i = 0; i < PTR.Length; i++)
{ CMDPayload.Add(PTR[i]); }
CMDPayload.Add(Count);
for (Int32 i = 0; i < Count * 2; i++)
{ CMDPayload.Add(Data[i]); }
for (Int32 i = 0; i < UII.Length; i++)
{ CMDPayload.Add(UII[i]); }
//封装命令帧
Byte[] Frame = EncapFrame(0x14, CMDPayload.ToArray(), CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x14)
{ return ErrorCode.CommandError; }
if (Status != 0x00)
{
if ((Status == 0x81) && (Payload.Length == 1))
{
switch (Payload[0])
{
case 0x00:
return ErrorCode.OtherErrorCode;
case 0x03:
return ErrorCode.OverflowErrorCode;
case 0x04:
return ErrorCode.LockErrorCode;
case 0x0B:
return ErrorCode.PowerLackErrorCode;
default:
return ErrorCode.UnknownErrorCode;
}
}
else
{
return ErrorCode.StatusError;
}
}
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 写入标签数据(不指定UII)
/// </summary>
/// <param name="AccessPassword">访问密钥,4个字节</param>
/// <param name="Bank">数据区类型</param>
/// <param name="Pointer">起始地址的偏移量</param>
/// <param name="Count">数据长度,以字(2Byte)为单位</param>
/// <param name="UII">返回值,标签的UII</param>
/// <param name="Data">待写入的数据,长度不小于Count*2</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode WriteDataSingle(Byte[] AccessPassword, Byte Bank, Int32 Pointer, Byte Count, out Byte[] UII, Byte[] Data, Boolean CRCFlag)
{
UII = new Byte[0];
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
if (Data.Length < (Count * 2))
{ return ErrorCode.DataLengthError; }
//把Pointer转换成EBV数据
Byte[] PTR = Int32ToEBV(Pointer);
//构成命令帧payload
List<Byte> CMDPayload = new List<byte>();
for (Int32 i = 0; i < 4; i++)
{ CMDPayload.Add(AccessPassword[i]); }
CMDPayload.Add(Bank);
for (Int32 i = 0; i < PTR.Length; i++)
{ CMDPayload.Add(PTR[i]); }
CMDPayload.Add(Count);
for (Int32 i = 0; i < Count * 2; i++)
{ CMDPayload.Add(Data[i]); }
for (Int32 i = 0; i < UII.Length; i++)
{ CMDPayload.Add(UII[i]); }
//封装命令帧
Byte[] Frame = EncapFrame(0x21, CMDPayload.ToArray(), CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x21)
{ return ErrorCode.CommandError; }
if (Status != 0x00)
{
if ((Status == 0x81) && (Payload.Length == 1))
{
switch (Payload[0])
{
case 0x00:
return ErrorCode.OtherErrorCode;
case 0x03:
return ErrorCode.OverflowErrorCode;
case 0x04:
return ErrorCode.LockErrorCode;
case 0x0B:
return ErrorCode.PowerLackErrorCode;
default:
return ErrorCode.UnknownErrorCode;
}
}
else
{
return ErrorCode.StatusError;
}
}
UII = Payload;
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 擦除标签数据
/// </summary>
/// <param name="AccessPassword">访问密钥,4个字节</param>
/// <param name="Bank">数据区类型</param>
/// <param name="Pointer">起始地址的偏移量</param>
/// <param name="Count">数据长度,以字(2Byte)为单位</param>
/// <param name="UII">标签的UII</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode EraseData(Byte[] AccessPassword, Byte Bank, Int32 Pointer, Byte Count, Byte[] UII, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//把Pointer转换成EBV数据
Byte[] PTR = Int32ToEBV(Pointer);
//构成命令帧payload
List<Byte> CMDPayload = new List<byte>();
for (Int32 i = 0; i < 4; i++)
{ CMDPayload.Add(AccessPassword[i]); }
CMDPayload.Add(Bank);
for (Int32 i = 0; i < PTR.Length; i++)
{ CMDPayload.Add(PTR[i]); }
CMDPayload.Add(Count);
for (Int32 i = 0; i < UII.Length; i++)
{ CMDPayload.Add(UII[i]); }
//封装命令帧
Byte[] Frame = EncapFrame(0x15, CMDPayload.ToArray(), CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x15)
{ return ErrorCode.CommandError; }
if (Status != 0x00)
{
if ((Status == 0x81) && (Payload.Length == 1))
{
switch (Payload[0])
{
case 0x00:
return ErrorCode.OtherErrorCode;
case 0x03:
return ErrorCode.OverflowErrorCode;
case 0x04:
return ErrorCode.LockErrorCode;
case 0x0B:
return ErrorCode.PowerLackErrorCode;
default:
return ErrorCode.UnknownErrorCode;
}
}
else
{
return ErrorCode.StatusError;
}
}
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 锁定标签的指定数据区
/// </summary>
/// <param name="AccessPassword">访问密钥,4个字节</param>
/// <param name="LockData">锁定操作参数,3个字节</param>
/// <param name="UII">标签的UII</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode LockMemory(Byte[] AccessPassword, Byte[] LockData, Byte[] UII, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//构成命令帧payload
List<Byte> CMDPayload = new List<byte>();
for (Int32 i = 0; i < 4; i++)
{ CMDPayload.Add(AccessPassword[i]); }
for (Int32 i = 0; i < 3; i++)
{ CMDPayload.Add(LockData[i]); }
for (Int32 i = 0; i < UII.Length; i++)
{ CMDPayload.Add(UII[i]); }
//封装命令帧
Byte[] Frame = EncapFrame(0x16, CMDPayload.ToArray(), CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x16)
{ return ErrorCode.CommandError; }
if (Status != 0x00)
{
if ((Status == 0x81) && (Payload.Length == 1))
{
switch (Payload[0])
{
case 0x00:
return ErrorCode.OtherErrorCode;
case 0x03:
return ErrorCode.OverflowErrorCode;
case 0x04:
return ErrorCode.LockErrorCode;
case 0x0B:
return ErrorCode.PowerLackErrorCode;
default:
return ErrorCode.UnknownErrorCode;
}
}
else
{
return ErrorCode.StatusError;
}
}
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 销毁指定的标签
/// </summary>
/// <param name="KillPassword">销毁密钥,4个字节</param>
/// <param name="UII">标签的UII</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode KillTag(Byte[] KillPassword, Byte[] UII, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//构成命令帧payload
List<Byte> CMDPayload = new List<byte>();
for (Int32 i = 0; i < 4; i++)
{ CMDPayload.Add(KillPassword[i]); }
for (Int32 i = 0; i < UII.Length; i++)
{ CMDPayload.Add(UII[i]); }
//封装命令帧
Byte[] Frame = EncapFrame(0x17, CMDPayload.ToArray(), CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x17)
{ return ErrorCode.CommandError; }
if (Status != 0x00)
{
if ((Status == 0x81) && (Payload.Length == 1))
{
switch (Payload[0])
{
case 0x00:
return ErrorCode.OtherErrorCode;
case 0x03:
return ErrorCode.OverflowErrorCode;
case 0x04:
return ErrorCode.LockErrorCode;
case 0x0B:
return ErrorCode.PowerLackErrorCode;
default:
return ErrorCode.UnknownErrorCode;
}
}
else
{
return ErrorCode.StatusError;
}
}
return ErrorCode.AllDone;
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// 读取读写器的寄存器数据
/// 注意1:RegAddress+RegLength不能大于512
/// </summary>
/// <param name="RegAddress">寄存器数据的起始地址</param>
/// <param name="RegLength">寄存器数据长度,以字节为单位</param>
/// <param name="RegValue">返回值,返回的寄存器数据</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode ReadReg(Int32 RegAddress, Int32 RegLength, out Byte[] RegValue, Boolean CRCFlag)
{
RegValue = new Byte[0];
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
if ((RegAddress + RegLength) > 512)
{ return ErrorCode.ParameterError; }
//构成命令帧payload
List<Byte> CMDPayload = new List<byte>();
CMDPayload.Add((Byte)(RegAddress / 256));
CMDPayload.Add((Byte)(RegAddress % 256));
CMDPayload.Add((Byte)(RegLength / 256));
CMDPayload.Add((Byte)(RegLength % 256));
//封装命令帧
Byte[] Frame = EncapFrame(0x30, CMDPayload.ToArray(), CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x30)
{ return ErrorCode.CommandError; }
switch (Status)
{
case 0x00:
RegValue = Payload;
return ErrorCode.AllDone;
case 0x81:
return ErrorCode.ParameterError;
default:
return ErrorCode.UnknownError;
}
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 设置读写器的寄存器数据
/// 注意1:RegAddress+RegLength不能大于512
/// 注意2:RegValue的字节长度应等于RegLength
/// </summary>
/// <param name="RegAddress">寄存器数据的起始地址</param>
/// <param name="RegLength">寄存器数据长度,以字节为单位</param>
/// <param name="RegValue">待写入的寄存器数据</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode ReadReg(Int32 RegAddress, Int32 RegLength, Byte[] RegValue, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
if ((RegAddress + RegLength) > 512)
{ return ErrorCode.ParameterError; }
if (RegValue.Length != RegLength)
{ return ErrorCode.DataLengthError; }
//构成命令帧payload
List<Byte> CMDPayload = new List<byte>();
CMDPayload.Add((Byte)(RegAddress / 256));
CMDPayload.Add((Byte)(RegAddress % 256));
CMDPayload.Add((Byte)(RegLength / 256));
CMDPayload.Add((Byte)(RegLength % 256));
for (Int32 i = 0; i < RegValue.Length; i++)
{ CMDPayload.Add(RegValue[i]); }
//封装命令帧
Byte[] Frame = EncapFrame(0x31, CMDPayload.ToArray(), CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x31)
{ return ErrorCode.CommandError; }
switch (Status)
{
case 0x00:
return ErrorCode.AllDone;
case 0x81:
return ErrorCode.ParameterError;
case 0x82:
return ErrorCode.ReadOnlyError;
case 0x83:
return ErrorCode.DataLengthError;
default:
return ErrorCode.UnknownError;
}
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 恢复读写器寄存器的出厂默认值
/// </summary>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode ResetReg(Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//构成命令帧payload
//封装命令帧
Byte[] Frame = EncapFrame(0x32, new Byte[0], CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x32)
{ return ErrorCode.CommandError; }
switch (Status)
{
case 0x00:
return ErrorCode.AllDone;
default:
return ErrorCode.UnknownError;
}
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 将当前用户设置由RAM保存到FLASH,以便掉电重启也能保持
/// 保存的信息包括功率设置、频率设置、BLF设置、波特率设置以及当前寄存器设置
/// </summary>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode SaveReg(Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//构成命令帧payload
//封装命令帧
Byte[] Frame = EncapFrame(0x33, new Byte[0], CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x33)
{ return ErrorCode.CommandError; }
switch (Status)
{
case 0x00:
return ErrorCode.AllDone;
default:
return ErrorCode.UnknownError;
}
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 用于添加Select记录
/// </summary>
/// <param name="SRecord">Select记录数据</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode AddSelect(Byte[] SRecord, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//构成命令帧payload
//封装命令帧
Byte[] Frame = EncapFrame(0x38, SRecord, CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x38)
{ return ErrorCode.CommandError; }
switch (Status)
{
case 0x00:
return ErrorCode.AllDone;
case 0x80:
return ErrorCode.OtherSelectError;
case 0x81:
return ErrorCode.OverflowSelectError;
case 0x82:
return ErrorCode.ReadOnlySelectError;
case 0x83:
return ErrorCode.UnknowSelectError;
default:
return ErrorCode.UnknownError;
}
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 用于删除Select记录
/// </summary>
/// <param name="SRecord">Select记录序号</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode DeleteSelect(Byte SIndex, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//构成命令帧payload
//封装命令帧
Byte[] Frame = EncapFrame(0x39, new Byte[] { SIndex }, CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x39)
{ return ErrorCode.CommandError; }
switch (Status)
{
case 0x00:
return ErrorCode.AllDone;
case 0x80:
return ErrorCode.OtherSelectError;
case 0x81:
return ErrorCode.OverflowSelectError;
case 0x82:
return ErrorCode.ReadOnlySelectError;
case 0x83:
return ErrorCode.UnknowSelectError;
default:
return ErrorCode.UnknownError;
}
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 用于读取Select记录,正常情况下,读写器会返回SNumber+1个响应帧,
/// 第一个响应帧表示读写器正确接收了该命令,
/// 后面的每个数据帧包含一个Select记录,因此需要使用GetSelect获取这些Select记录
/// 当SNumber=0时,读写器会返回所有的Select记录
/// </summary>
/// <param name="SIndex">需要读取的Select记录的起始序号</param>
/// <param name="SNumber">需要读取的Select记录的数量</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode ReadSelect(Byte SIndex, Byte SNumber, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//构成命令帧payload
//封装命令帧
Byte[] Frame = EncapFrame(0x3A, new Byte[] { SIndex, SNumber }, CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x3A)
{ return ErrorCode.CommandError; }
switch (Status)
{
case 0x01:
return ErrorCode.AllDone;
default:
return ErrorCode.UnknownError;
}
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
///// <summary>
///// 用于获取与ReadSelect命令相应的后续响应包中的Select记录
///// </summary>
///// <param name="SRecord">返回值,Select记录数据</param>
///// <param name="IsFollowed">返回值,用于指示后面是否还有包含Select记录的响应包</param>
///// <param name="CRCFlag">CRC标志</param>
///// <returns>命令执行情况</returns>
//public static ErrorCode GetSelect(out Byte[] SRecord,out Boolean IsFollowed, Boolean CRCFlag)
//{
// IsFollowed = false;
// SRecord = new Byte[0];
// if (!IsOpen)
// { return ErrorCode.NotOpenError; }
// //构成命令帧payload
// //封装命令帧
// //Byte[] Frame = EncapFrame(0x3A, new Byte[] { SIndex, SNumber }, CRCFlag);
// //发送命令帧
// //try
// //{
// // serialport.DiscardInBuffer();ewh.Reset();
// // serialport.Write(Frame, 0, Frame.Length);
// //}
// //catch
// //{ return ErrorCode.SendTimeOut; }
// //等待下位机响应
// //Thread.Sleep(500);
// //接收、分析处理响应帧
// Byte Command, Status;
// Byte[] Payload;
// ErrorCode ec = RcvFrame(out Command, out Status, out Payload);
// if (ec != ErrorCode.AllDone)
// { return ec; }
// //分析响应帧数据
// if (Command != 0x3A)
// { return ErrorCode.CommandError; }
// switch (Status)
// {
// case 0x00:
// IsFollowed = true;
// SRecord = Payload;
// return ErrorCode.AllDone;
// case 0x01:
// case 0x02:
// IsFollowed = false;
// SRecord = Payload;
// return ErrorCode.AllDone;
// case 0x03:
// return ErrorCode.SRecordSelectError;
// case 0x80:
// return ErrorCode.OtherSelectError;
// case 0x81:
// return ErrorCode.OverflowSelectError;
// default:
// return ErrorCode.UnknowSelectError;
// }
//}
/// <summary>
/// 用于选择发送的Select命令参数
/// </summary>
/// <param name="SIndex">需要选择的SRecord的起始序号</param>
/// <param name="SNumber">需要选择的SRecord的个数</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode ChooseSelect(Byte SIndex, Byte SNumber, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//构成命令帧payload
//封装命令帧
Byte[] Frame = EncapFrame(0x3B, new Byte[] { SIndex, SNumber }, CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x3B)
{ return ErrorCode.CommandError; }
switch (Status)
{
case 0x00:
return ErrorCode.AllDone;
case 0x80:
return ErrorCode.OverflowSelectError;
default:
return ErrorCode.UnknowSelectError;
}
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
/// <summary>
/// 用于启动高级识别
/// </summary>
/// <param name="SIndex">发送SRecord中的Select命令的起始序号</param>
/// <param name="SNumber">发送SRecord中的Select命令的个数</param>
/// <param name="SST">发送Sel、Session、Target的参数</param>
/// <param name="InitQ">防碰撞起始Q值</param>
/// <param name="CRCFlag">CRC标志</param>
/// <returns>命令执行情况</returns>
public static ErrorCode AdvanceInventory(Byte SIndex, Byte SNumber, Byte SST, Byte InitQ, Boolean CRCFlag)
{
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//构成命令帧payload
//封装命令帧
Byte[] Frame = EncapFrame(0x40, new Byte[] { SIndex, SNumber, SST, InitQ }, CRCFlag);
//发送命令帧
try
{
serialport.DiscardInBuffer(); ewh.Reset();
serialport.Write(Frame, 0, Frame.Length);
}
catch
{ return ErrorCode.SendTimeOut; }
if (ewh.WaitOne(500, false))
{
Byte Command = temp_Command;
Byte Status = temp_Status;
Byte[] Payload = temp_Payload;
//分析响应帧数据
if (Command != 0x40)
{ return ErrorCode.CommandError; }
switch (Status)
{
case 0x00:
return ErrorCode.AllDone;
case 0x80:
return ErrorCode.OverflowSelectError;
default:
return ErrorCode.UnknowSelectError;
}
}
else
{ return ErrorCode.ReceiveTimeOut; }
}
#endregion
#region PrivateMethod
/// <summary>
/// 整数到EBV数据的转换
/// </summary>
/// <param name="Integer">整数</param>
/// <returns>返回的EBV数据</returns>
private static Byte[] Int32ToEBV(Int32 Integer)
{
List<Byte> data = new List<byte>();
Boolean Flag = false;
while (Integer != 0)
{
if (Flag)
{
data.Insert(0, (Byte)(((Byte)(Integer % 128)) | 0x80));
}
else
{
data.Insert(0, (Byte)(Integer % 128));
Flag = true;
}
Integer = Integer / 128;
}
return data.ToArray();
}
/// <summary>
/// 将字节数组转换为十六进制的字符串
/// </summary>
/// <param name="array">字节数组</param>
/// <returns>字符串</returns>
private static String ByteArrayToString(Byte[] array)
{
StringBuilder sb = new StringBuilder();
foreach (Byte a in array)
{ sb = sb.Append(a.ToString("X2")); }
return sb.ToString();
}
/// <summary>
/// 将字节数组转换为十六进制的字符串
/// </summary>
/// <param name="array">字节数组</param>
/// <param name="StartPos">起始位置</param>
/// <param name="Length">长度</param>
/// <returns>字符串</returns>
private static String ByteArrayToString(Byte[] array, Int32 StartPos, Int32 Length)
{
StringBuilder sb = new StringBuilder();
for (Int32 index = StartPos; index < StartPos + Length; index++)
{ sb = sb.Append(array[index].ToString("X2")); }
return sb.ToString();
}
/// <summary>
/// 将十六进制的字符串转换为字节数组
/// </summary>
/// <param name="str">字符串</param>
/// <returns>字节数组</returns>
private static Byte[] StringToByteArray(String str)
{
Byte[] data = new Byte[str.Length / 2];
for (Int32 i = 0; i < data.Length; i++)
{
data[i] = Convert.ToByte(str.Substring(i * 2, 2), 16);
}
return data;
}
/// <summary>
/// 一个字节数据转换成二进制字符串,长度为8
/// </summary>
/// <param name="data">字节数据</param>
/// <returns>返回的二进制形式字符串</returns>
private static String ToBinaryString(Byte data)
{
string temp = Convert.ToString(data, 2);
while (temp.Length < 8)
{
temp = '0' + temp;
}
return temp;
}
/// <summary>
/// 一个Uint16数据转换成二进制字符串,长度为16
/// </summary>
/// <param name="data">字节数据</param>
/// <returns>返回的二进制形式字符串</returns>
private static String ToBinaryString(UInt16 data)
{
string temp = Convert.ToString(data, 2);
while (temp.Length < 16)
{
temp = '0' + temp;
}
return temp;
}
/// <summary>
/// 一个UInt32数据转换成二进制字符串,长度为32
/// </summary>
/// <param name="data">字节数据</param>
/// <returns>返回的二进制形式字符串</returns>
private static String ToBinaryString(UInt32 data)
{
string temp = Convert.ToString(data, 2);
while (temp.Length < 32)
{
temp = '0' + temp;
}
return temp;
}
/// <summary>
/// CRC-16的计算
/// </summary>
/// <param name="frame">字节数组</param>
/// <param name="offset">偏移量</param>
/// <param name="datalength">长度</param>
private static void CalculateCRC(ref Byte[] frame, Int32 offset, Int32 datalength)
{
UInt16 crc16_preset = 0xFFFF;
UInt16 RFCRC16_POLYNOM = 0x8408;
UInt16 CRC16, m;
Byte n;
CRC16 = crc16_preset;
for (m = 0; m < datalength; m++)
{
CRC16 ^= (UInt16)(frame[offset + m] & 0xff);
for (n = 0; n < 8; n++)
{
if ((CRC16 & 0x0001) > 0)
CRC16 = (UInt16)((CRC16 >> 1) ^ RFCRC16_POLYNOM);
else
CRC16 = (UInt16)(CRC16 >> 1);
}
}
frame[offset + datalength] = (Byte)(CRC16 % 256);
frame[offset + datalength + 1] = (Byte)(CRC16 / 256);
}
/// <summary>
/// CRC-16的校验
/// </summary>
/// <param name="frame">字节数组</param>
/// <returns>布尔值</returns>
private static Boolean CheckCRC(Byte[] frame)
{
Int32 length = frame.Length;
Byte LowByte, UperByte;
UperByte = frame[length - 1];
LowByte = frame[length - 2];
CalculateCRC(ref frame, 0, length - 2);
if ((UperByte == frame[length - 1]) && (LowByte == frame[length - 2]))
{ return true; }
else
{ return false; }
}
/// <summary>
/// 对数据帧执行的字节插入,这是在发送数据帧之前的最后一步操作
/// 若数据帧中包含帧头和帧尾,ByteInsert( FrameData,1,FrameData.Length-2)
/// 若数据帧中不包含帧头和帧尾,ByteInsert( FrameData,0,FrameData.Length)
/// </summary>
/// <param name="FrameData">字节插入前的帧数据</param>
/// <param name="Index">起始位置</param>
/// <param name="Count">长度</param>
/// <returns>字节插入后的帧数据</returns>
private static Byte[] ByteInsert(Byte[] FrameData, Int32 Index, Int32 Count)
{
List<Byte> Frame = new List<byte>();
for (Int32 i = 0; i < Index; i++)
{
Frame.Add(FrameData[i]);
}
Int32 EndIndex = Index + Count;
for (Int32 i = Index; i < EndIndex; i++)
{
switch (FrameData[i])
{
case 0xAA:
case 0x55:
case 0xFF:
Frame.Add(0xFF);
Frame.Add(FrameData[i]);
break;
default:
Frame.Add(FrameData[i]);
break;
}
}
for (Int32 i = EndIndex; i < FrameData.Length; i++)
{
Frame.Add(FrameData[i]);
}
return Frame.ToArray();
}
/// <summary>
/// 封装数据帧(已执行字节插入操作)
/// </summary>
/// <param name="Command">命令码</param>
/// <param name="Payload">有效载荷</param>
/// <returns>返回的帧数据(已执行字节插入操作)</returns>
private static Byte[] EncapFrame(Byte Command, Byte[] Payload, Boolean CRCFlag)
{
List<Byte> Frame = new List<byte>();
Frame.Add(0xAA);//帧头
//考虑EBV
if (CRCFlag)//含两个字节的CRC校验
{
if (Payload.Length < 124)//Length为一个字节
{ Frame.Add((Byte)(Payload.Length + 4)); }
else//Length为两个字节
{
Frame.Add((Byte)(((Payload.Length + 4) / 128) | 0x80)); //高字节在前,延伸位为1
Frame.Add((Byte)((Payload.Length + 4) % 128)); //低字节在前,延伸位为0
}
Frame.Add((Byte)(Command | 0x80));
for (Int32 i = 0; i < Payload.Length; i++)
{ Frame.Add(Payload[i]); }
Frame.Add(0x00);//CRC高字节
Frame.Add(0x00);//CRC低字节
Frame.Add(0x55);//帧尾
Byte[] FrameData = Frame.ToArray();
CalculateCRC(ref FrameData, 1, FrameData.Length - 4); //计算CRC校验
Byte[] ReturnData = ByteInsert(FrameData, 1, FrameData.Length - 2); //执行字节插入
////////////////////////////////////////////////////
tempDirection = "发送";
tempFrameData = ReturnData;
ewh1.Set();
////////////////////////////////////////////////////
return ReturnData;
}
else//不含两个字节的CRC校验
{
if (Payload.Length < 126)//Length为一个字节
{ Frame.Add((Byte)(Payload.Length + 2)); }
else//Length为两个字节
{
Frame.Add((Byte)(((Payload.Length + 2) / 128) | 0x80)); //高字节在前,延伸位为1
Frame.Add((Byte)((Payload.Length + 2) % 128)); //低字节在前,延伸位为0
}
Frame.Add((Byte)(Command & 0x7F));
for (Int32 i = 0; i < Payload.Length; i++)
{ Frame.Add(Payload[i]); }
Frame.Add(0x55);//帧尾
Byte[] FrameData = Frame.ToArray();
Byte[] ReturnData = ByteInsert(FrameData, 1, FrameData.Length - 2); //执行字节插入
////////////////////////////////////////////////////
tempDirection = "发送";
tempFrameData = ReturnData;
ewh1.Set();
////////////////////////////////////////////////////
return ReturnData;
}
}
////////////////////////////////////////////////
private static void ReportFrame()
{
String Direction;
Byte[] FrameData;
ewh1.Reset();
while (IsOpen)
{
ewh1.WaitOne();
Direction = tempDirection;
FrameData = tempFrameData;
SendAndReceive(Direction, FrameData);
}
}
////////////////////////////////////////////////
/// <summary>
/// 接收数据的子线程代码
/// 该线程在打开串口时启动,关闭串口时自动结束
/// </summary>
private static void RcvData()
{
Byte Command, Status;
Byte[] Payload;
while (IsOpen)
{
if (RcvFrame(out Command, out Status, out Payload) == ErrorCode.AllDone)
{
switch (Command)
{
case 0x10:
if (Payload.Length == 0)
{
temp_Command = Command;
temp_Status = Status;
temp_Payload = Payload;
ewh.Set();
}
else
{
TagDetected(Command, Status, Payload);
}
break;
case 0x11:
if (Payload.Length == 0)
{
temp_Command = Command;
temp_Status = Status;
temp_Payload = Payload;
ewh.Set();
}
else
{
TagDetected(Command, Status, Payload);
}
break;
case 0x3A:
if (Payload.Length == 0)
{
temp_Command = Command;
temp_Status = Status;
temp_Payload = Payload;
ewh.Set();
}
else
{
ReturnSelectRecord(Command, Status, Payload);
}
break;
case 0x40:
if (Payload.Length == 0)
{
temp_Command = Command;
temp_Status = Status;
temp_Payload = Payload;
ewh.Set();
}
else
{
AdvancedInventoryComplete(Command, Status, Payload[0] * 256 + Payload[1]);
}
break;
case 0x42:
if (Payload.Length == 0)
{
temp_Command = Command;
temp_Status = Status;
temp_Payload = Payload;
ewh.Set();
}
else
{
ReturnTagRecord(Command, Status, Payload);
}
break;
default:
temp_Command = Command;
temp_Status = Status;
temp_Payload = Payload;
ewh.Set();
break;
}
}
else { }
//Thread.Sleep(100);
}
//String rcvstr = "";
//Byte[] rcvdata = new Byte[256];
//Int32 StartPos, StopPos;
//while (IsOpen)
//{
// try
// {
// while (serialport.BytesToRead > 0)
// {
// Int32 count = serialport.Read(rcvdata, 0, rcvdata.Length);
// rcvstr += System.Text.Encoding.ASCII.GetString(rcvdata, 0, count);
// }
// StartPos = rcvstr.IndexOf(":");
// StopPos = rcvstr.IndexOf("\r\n");
// while ((StartPos >= 0) && (StopPos > StartPos))
// {
// String framestr = rcvstr.Substring(StartPos + 1, StopPos - StartPos - 1);
// ProcessAFrame(framestr);
// rcvstr = rcvstr.Remove(0, StopPos + 2);
// StartPos = rcvstr.IndexOf(":");
// StopPos = rcvstr.IndexOf("\r\n");
// }
// }
// catch
// {
// }
// Thread.Sleep(100);
//}
}
/// <summary>
/// 接收、分析、处理响应帧
/// </summary>
/// <param name="Command">响应帧中的命令</param>
/// <param name="Status">响应帧中的状态</param>
/// <param name="Payload">响应帧中的载荷</param>
/// <returns></returns>
private static ErrorCode RcvFrame(out Byte Command, out Byte Status, out Byte[] Payload)
{
Command = 0x00;
Status = 0x00;
Payload = new Byte[0];
if (!IsOpen)
{ return ErrorCode.NotOpenError; }
//接收数据帧
List<Byte> Frame = new List<byte>();
Boolean IsDone = false;
Byte Data = 0x00;
Boolean flag = true;
try
{
while (!IsDone)
{
Data = (Byte)serialport.ReadByte();
switch (Data)
{
case 0xAA:
if (flag) //帧头,开始
{
//过滤
}
else //数据
{
Frame.Add(Data);
flag = true;
}
break;
case 0x55:
if (flag) //帧尾,结束
{
//过滤
IsDone = true;
}
else //数据
{
Frame.Add(Data);
flag = true;
}
break;
case 0xFF:
if (flag) //转义,过滤
{
flag = false;
}
else //数据
{
Frame.Add(Data);
flag = true;
}
break;
default:
Frame.Add(Data);
break;
}
}
}
catch
{ return ErrorCode.ReceiveTimeOut; }
//分析处理数据帧
//判断EBV帧长度
Int32 FrameLength;
if (Frame[0] > 127)
{
FrameLength = (Frame[0] & 0x7F) * 128 + (Frame[1] & 0x7F);
Command = Frame[2];
}
else
{
FrameLength = Frame[0];
Command = Frame[1];
}
if (FrameLength != Frame.Count)
{ return ErrorCode.FrameLengthError; }
//CRC校验
if (Command > 127)
{
if (!CheckCRC(Frame.ToArray()))//校验错误
{ return ErrorCode.CRCError; }
////////////////////////////////////////////////////
Byte[] ReturnData = new Byte[Frame.Count + 2];
ReturnData[0] = 0xAA;
for (Int32 i = 0; i < Frame.Count; i++)
{ ReturnData[1 + i] = Frame[i]; }
ReturnData[ReturnData.Length - 1] = 0x55;
tempDirection = "接收";
tempFrameData = ReturnData;
ewh1.Set();
//SendAndReceive("接收", ReturnData);
////////////////////////////////////////////////////
//校验正确,移除帧校验
Frame.RemoveAt(Frame.Count - 1);
Frame.RemoveAt(Frame.Count - 1);
}
else
{
//////////////////////////////////////////////////////////////////////////////
Byte[] ReturnData = new Byte[Frame.Count + 2];
ReturnData[0] = 0xAA;
for (Int32 i = 0; i < Frame.Count; i++)
{ ReturnData[1 + i] = Frame[i]; }
ReturnData[ReturnData.Length - 1] = 0x55;
tempDirection = "接收";
tempFrameData = ReturnData;
ewh1.Set();
//SendAndReceive("接收", ReturnData);
//////////////////////////////////////////////////////////////////////////////
}
//移除Frame Length
if (FrameLength > 127)
{
Frame.RemoveAt(0);
Frame.RemoveAt(0);
}
else
{
Frame.RemoveAt(0);
}
//移除Command
Frame.RemoveAt(0);
Status = Frame[0];
//移除Status
Frame.RemoveAt(0);
Payload = Frame.ToArray();
return ErrorCode.AllDone;
}
#endregion
#region MyRegion
#endregion
public static class FrequencySetting
{
public static Byte FREMODE = 0x00;
public static Byte FREBASE = 0x01;
public static UInt16 BF = 0x7303;
public static Byte CN = 0x10;
public static Byte SPC = 0x02;
public static Byte FREHOP = 0x00;
public static Boolean SetFrequncy(Byte fremode)
{
switch (fremode)
{
case 0x00:
FREMODE = 0x00;
FREBASE = 0x01;
BF = 0x7303;
CN = 0x10;
SPC = 0x02;
FREHOP = 0x00;
return true;
case 0x01:
FREMODE = 0x01;
FREBASE = 0x01;
BF = 0x6903;
CN = 0x10;
SPC = 0x02;
FREHOP = 0x00;
return true;
case 0x02:
FREMODE = 0x02;
FREBASE = 0x00;
BF = 0x6C2E;
CN = 0x0C;
SPC = 0x04;
FREHOP = 0x00;
return true;
case 0x03:
FREMODE = 0x03;
FREBASE = 0x00;
BF = 0x7260;
CN = 0x01;
SPC = 0x02;
FREHOP = 0x00;
return true;
case 0x04:
return false;
default:
return SetFrequncy(0x00);
}
}
public static Boolean SetFrequncy(Byte[] FrequencyData)
{
switch (FrequencyData[0])
{
case 0x00:
case 0x01:
case 0x02:
case 0x03:
return SetFrequncy(FrequencyData[0]);
case 0x04:
try
{
FREMODE = 0x04;
FREBASE = FrequencyData[1];
BF = (UInt16)(FrequencyData[2] * 256 + FrequencyData[3]);
CN = FrequencyData[4];
SPC = FrequencyData[5];
FREHOP = FrequencyData[6];
return true;
}
catch
{ return false; }
default:
return SetFrequncy(0x00);
}
}
public static Byte[] GetFrequncy()
{
return new Byte[] { FREMODE, FREBASE, (Byte)(BF / 256), (Byte)(BF % 256), CN, SPC, FREHOP };
}
}
}
public enum ErrorCode
{
AllDone = 0x00,
SerialPortError = 0x01,
SendTimeOut = 0x02,
NotOpenError = 0x03,
ReceiveTimeOut = 0x04,
CRCError = 0x05,
FrameLengthError = 0x06,
CommandError = 0x07,
StatusError = 0x08,
PayloadError = 0x09,
DataLengthError = 0x0A,
ParameterError = 0x0B,
ReadOnlyError = 0x0C,
OtherErrorCode = 0x10,
OverflowErrorCode = 0x11,
LockErrorCode = 0x12,
PowerLackErrorCode = 0x13,
UnknownErrorCode = 0x14,
OverflowSelectError = 0x20,
ReadOnlySelectError = 0x21,
OtherSelectError = 0x22,
UnknowSelectError = 0x23,
SRecordSelectError = 0x24,
UnknownError = 0xFF
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。