通信规格书:
指定页读取规范:
HOST:<LF>RPP1<CR>
Reader:<LF>R<FAIL> <CR><LF> // 读取失败
Reader:<LF>R12345678<CR><LF>// 读取成功
Example:
HOST:0A 52 50 50 31 0D
Reader:0A 52 30 31 32 33 34 35 59 54 0D 0A // 成功
Reader:0A 52 46 41 49 4C 0D 0A // 失败
-
HOST发送指令:
- HOST通过串口向RFID读写器发送指定页读取的命令。
- 命令格式为
<LF>RPP1<CR>
,其中:<LF>
表示换行符,ASCII码为 0x0A。<CR>
表示回车符,ASCII码为 0x0D。RPP1
表示指定读取第一页的数据。
-
读写器响应:
- 如果读写器成功读取了数据,会返回如下格式的响应:
<LF>R12345678<CR><LF>
,其中:R
是固定的标识符,表示读取操作。12345678
是具体的数据内容。<LF>
表示换行符。<CR>
表示回车符。
- 如果读取失败,读写器返回如下格式的响应:
<LF>RFAIL<CR><LF>
,其中:RFAIL
表示读取失败。
- 如果读写器成功读取了数据,会返回如下格式的响应:
指定页写入规范:
HOST:<LF>WPP1,12345678<CR>
Reader:<LF>W<FAIL> <CR><LF> //写入失败
Reader:<LF>W<OK> <CR><LF> // 写入成功
Example:
HOST:0A 57 50 50 31 2C 31 32 33 34 35 36 37 38 0D
Reader:0A 57 4F 4B 0D 0A // 写入成功
Reader:0A 57 46 41 49 4C 0D 0A // 写入失败
-
HOST发送指令:
- HOST通过串口向RFID读写器发送指定页写入的命令。
- 命令格式为
<LF>WPP1,12345678<CR>
,其中:<LF>
表示换行符,ASCII码为 0x0A。<CR>
表示回车符,ASCII码为 0x0D。WPP1,12345678
表示写入数据到第一页,数据为12345678
。
-
读写器响应:
- 如果写入操作成功,读写器会返回如下格式的响应:
<LF>W<OK><CR><LF>
,其中:W
是固定的标识符,表示写入操作。<OK>
表示写入成功。<LF>
表示换行符。<CR>
表示回车符。
- 如果写入操作失败,读写器会返回如下格式的响应:
<LF>W<FAIL><CR><LF>
,其中:W
是固定的标识符,表示写入操作。<FAIL>
表示写入失败。
- 如果写入操作成功,读写器会返回如下格式的响应:
实现代码类:
public class RfidCls : IDisposable
{
private SerialPort port;
private Thread initThread;
private readonly object mylock = new object();
private string portName = "COM2";
private int baudRate = 9600;
public bool IsLink { get; private set; }
public void Start(string portname, int baudrate)
{
portName = portname;
baudRate = baudrate;
initThread = new Thread(InitializePort);
initThread.Start();
}
private void InitializePort()
{
try
{
if (string.IsNullOrEmpty(portName))
throw new ArgumentException("串口参数未设置,请检查!");
port = new SerialPort(portName, baudRate)
{
StopBits = StopBits.One,
DataBits = 8,
Parity = Parity.None
};
port.Open();
if (port.IsOpen)
{
IsLink = true;
LogInfo("RFID连接成功");
}
else
{
throw new Exception("串口未能成功打开!");
}
}
catch (Exception ex)
{
LogError($"串口连接失败:{ex.Message}");
}
}
public void Close()
{
try
{
if (port != null && port.IsOpen)
{
port.Close();
LogInfo("RFID连接已关闭");
}
}
catch (Exception ex)
{
LogError($"关闭RFID连接失败:{ex.Message}");
}
}
public bool ReadRFID(int pageIndex, out string pageInfo)
{
pageInfo = null;
try
{
lock (mylock)
{
if (port == null || !port.IsOpen)
throw new InvalidOperationException("RFID端口未打开或已关闭");
string command = $"RPP{pageIndex + 1}";
byte[] commandBytes = ConstructCommand(command, "");
port.Write(commandBytes, 0, commandBytes.Length);
byte[] responseBytes = ReadResponse();
if (responseBytes != null && responseBytes.Length >= 4)
{
string response = Encoding.Default.GetString(responseBytes);
if (response.StartsWith("R") && response.Length >= 6)
{
if (response.Substring(1, 4) == "FAIL")
{
LogError("读取RFID失败");
return false;
}
else if (response.Length > 6)
{
pageInfo = response.Substring(1);
LogInfo($"读取RFID成功:{pageInfo}");
return true;
}
}
}
LogError("读取RFID未知响应");
return false;
}
}
catch (Exception ex)
{
LogError($"读取RFID出错:{ex.Message}");
return false;
}
}
public bool WriteRFID(int pageIndex, string hexValue)
{
try
{
lock (mylock)
{
if (port == null || !port.IsOpen)
throw new InvalidOperationException("RFID端口未打开或已关闭");
string command = $"WPP{pageIndex + 1},{hexValue}";
byte[] commandBytes = ConstructCommand(command, "");
port.Write(commandBytes, 0, commandBytes.Length);
byte[] responseBytes = ReadResponse();
if (responseBytes != null && responseBytes.Length >= 4)
{
string response = Encoding.Default.GetString(responseBytes);
if (response.StartsWith("W"))
{
if (response.Length >= 6 && response.Substring(1, 2) == "OK")
{
LogInfo("写入RFID成功");
return true;
}
else if (response.Length >= 6 && response.Substring(1, 4) == "FAIL")
{
LogError("写入RFID失败");
return false;
}
}
}
LogError("写入RFID未知响应");
return false;
}
}
catch (Exception ex)
{
LogError($"写入RFID出错:{ex.Message}");
return false;
}
}
private byte[] ConstructCommand(string command, string hexValue)
{
StringBuilder commandHex = new StringBuilder();
foreach (char c in command)
{
commandHex.Append(Convert.ToString(c, 16));
}
string dataHex = hexValue;
string fullHex = $"0A{commandHex}2C{dataHex}0D";
byte[] commandBytes = new byte[fullHex.Length / 2];
for (int i = 0; i < fullHex.Length; i += 2)
{
commandBytes[i / 2] = Convert.ToByte(fullHex.Substring(i, 2), 16);
}
return commandBytes;
}
private byte[] ReadResponse()
{
DateTime startTime = DateTime.Now;
byte[] buffer = new byte[1024];
int totalBytes = 0;
while (DateTime.Now.Subtract(startTime).TotalSeconds < 3)
{
int bytesToRead = port.BytesToRead;
if (bytesToRead > 0)
{
if (totalBytes + bytesToRead > buffer.Length)
Array.Resize(ref buffer, totalBytes + bytesToRead);
totalBytes += port.Read(buffer, totalBytes, bytesToRead);
if (totalBytes >= 2 && (buffer[totalBytes - 2] == 0x0D || buffer[totalBytes - 1] == 0x0A))
break;
}
else
{
Thread.Sleep(100);
}
}
if (totalBytes > 0)
{
Array.Resize(ref buffer, totalBytes);
return buffer;
}
return null;
}
private void LogInfo(string message)
{
// 实现信息日志记录,例如使用日志框架记录到文件或其他存储介质
Console.WriteLine($"信息:{message}");
}
private void LogError(string message)
{
// 实现错误日志记录,例如使用日志框架记录到文件或其他存储介质
Console.WriteLine($"错误:{message}");
}
public void Dispose()
{
Close();
if (initThread != null)
{
initThread.Join(); // 确保线程已终止
initThread = null;
}
}
}