nanoFramework.Iot.Device.Pn532 1.2.606
前缀保留
dotnet add package nanoFramework.Iot.Device.Pn532 --version 1.2.606
NuGet\Install-Package nanoFramework.Iot.Device.Pn532 -Version 1.2.606
此命令旨在在 Visual Studio 的包管理器控制台中使用,因为它使用 NuGet 模块的 Install-Package 版本。
<PackageReference Include="nanoFramework.Iot.Device.Pn532" Version="1.2.606" />
对于支持 PackageReference 的项目,请将此 XML 节复制到项目文件中,以引用此包。
paket add nanoFramework.Iot.Device.Pn532 --version 1.2.606
NuGet 团队不为此客户端提供支持。请联系其 维护者 以获得支持。
#r "nuget: nanoFramework.Iot.Device.Pn532, 1.2.606"
#r 指令可用于 F# Interactive 和混合语言笔记本。将此复制到交互式工具或脚本的源代码中,以引用此包。
// Install nanoFramework.Iot.Device.Pn532 as a Cake Addin #addin nuget:?package=nanoFramework.Iot.Device.Pn532&version=1.2.606 // Install nanoFramework.Iot.Device.Pn532 as a Cake Tool #tool nuget:?package=nanoFramework.Iot.Device.Pn532&version=1.2.606
NuGet 团队不为此客户端提供支持。请联系其 维护者 以获得支持。
PN532 - RFID 和 NFC 读取器
PN532 是一个 RFID 和 NFC 读取器。它支持各种标准:IsoIec14443TypeA、IsoIec14443TypeB、Iso18092。此实现还应支持 PN533,它是一个完全的 ASB 串行实现,有更多寄存器和功能,但看起来与此实现向后兼容。
文档
- 官方文档可在 此处 找到
- 查看 [示例]'./samples),其中包含有关如何读取其他类型卡片(如 Ultralight)的更详细信息
用法
您首先需要通过 I2C、SPI 或串行创建该类。
string device = "COM2";
pn532 = new Pn532(device);
要作为卡读取器,PN532 必须处于监听模式。有两种选项,可以通过使用 ListPassiveTarget
或 AutoPoll
函数。
以下示例演示了轮询简单的 14443 类型 A 卡(如 Mifare)
byte[] retData = null;
while (true)
{
retData = pn532.ListPassiveTarget(MaxTarget.One, TargetBaudRate.B106kbpsTypeA);
if (retData is object)
break;
// Give time to PN532 to process
Thread.Sleep(200);
}
if (retData is null)
return;
// You need to remove the first element at it's the number of tags read
// In, this case we will assume we are reading only 1 tag at a time
var tagData = new SpanByte(retData, 1, retData.Length - 1);
var decrypted = pn532.TryDecode106kbpsTypeA(tagData);
以下示例演示了轮询 14443 类型 B 卡(如信用卡)
byte[] retData = null;
while (true)
{
retData = pn532.AutoPoll(5, 300, new PollingType[] { PollingType.Passive106kbpsISO144443_4B });
if (retData is object)
{
if (retData.Length >= 3)
break;
}
// Give time to PN532 to process
Thread.Sleep(200);
}
if (retData is null)
return;
// Check how many tags and the type
Debug.WriteLine($"Num tags: {retData[0]}, Type: {(PollingType)retData[1]}");
// See documentation page 145
// You need to remove the first element at it's the number of tags read
// In, this case we will assume we are reading only 1 tag at a time
// The second element is the type of the card. In our case, because we are using a Credit Card, we already know it's a Type B card
// The thrid element is the size of the data
var tagData = new SpanByte(retData, 3, retData.Length - 3);
var decrypted = pn532.TryDecodeData106kbpsTypeB(tagData);
读取或写入卡片
PN532实现了读写功能,允许使用高级Mifare卡片类。这种实现抽象化了所使用的读卡器。
一旦检测并选择,如前例所示,将完全转储经典Mifare 1K卡的内容
if (decrypted is object)
{
Debug.WriteLine($"Tg: {decrypted.TargetNumber}, ATQA: {decrypted.Atqa} SAK: {decrypted.Sak}, NFCID: {BitConverter.ToString(decrypted.NfcId)}");
if (decrypted.Ats is object)
Debug.WriteLine($", ATS: {BitConverter.ToString(decrypted.Ats)}");
MifareCard mifareCard = new MifareCard(pn532, decrypted.TargetNumber) { BlockNumber = 0, Command = MifareCardCommand.AuthenticationA };
mifareCard.SetCapacity(decrypted.Atqa, decrypted.Sak);
mifareCard.SerialNumber = decrypted.NfcId;
mifareCard.KeyA = new byte[6] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
mifareCard.KeyB = new byte[6] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };/
for (byte block = 0; block < 64; block++)
{
mifareCard.BlockNumber = block;
mifareCard.Command = MifareCardCommand.AuthenticationB;
var ret = mifareCard.RunMifiCardCommand();
if (ret < 0)
{
// Try another one
mifareCard.Command = MifareCardCommand.AuthenticationA;
ret = mifareCard.RunMifiCardCommand();
}
if (ret >= 0)
{
mifareCard.BlockNumber = block;
mifareCard.Command = MifareCardCommand.Read16Bytes;
ret = mifareCard.RunMifiCardCommand();
if (ret >= 0)
Debug.WriteLine($"Bloc: {block}, Data: {BitConverter.ToString(mifareCard.Data)}");
else
{
Debug.WriteLine($"Error reading bloc: {block}, Data: {BitConverter.ToString(mifareCard.Data)}");
}
if (block % 4 == 3)
{
// Check what are the permissions
for (byte j = 3; j > 0; j--)
{
var access = mifareCard.BlockAccess((byte)(block - j), mifareCard.Data);
Debug.WriteLine($"Bloc: {block - j}, Access: {access}");
}
var sector = mifareCard.SectorTailerAccess(block, mifareCard.Data);
Debug.WriteLine($"Bloc: {block}, Access: {sector}");
}
}
else
{
Debug.WriteLine($"Authentication error");
}
}
PN532作为目标
可以将PN532模式更改为另一台读卡器(例如,带NFC的手机)识别为目标。以下示例显示了如何将PN532转换为信用卡
static void AsTarget(Pn532 pn532)
{
byte[] retData = null;
TargetModeInitialized modeInitialized = null;
while (true)
{
(modeInitialized, retData) = pn532.InitAsTarget(
TargetModeInitialization.PiccOnly,
new TargetMifareParameters() { Atqa = new byte[] { 0x08, 0x00 }, Sak = 0x60 },
new TargetFeliCaParameters() { NfcId2 = new byte[] { 0x01, 0xFE, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7 }, Pad = new byte[] { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7 } },
new TargetPiccParameters() { NfcId3 = new byte[] { 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, GeneralTarget = new byte[0], HistoricalTarget = new byte[0] });
if (modeInitialized is object)
break;
// Give time to PN532 to process
Thread.Sleep(200);
}
if (modeInitialized is null)
return;
Debug.WriteLine($"PN532 as a target: ISDep: {modeInitialized.IsDep}, IsPicc {modeInitialized.IsISO14443_4Picc}, {modeInitialized.TargetBaudRate}, {modeInitialized.TargetFramingType}");
Debug.WriteLine($"Initiator: {BitConverter.ToString(retData)}");
// 25-D4-00-E8-11-6A-0A-69-1C-46-5D-2D-7C-00-00-00-32-46-66-6D-01-01-12-02-02-07-FF-03-02-00-13-04-01-64-07-01-03
// 11-D4-00-01-FE-A2-A3-A4-A5-A6-A7-00-00-00-00-00-30
// E0-80
Span<byte> read = stackalloc byte[512];
int ret = -1;
while (ret<0)
ret = pn532.ReadDataAsTarget(read);
// For example: 00-00-A4-04-00-0E-32-50-41-59-2E-53-59-53-2E-44-44-46-30-31-00
Debug.WriteLine($"Status: {read[0]}, Data: {BitConverter.ToString(read.Slice(1).ToArray())}");
}
请注意,这只是初始化过程的第一阶段,展示了如何获取第一份数据和读取数据。在特定情况下,仿真必须理解读卡器发送的命令并正确地模拟卡片。
可以模拟任何A类、B类和Felica卡片。
当前实现
通信支持
- HSU串行端口:完全支持
- I2C:支持
- SPI:支持,但使用了特定的片选引脚
- SPI模式应为模式0和LSB首先
- 硬件复位引脚:用户代码可以执行此操作
其他命令
- 诊断。注意:仅为部分实现,仅实现了基本测试
- 获取固件版本
- 获取通用状态
- 读取寄存器
- 写入寄存器
- 读取GPIO
- 写入GPIO
- 设置串行波特率
- 设置参数
- SAM配置
- 关机
RF通信命令
- RF配置
- RF规整测试
PN532作为发起者(读卡器)命令
- InJumpForDEP
- InJumpForPSL
- InListPassiveTarget
- InATR
- InPSL
- InDataExchange
- InCommunicateThru
- InDeselect
- InRelease
- InSelect
- InAutoPoll
PN532作为目标(模拟卡片)
- TgInitAsTarget
- TgSetGeneralBytes
- TgGetData
- TgSetData
- TgSetMetaData
- TgGetInitiatorCommand
- TgResponseToInitiator
- TgGetTargetStatus
产品 | 版本 兼容的以及额外的计算目标框架版本。 |
---|---|
.NET Framework | net is compatible. |
-
- nanoFramework.CoreLibrary (>= 1.15.5)
- nanoFramework.Logging (>= 1.1.108)
- nanoFramework.Runtime.Events (>= 1.11.18)
- nanoFramework.System.Buffers.Binary.BinaryPrimitives (>= 1.2.586)
- nanoFramework.System.Device.Gpio (>= 1.1.41)
- nanoFramework.System.Device.I2c (>= 1.1.16)
- nanoFramework.System.Device.Spi (>= 1.3.52)
- nanoFramework.System.IO.Ports (>= 1.1.86)
- nanoFramework.System.IO.Streams (>= 1.1.59)
- nanoFramework.System.Text (>= 1.2.54)
NuGet包
此包未用于任何NuGet包。
GitHub存储库
此包未用于任何流行的GitHub存储库。
版本 | 下载 | 最后更新 |
---|---|---|
1.2.606 | 25 | 8/2/2024 |
1.2.595 | 69 | 7/24/2024 |
1.2.590 | 67 | 7/17/2024 |
1.2.570 | 87 | 6/14/2024 |
1.2.560 | 89 | 5/29/2024 |
1.2.548 | 88 | 5/15/2024 |
1.2.536 | 101 | 4/15/2024 |
1.2.486 | 114 | 2/2/2024 |
1.2.479 | 94 | 1/27/2024 |
1.2.446 | 227 | 11/17/2023 |
1.2.439 | 99 | 11/14/2023 |
1.2.436 | 107 | 11/10/2023 |
1.2.416 | 105 | 11/8/2023 |
1.2.329 | 171 | 5/26/2023 |
1.2.313 | 126 | 5/12/2023 |
1.2.297 | 140 | 5/3/2023 |
1.2.212 | 301 | 1/5/2023 |
1.2.203 | 267 | 12/28/2022 |
1.2.159 | 364 | 11/14/2022 |
1.2.153 | 348 | 11/5/2022 |
1.2.141 | 382 | 10/25/2022 |
1.2.128 | 380 | 10/22/2022 |
1.2.122 | 418 | 10/12/2022 |
1.2.118 | 408 | 10/11/2022 |
1.2.117 | 397 | 10/10/2022 |
1.2.114 | 365 | 10/8/2022 |
1.2.95 | 420 | 9/22/2022 |
1.2.89 | 420 | 9/16/2022 |
1.2.87 | 475 | 9/15/2022 |
1.2.73 | 392 | 9/8/2022 |
1.2.40 | 410 | 8/6/2022 |
1.2.35 | 395 | 8/4/2022 |
1.2.5 | 447 | 7/13/2022 |
1.1.141.41205 | 426 | 7/6/2022 |
1.1.116.8772 | 425 | 6/24/2022 |
1.1.113.2032 | 411 | 6/23/2022 |
1.1.111.5739 | 419 | 6/17/2022 |
1.1.109.32999 | 419 | 6/16/2022 |
1.1.99.36719 | 414 | 6/14/2022 |
1.1.97.17326 | 432 | 6/13/2022 |
1.1.92.53000 | 408 | 6/8/2022 |
1.1.67.25390 | 421 | 5/27/2022 |
1.1.48.19401 | 406 | 5/19/2022 |
1.1.38 | 423 | 5/4/2022 |
1.1.27 | 434 | 4/26/2022 |
1.1.20 | 426 | 4/21/2022 |
1.1.3 | 461 | 4/15/2022 |
1.1.1 | 447 | 4/14/2022 |
1.0.300 | 435 | 4/3/2022 |
1.0.278-preview.125 | 117 | 3/25/2022 |
1.0.278-preview.124 | 110 | 3/25/2022 |
1.0.278-preview.118 | 105 | 3/24/2022 |
1.0.278-preview.115 | 102 | 3/22/2022 |
1.0.278-preview.111 | 107 | 3/19/2022 |
1.0.278-preview.105 | 115 | 3/15/2022 |
1.0.278-preview.101 | 111 | 3/11/2022 |
1.0.278-preview.98 | 112 | 3/10/2022 |
1.0.278-preview.97 | 113 | 3/8/2022 |
1.0.278-preview.84 | 119 | 2/25/2022 |
1.0.278-preview.70 | 109 | 2/11/2022 |
1.0.278-preview.64 | 109 | 2/9/2022 |
1.0.278-preview.62 | 116 | 2/8/2022 |
1.0.278-preview.61 | 123 | 2/5/2022 |
1.0.278-preview.59 | 123 | 2/4/2022 |
1.0.278-preview.52 | 125 | 1/31/2022 |
1.0.278-preview.31 | 124 | 1/27/2022 |
1.0.278-preview.29 | 127 | 1/27/2022 |
1.0.278-preview.16 | 126 | 1/24/2022 |
1.0.278-preview.14 | 125 | 1/21/2022 |
1.0.278-preview.1 | 132 | 1/14/2022 |
1.0.272 | 159 | 1/10/2022 |
1.0.259 | 312 | 12/9/2021 |
1.0.221 | 157 | 10/19/2021 |
1.0.219 | 157 | 10/19/2021 |
1.0.218 | 196 | 10/18/2021 |
1.0.217 | 181 | 10/16/2021 |
1.0.194 | 202 | 10/1/2021 |
1.0.193 | 154 | 9/30/2021 |
1.0.191 | 162 | 9/29/2021 |
1.0.146 | 164 | 7/22/2021 |
1.0.140 | 170 | 7/20/2021 |