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                
#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                

PN532 - RFID 和 NFC 读取器

PN532 是一个 RFID 和 NFC 读取器。它支持各种标准:IsoIec14443TypeA、IsoIec14443TypeB、Iso18092。此实现还应支持 PN533,它是一个完全的 ASB 串行实现,有更多寄存器和功能,但看起来与此实现向后兼容。

文档

  • 官方文档可在 此处 找到
  • 查看 [示例]'./samples),其中包含有关如何读取其他类型卡片(如 Ultralight)的更详细信息

用法

您首先需要通过 I2C、SPI 或串行创建该类。

string device = "COM2";
pn532 = new Pn532(device);

要作为卡读取器,PN532 必须处于监听模式。有两种选项,可以通过使用 ListPassiveTargetAutoPoll 函数。

以下示例演示了轮询简单的 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. 
兼容的目标框架
包含的目标框架(在包中)
了解有关目标框架.NET Standard的更多信息。

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