Difference between revisions of "PN532 NFC HAT"

From Waveshare Wiki
Jump to: navigation, search
Line 417: Line 417:
  
 
6. Expected result: close card to coil part of PN532, the UID of card is read and printed.
 
6. Expected result: close card to coil part of PN532, the UID of card is read and printed.
 +
==程序说明==
 +
上面的演示是以获取 Mifare Classic 卡的 ID 作为例子(example_get_uid.py / rpi_get_uid.exe / uno_get_uid.ino / stm32_get_uid),下面将对其他示例程序进行说明。
 +
 +
【注意】
 +
 +
使用这些程序之前,请根据实际情况,设置 PN532 NFC HAT 的I0 / I1 跳线以及拨码开关。拨码开关不能同时设置为ON,否则无法接收到正确的数据。简单起见,这里用0表示拨码开关拨到OFF,用1表示拨码开关拨到ON。
 +
*使用UART接口的时候,[I1..I0]跳线应设置为LL,拨码开关设置为00000011
 +
*使用I2C接口的时候,[I1..I0]跳线应设置为LH,拨码开关设置为00001100。
 +
*使用SPI接口的时候,[I1..I0]跳线应设置为HL,拨码开关设置为11110000。
 +
 +
===读取Mifare Classic卡内容===
 +
{|border="1px" width ="800px"
 +
|-align="center" style="background:grey; color:white"
 +
|'''程序'''||'''开发板'''
 +
|-align="center"
 +
|example_dump_mifare.py||Raspberry Pi
 +
|-align="center"
 +
|rpi_dump_mifare.c||Raspberry Pi
 +
|-align="center"
 +
|uno_dump_mifare.ino||Arduino UNO
 +
|-align="center"
 +
|stm32_dump_mifare/MDK-ARM/pn532_stm32.uvprojx||STM32F103CBT6
 +
|}
 +
 +
 +
预期结果:把Mifare Classic 卡贴近PN532 NFC HAT,卡的内容会被打印出来
 +
<source lang="c">
 +
0 : 37 F9 20 69 87 08 04 00 62 63 64 65 66 67 68 69
 +
1 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 +
2 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 +
3 : 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF
 +
4 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 +
5 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 +
6 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 +
7 : 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF
 +
8 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 +
9 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 +
10 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 +
11 : 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF
 +
… …
 +
63 : 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF
 +
</source>
 +
说明:
 +
*每一行的显示内容是对应的块的内容
 +
*第0块的前4字节是Mifare Classic卡的UID,第5字节是校验位,是前4字节的异或结果
 +
*常规的卡的第0块(UID)是无法修改的
 +
*每4个块属于同一个扇区(sector),共用同一个密码,例如4N~4N+3块属于同一个扇区。
 +
*第4N+3块是密码块,相应的,如果要读取4N~4N+2块的内容,就必须使用4N+3块所记录的密码
 +
*容量为1K的卡,一共有64个块
 +
以读取第6块为例,必须使用对应扇区的密码,即第7块的前6个字节(KEY A)或者后6字节(KEY B)的密码
 +
 +
7 : 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF
 +
 +
前6个字节为KEY A,默认为FF FF FF FF FF FF,但是其读取结果永远为00 00 00 00 00 00。后6字节为KEY B,使用明文存储,Mifare Classic卡默认的KEY A和KEY B均为FF FF FF FF FF FF。
 +
 +
中间的4个字节是访问控制位(Access Bits)。默认值FF 07 80 69,这个数值用于扇区得写的访问权限控制,用户如果对其写入不合适的数值,将会导致卡被锁死。
 +
 +
:[[File:PN532_NFC_HAT-6.png|700px]]
 +
 +
例如byte6写入0xFF,那么byte7的高4位必须为0b0000, byte 8的低4位必须为0b0000。具体参见MF1S50YYX_V1.pdf 的 Access conditions for data blocks 节
 +
 +
'''产品随附的卡是魔法卡,通过预留的后门可以解锁,但是用户应当知道,如果使用常规的 Mifare 卡,一旦把访问控制位写错,将会无法修复。所以在写卡的时候要特别注意'''
 +
 +
===读写Mifare Classic卡===
 +
{|border="1px" width ="800px"
 +
|-align="center" style="background:grey; color:white"
 +
|'''程序'''||'''开发板'''
 +
|-align="center"
 +
|example_rw_mifare.py||Raspberry Pi
 +
|-align="center"
 +
|rpi_rw_mifare.c||Raspberry Pi
 +
|-align="center"
 +
|uno_rw_mifare.ino||Arduino UNO
 +
|-align="center"
 +
|stm32_rw_mifare/MDK-ARM/pn532_stm32.uvprojx||STM32F103CBT6
 +
|}
 +
 +
 +
预期结果:把Mifare Classic卡贴近PN532 NFC HAT,第6块的内容会被改写成00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F。
 +
 +
说明:
 +
*写入第6块的内容之前,需要保证第6块对应的密码为0xFF FF FF FF FF FF。这个密码即为第7块的前6个字节(读取结果永远为0x00 00 00 00 00 00)。
 +
*如果用户修改示例程序、试图写入第N+3块的内容,应该特别小心。因为这部分的内容是N ~ N+2块的密码。应当记住写入的密码,如果忘记密码,那么所在扇区的所有块都将无法读写。
 +
===读取NTAG2XX整卡内容===
 +
{|border="1px" width ="800px"
 +
|-align="center" style="background:grey; color:white"
 +
|'''程序'''||'''开发板'''
 +
|-align="center"
 +
|example_dump_ntag2.py||Raspberry Pi
 +
|-align="center"
 +
|rpi_dump_ntag2.c||Raspberry Pi
 +
|-align="center"
 +
|uno_dump_ntag2.ino||Arduino UNO
 +
|-align="center"
 +
|stm32_dump_ntag2/MDK-ARM/pn532_stm32.uvprojx||STM32F103CBT6
 +
|}
 +
 +
预期结果:把Ntag215卡贴近PN532 NFC HAT,卡的内容会被打印出来
 +
 +
<source lang="c">
 +
0: 04 85 32 3b
 +
1: 92 a8 64 80
 +
2: de 48 00 00
 +
3: e1 10 3e 00
 +
4: 03 00 fe 00
 +
5: 00 00 00 00
 +
6: 00 00 00 00
 +
7: 00 00 00 00
 +
… …
 +
134: 00 00 00 00
 +
</source>
 +
 +
说明:
 +
*Ntag215 卡片需要用户自行购买。
 +
*根据习惯,Ntag215 的页(page)相当于Mifare 的块(block),一行代表一页。
 +
*第0页的前3字节是UID0-UID2,第4字节是校验位,是前3字节和0x88 (Cascade Tag,由ISO/IEC 14443-3 Type A 定义)的异或结果。
 +
*第1页的4个字节是UID3-UID6。
 +
*第2页的第1字节是校验位,是UID3-UID6的异或结果
 +
 +
===读写NTAG2XX卡===
 +
{|border="1px" width ="800px"
 +
|-align="center" style="background:grey; color:white"
 +
|'''程序'''||'''开发板'''
 +
|-align="center"
 +
|example_rw_ntag2.py||Raspberry Pi
 +
|-align="center"
 +
|rpi_rw_ntag2.c||Raspberry Pi
 +
|-align="center"
 +
|uno_rw_ntag2.ino||Arduino UNO
 +
|-align="center"
 +
|stm32_rw_ntag2/MDK-ARM/pn532_stm32.uvprojx||STM32F103CBT6
 +
|}
 +
 +
预期结果:把NTAG215卡贴近PN532 NFC HAT,第6块的内容会被改写成00 01 02 03。
 +
 +
说明:
 +
*第2页的最后两个字节用于标记并锁定03h到0Fh的对应的页为只读,并且这个'''操作不可逆'''。使用的时候应该注意这个情况。见NTAG213/215/216 的Static lock bytes (NTAG21x) 节。
 +
:[[File:PN532_NFC_HAT-7.png|800px]]
 +
*要锁定第10h页之后的数据,则把对应的地址写入28h页(NTAG213)或82h页(NTAG215)或E2h页(NTAG216)的前3字节,第4字节读取结果永远是0xBD。见NTAG213/215/216 的Dynamic Lock Bytes节
 +
:[[File:PN532_NFC_HAT-8.png|800px]]
 +
*Ntag2xx卡的功能详情请参见 NTAG213/215/216 手册的相关内容。
 +
===设置PN532的GPIO电平===
 +
{|border="1px" width ="800px"
 +
|-align="center" style="background:grey; color:white"
 +
|'''程序'''||'''开发板'''
 +
|-align="center"
 +
|example_write_gpio.py||Raspberry Pi
 +
|-align="center"
 +
|rpi_write_gpio.c||Raspberry Pi
 +
|-align="center"
 +
|uno_write_gpio.ino||Arduino UNO
 +
|-align="center"
 +
|stm32_write_gpio/MDK-ARM/pn532_stm32.uvprojx||STM32F103CBT6
 +
|}
 +
 +
预期结果:打印PN532的GPIO电平
 +
<source lang="c">
 +
Pin P30: 1
 +
Pin P31: 0
 +
Pin P32: 1
 +
Pin P33: 0
 +
Pin P34: 1
 +
Pin P35: 0
 +
Pin P71: 0
 +
Pin P72: 1
 +
Pin I0: 1
 +
Pin I1: 0
 +
</source>
 +
说明:
 +
 +
程序尝试设置管脚电平:P30 -> 高,P31 -> 低,P33 -> 低,P35 -> 低,P71 -> 低,P72 -> 高
 +
 +
注意:
 +
*P32是 int0,一旦写入低电平,将会导致模块复位。
 +
*P34是SIC_CLK,读取的结果是高电平。
 +
*P71是MISO,在SPI模式下,读取的结果是高电平。
 +
*P72是SCK,在SPI模式下,读取的结果是高电平。
 +
*模块上电的时候, PN532 会根据I0/I1的电平设置通讯接口。之后可以移除跳线帽,作为普通的GPIO使用。
 +
PN532的P30 – P35电平会在硬件复位(RSTPDN置低2ms然后置高)之后,恢复为高电平。
 +
===读取PN532的GPIO电平===
 +
{|border="1px" width ="800px"
 +
|-align="center" style="background:grey; color:white"
 +
|'''程序'''||'''开发板'''
 +
|-align="center"
 +
|example_read_gpio.py||Raspberry Pi
 +
|-align="center"
 +
|rpi_read_gpio.c||Raspberry Pi
 +
|-align="center"
 +
|uno_read_gpio.ino||Arduino UNO
 +
|-align="center"
 +
|stm32_read_gpio/MDK-ARM/pn532_stm32.uvprojx||STM32F103CBT6
 +
|}
 +
 +
预期结果:会打印PN532的GPIO电平
 +
 +
<source lang="c">
 +
Port P3: 0x3f
 +
Port P7: 0x07
 +
Port I: 0x07
 +
Pin P30: 1
 +
Pin P31: 1
 +
Pin P32: 1
 +
Pin P33: 1
 +
Pin P34: 1
 +
Pin P35: 1
 +
Pin I0: 1
 +
Pin I1: 0
 +
</source>
 +
说明:
 +
*PN532的P30 – P35电平会在硬件复位(RSTPDN置低2ms然后置高)之后,恢复为高电平。
  
 
==Resources==
 
==Resources==

Revision as of 01:51, 12 August 2019

PN532 NFC HAT
PN532 NFC HAT

PN532 NFC HAT for Raspberry Pi, I2C / SPI / UART
{{{name2}}}

{{{name3}}}

{{{name4}}}

{{{name5}}}

Instruction

This is a Raspberry Pi NFC HAT based on PN532 operating in the 13.56MHz frequency range. It supports three communication interfaces: I2C, SPI, and UART.

NFC (Near Field Communication) is a wireless technology allows contactless point-to-point data communication between devices within a short distance of 10 cm. It is widely used in applications such as access control system, smart tickets, meal card, etc.

Based on the popular NFC controller PN532 with multi interface options, this HAT will easily enable NFC function for your Raspberry Pi.

Features

  • Standard Raspberry Pi 40PIN GPIO extension header, supports Raspberry Pi series boards
  • Onboard PN532 chip, supports various NFC/RFID cards like MIFARE/NTAG2xx, etc.
  • Three interface options: I2C, SPI, and UART, configured via jumpers and switches
  • Breakout control pins, for easily connecting with host boards like STM32/Arduino
  • Comes with development resources and manual (examples for Raspberry Python/C, STM32, Arduino)

Note

  • This module can only be used to write/read NFC card whose password is known, it cannot be used for decrypting encrypted NFC card. For example, the default password of all blocks of Mifare Classic card is 0xFFFFFFFFFFFF. the Mifare card can be written/read only when the default password isn't changed
  • This module cannot be used to copy card, unless that the card use default password.
  • This module cannot be used to simulate NFC card. Because ID of NFC card are 4 bytes, because of security policy of PN532, it will set the first byte of simulate card to 0x08. For more details, please refer to http://www.nfc-tools.org/index.php?title=PN53x%E3%80%82

Quick testing

You can quick test the module by connecting it to PC with USB to TTL module instead of Raspberry Pi

1. Hardware connection
PN532 NFC HAT USB to TTL Module
3V3 3.3V
GND GND
TX RX
RX TX
2. Set L0 to L and L1 to L by jumpers
3. Connect USB to TTL Module to PC by USB cable
4. Open Serial assistant software, set it
  • 波特率(Baud rate):115200
  • 数据位(Data bits):8
  • 停止位(Stop bits):1
  • 校验位(Parity):None
  • 流控制(Flow control):None
5. Check "HEX发送” and “HEX显示”
PN532 NFC HAT.jpg
6. Select correct serial port and open
7. Send data below to wake up FN532 module:
55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 03 FD D4 14 01 17 00

(Please refer to PN532 User Manual HSU wake up condition Chapter)

The response from PN532 module should be:

00 00 FF 00 FF 00 00 00 FF 02 FE D5 15 16 00
8. Send data below to scan Mifare Classic card(The blue card provided, hereafter called as "card")
00 00 FF 04 FC D4 4A 01 00 E1 00

Closing card to coil part of module, module scan it and response:

00 00 FF 0C F4 D5 4B 01 01 00 04 08 04 XXXXXXXXXX 00

XXXXXXXXXX in response data is ID (3 bytes) and checksum (1 byte) of card.(Please refer to PN532 User Manual InListPassiveTarget Chapter)

Using demo codes

PN532 NFC HAT supports UART, I2C and SPI interface. You can use them according to your situation.After connecting PN532 NFC HAT (hereafter called as PN532) to Raspberry PI, then set the L1, L0 jumpers and DIP switch for different interfaces.

Choose the interface:

  • UART:By default, UART interface of Raspberry Pi is used for Sheell debugging. If you use serial port for degbugging, you need to add an USB to TTL module for communicating just like what we do on #Quick testing. In this case, the serial port is mapped as ttyUSB0 instead of ttyS0
  • I2C: Raspberry Pi doesn't supports I2C Clock Stretching. However, PN532 may use Clock Stretching (slaver pull-down SCL pin of I2C interface). Clock Stretching cause that Raspberry Pi cannot control all I2C devices, therefore, if you need to connect other i2C device, we do not recommend you to use I2C interface.
  • SPI:We use D4 (BCM) pin as Chip select pin of SPI interface. Take care about GPIO conflict.

Raspberry Pi examples

Download demo code from #Resources, unzip and copy raspberrypi folder to /home/pi of Raspberry Pi. You can firstly copy it to /boot of SD card, then copy it to /home/pi.

SPI Interface

1. Set L0 toL and L1 to H by jumpers

2. Connect RSTPDN->D20 by jumper

3. Set DIP switch to

SCK MISO MOSI NSS SCL SDA RX TX
ON ON ON ON OFF OFF OFF OFF
PN532 NFC HAT-2.jpg

4. Connect PN532 NFC HAT to Raspberry Pi

Connect PN532 NFC HAT to Raspberry Pi via SPI interface
PN532 NFC HAT Raspberry Pi (BCM)
SCK SCK
MISO MISO
MOSI MOSI
NSS P4 (D4)

5. Enable SPI interface

Open Terminal of Raspberry Pi,use command: sudo raspi-config

Choose Interfacing Options -> SPI -> Yes

6. Run demo codes(Use example_get_uid.py and rpi_get_uid.c as example)

Open Terminal, navigate to directory of demo codes

cd ~/raspberrypi/

1) python code:

Enter directory of python codes: cd ~/raspberrypi/python/

Modify example_get_uid.py file,set the initialize code as :

pn532 = PN532_SPI(debug=False, reset=20, cs=4)
#pn532 = PN532_I2C(debug=False, reset=20, req=16)
#pn532 = PN532_UART(debug=False, reset=20)

Save after modifying, then run the codes with command:

python3 example_get_uid.py

2) C codes:

Enter directory of c code: cd ~/raspberrypi/c/example/

Modify rpi_get_uid.c file, set initialize code as:

PN532_SPI_Init(&pn532);
//PN532_I2C_Init(&pn532);
//PN532_UART_Init(&pn532);

Save and compile:sudo make

Run the code:

./rpi_get_uid.exe

7. Expected result:Close card to coil part of PN532, the UID of card is read

UART interface

1. Set L0 to L and L1 to L by jumpers

2. Connecting RSTPDN ->D20 by jumper

3. Set DIP switch to

SCK MISO MOSI NSS SCL SDA RX TX
OFF OFF OFF OFF OFF OFF ON ON
PN532 NFC HAT-3.jpg

4. Connect PN532 to Raspberry Pi

Connect PN532 NFC HAT to Raspberry Pi via UART interface
PN532 NFC HAT Raspberry Pi
RX TX
TX RX

5. Enable Serial port. By default, serial port is used for Shell debugging.

Open Terminal of Raspberry PI and run command: sudo raspi-config

Choose Interfacing Options-> Serial -> No -> Yes

【Note】You need to restart Raspberry Pi after enabling serial port

6. Run demo codes(Use example_get_uid.py and rpi_get_uid.c as examples)

Open Terminal and navigate to directory of demo codes:

cd ~/raspberrypi/

1) python code:

Enter directory of python code: cd ~/raspberrypi/python/

Modify example_get_uid.py file, set initialize code to:

#pn532 = PN532_SPI(debug=False, reset=20, cs=4)
#pn532 = PN532_I2C(debug=False, reset=20, req=16)
pn532 = PN532_UART(debug=False, reset=20)

Save.Then run code by command:

python3 example_get_uid.py

2) C code:

Enter directory of c code:cd ~/raspberrypi/c/example/

Modify rpi_get_uid.c file, set initialize code to:

//PN532_SPI_Init(&pn532);
//PN532_I2C_Init(&pn532);
PN532_UART_Init(&pn532);

Save then compile code: sudo make

Run code:

./rpi_get_uid.exe

7. Expected result:Close card to coil part of PN532, the UID of card is read

If demo code of UART run failed, you can test serial port by this example
cd ~/raspberrypi/python/
python3 example_uart_hex.py

Enter data and sent, data sent and received should be printed on terminal as expected. e.g. sent data below to wake up PN532:

55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 03 FD D4 14 01 17 00

The response data should be:

00 00 FF 00 FF 00 00 00 FF 02 FE D5 15 16 00
I2C interface

1. Set K0 as H, L1 as L by jumpers

2. Connect RSTPDN ->D20 and INT0 -> D16(avoid from Clock Stretching) by jumpers

3. Set DIP switch to

SCK MISO MOSI NSS SCL SDA RX TX
OFF OFF OFF OFF ON ON OFF OFF
PN532 NFC HAT-3.jpg

4. Connect PN532 to Raspberry Pi

Connect PN532 NFC HAT to Raspberry Pi via I2C interface
PN532 NFC HAT Raspberry Pi
SCL SCL
SDA SDA

5. Enable I2C interface

Open Terminal of Raspberry Pi and run command: sudo raspi-config

Choose Interfacing Options-> I2C -> Yes


6. Run code(Use example_get_uid.py and rpi_get_uid.c as examples)

Open ternimal and navigate to directory of demo codes:

cd ~/raspberrypi/

1) python code:

Enter directory of python code: cd ~/raspberrypi/python/

Modify example_get_uid.py file, set initialize code to:

#pn532 = PN532_SPI(debug=False, reset=20, cs=4)
pn532 = PN532_I2C(debug=False, reset=20, req=16)
#pn532 = PN532_UART(debug=False, reset=20)

Save, then run code

python3 example_get_uid.py

2) C code:

Enter directory of c code:cd ~/raspberrypi/c/example/

Modify rpi_get_uid.c file, set initialize code to:

//PN532_SPI_Init(&pn532);
PN532_I2C_Init(&pn532);
//PN532_UART_Init(&pn532);

Save then compile codes:sudo make

Run code:

./rpi_get_uid.exe

7. Expected result:Close card to coil part of PN532, the UID of card is read

Arduino examples

1. Make sure that you have installed Arduino IDE in your PC

2. Create a new folder in ...\Arduino\libraries (Installation directory of Arduino IDE) and named it as pn532

3. Copy files pn532.c, pn532.h, pn532_uno.cpp and pn532_uno.h to ...\Arduino\libraries\pn532 from Arduino demo codes

4. Demo codes is under examples\arduino (demo codes you download) directory

5. Herein we take Arduino UNO board as example

SPI interface

1. Set L0 to L and L1 to H by hy jumpers

2. Set DIP switch to:

SCK MISO MOSI NSS SCL SDA RX TX
ON ON ON ON OFF OFF OFF OFF

3. Connect PN532 NFC HAT to Arduino UNO:

Connect PN532 NFC HAT to Arduino UNO via SPI interface
PN532 NFC HAT Arduino UNO
SCK D13
MISO D12
MOSI D11
NSS D4
PN532 NFC HAT-5.png

4. Run codes(Use examples\arduino\uno_get_uid\ uno_get_uid.ino as examples):

Open uno_get_uid.ino file, set initialize code to:

PN532_SPI_Init(&pn532);
//PN532_I2C_Init(&pn532);

Compile and upload codes to Arduino UNO

Open Serial monitor, press Reset button of Arduino Uno to reset

5. Expected result: close card to coil part of PN532, the UID of card is read and printed.

I2C interface

1. Set L0 to L and L1 to H by jumpers

2. Set DIP switch to

SCK MISO MOSI NSS SCL SDA RX TX
OFF OFF OFF OFF ON ON OFF OFF

3. Connect PN532 NFC HAT to Arduino UNO

Connect PN532 NFC HAT to Arduino UNO via I2C interface
PN532 NFC HAT Arduino UNO
SCL A5
SDA A4
PN532 NFC HAT-4.png

4. Run code(Use examples\arduino\uno_get_uid\ uno_get_uid.ino as example):

Open uno_get_uid.ino file, set initialize code to:

//PN532_SPI_Init(&pn532);
PN532_I2C_Init(&pn532);

Compile and upload codes to Arduino UNO board

Open Serial monitor, press Reset button of Arduino UNO board to reset.

5. Expected result: close card to coil part of PN532, the UID of card is read and printed.

STM32 example

The development board used here is Open103C which is based on STM32F103CBT6.

Download project

1. Open project by keil software(...\MDK-ARM\pn532_stm32.uvprojx),Click Rebuild to compile project.

2. Choose programmer:Options for Target -> Debug-> Use,default: ST-Link Debugger。

3. Choose download method:Options for Target -> Debug选项卡 -> Settings -> Debug -> Port,Default: JTAG.

4. Connect Open board to PC by programmer. Note that you should power Open board separately.

5. Click Download to download project.

Hardware connection

1. Set L0 to L and L1 to H by jumpers

2. Set DIP switch to

SCK MISO MOSI NSS SCL SDA RX TX
ON ON ON ON OFF OFF OFF OFF

3. Connect PN632 to Open103C board

Connect PN532 NFC HAT to STM32F via SPI interface
PN532 NFC HAT STM32F103CBT6
SCK PA5
MISO PA6
MOSI PA7
NSS PA4
PN532 NFC HAT-5.png

4. Connect USB to TTL module to UART1 interface (PA9->RX, PA10->TX) of STM32 and PC.

5. Open serial assistant software, and reset Open103C

6. Expected result: close card to coil part of PN532, the UID of card is read and printed.

程序说明

上面的演示是以获取 Mifare Classic 卡的 ID 作为例子(example_get_uid.py / rpi_get_uid.exe / uno_get_uid.ino / stm32_get_uid),下面将对其他示例程序进行说明。

【注意】

使用这些程序之前,请根据实际情况,设置 PN532 NFC HAT 的I0 / I1 跳线以及拨码开关。拨码开关不能同时设置为ON,否则无法接收到正确的数据。简单起见,这里用0表示拨码开关拨到OFF,用1表示拨码开关拨到ON。

  • 使用UART接口的时候,[I1..I0]跳线应设置为LL,拨码开关设置为00000011
  • 使用I2C接口的时候,[I1..I0]跳线应设置为LH,拨码开关设置为00001100。
  • 使用SPI接口的时候,[I1..I0]跳线应设置为HL,拨码开关设置为11110000。

读取Mifare Classic卡内容

程序 开发板
example_dump_mifare.py Raspberry Pi
rpi_dump_mifare.c Raspberry Pi
uno_dump_mifare.ino Arduino UNO
stm32_dump_mifare/MDK-ARM/pn532_stm32.uvprojx STM32F103CBT6


预期结果:把Mifare Classic 卡贴近PN532 NFC HAT,卡的内容会被打印出来

0 : 37 F9 20 69 87 08 04 00 62 63 64 65 66 67 68 69
1 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3 : 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF
4 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
5 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
6 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
7 : 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF
8 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
9 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
11 : 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF
… …
63 : 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF

说明:

  • 每一行的显示内容是对应的块的内容
  • 第0块的前4字节是Mifare Classic卡的UID,第5字节是校验位,是前4字节的异或结果
  • 常规的卡的第0块(UID)是无法修改的
  • 每4个块属于同一个扇区(sector),共用同一个密码,例如4N~4N+3块属于同一个扇区。
  • 第4N+3块是密码块,相应的,如果要读取4N~4N+2块的内容,就必须使用4N+3块所记录的密码
  • 容量为1K的卡,一共有64个块

以读取第6块为例,必须使用对应扇区的密码,即第7块的前6个字节(KEY A)或者后6字节(KEY B)的密码

7 : 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF

前6个字节为KEY A,默认为FF FF FF FF FF FF,但是其读取结果永远为00 00 00 00 00 00。后6字节为KEY B,使用明文存储,Mifare Classic卡默认的KEY A和KEY B均为FF FF FF FF FF FF。

中间的4个字节是访问控制位(Access Bits)。默认值FF 07 80 69,这个数值用于扇区得写的访问权限控制,用户如果对其写入不合适的数值,将会导致卡被锁死。

PN532 NFC HAT-6.png

例如byte6写入0xFF,那么byte7的高4位必须为0b0000, byte 8的低4位必须为0b0000。具体参见MF1S50YYX_V1.pdf 的 Access conditions for data blocks 节

产品随附的卡是魔法卡,通过预留的后门可以解锁,但是用户应当知道,如果使用常规的 Mifare 卡,一旦把访问控制位写错,将会无法修复。所以在写卡的时候要特别注意

读写Mifare Classic卡

程序 开发板
example_rw_mifare.py Raspberry Pi
rpi_rw_mifare.c Raspberry Pi
uno_rw_mifare.ino Arduino UNO
stm32_rw_mifare/MDK-ARM/pn532_stm32.uvprojx STM32F103CBT6


预期结果:把Mifare Classic卡贴近PN532 NFC HAT,第6块的内容会被改写成00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F。

说明:

  • 写入第6块的内容之前,需要保证第6块对应的密码为0xFF FF FF FF FF FF。这个密码即为第7块的前6个字节(读取结果永远为0x00 00 00 00 00 00)。
  • 如果用户修改示例程序、试图写入第N+3块的内容,应该特别小心。因为这部分的内容是N ~ N+2块的密码。应当记住写入的密码,如果忘记密码,那么所在扇区的所有块都将无法读写。

读取NTAG2XX整卡内容

程序 开发板
example_dump_ntag2.py Raspberry Pi
rpi_dump_ntag2.c Raspberry Pi
uno_dump_ntag2.ino Arduino UNO
stm32_dump_ntag2/MDK-ARM/pn532_stm32.uvprojx STM32F103CBT6

预期结果:把Ntag215卡贴近PN532 NFC HAT,卡的内容会被打印出来

0: 04 85 32 3b
1: 92 a8 64 80
2: de 48 00 00
3: e1 10 3e 00
4: 03 00 fe 00
5: 00 00 00 00
6: 00 00 00 00
7: 00 00 00 00
… …
134: 00 00 00 00

说明:

  • Ntag215 卡片需要用户自行购买。
  • 根据习惯,Ntag215 的页(page)相当于Mifare 的块(block),一行代表一页。
  • 第0页的前3字节是UID0-UID2,第4字节是校验位,是前3字节和0x88 (Cascade Tag,由ISO/IEC 14443-3 Type A 定义)的异或结果。
  • 第1页的4个字节是UID3-UID6。
  • 第2页的第1字节是校验位,是UID3-UID6的异或结果

读写NTAG2XX卡

程序 开发板
example_rw_ntag2.py Raspberry Pi
rpi_rw_ntag2.c Raspberry Pi
uno_rw_ntag2.ino Arduino UNO
stm32_rw_ntag2/MDK-ARM/pn532_stm32.uvprojx STM32F103CBT6

预期结果:把NTAG215卡贴近PN532 NFC HAT,第6块的内容会被改写成00 01 02 03。

说明:

  • 第2页的最后两个字节用于标记并锁定03h到0Fh的对应的页为只读,并且这个操作不可逆。使用的时候应该注意这个情况。见NTAG213/215/216 的Static lock bytes (NTAG21x) 节。
PN532 NFC HAT-7.png
  • 要锁定第10h页之后的数据,则把对应的地址写入28h页(NTAG213)或82h页(NTAG215)或E2h页(NTAG216)的前3字节,第4字节读取结果永远是0xBD。见NTAG213/215/216 的Dynamic Lock Bytes节
PN532 NFC HAT-8.png
  • Ntag2xx卡的功能详情请参见 NTAG213/215/216 手册的相关内容。

设置PN532的GPIO电平

程序 开发板
example_write_gpio.py Raspberry Pi
rpi_write_gpio.c Raspberry Pi
uno_write_gpio.ino Arduino UNO
stm32_write_gpio/MDK-ARM/pn532_stm32.uvprojx STM32F103CBT6

预期结果:打印PN532的GPIO电平

Pin P30: 1
Pin P31: 0
Pin P32: 1
Pin P33: 0
Pin P34: 1
Pin P35: 0
Pin P71: 0
Pin P72: 1
Pin I0: 1
Pin I1: 0

说明:

程序尝试设置管脚电平:P30 -> 高,P31 -> 低,P33 -> 低,P35 -> 低,P71 -> 低,P72 -> 高

注意:

  • P32是 int0,一旦写入低电平,将会导致模块复位。
  • P34是SIC_CLK,读取的结果是高电平。
  • P71是MISO,在SPI模式下,读取的结果是高电平。
  • P72是SCK,在SPI模式下,读取的结果是高电平。
  • 模块上电的时候, PN532 会根据I0/I1的电平设置通讯接口。之后可以移除跳线帽,作为普通的GPIO使用。

PN532的P30 – P35电平会在硬件复位(RSTPDN置低2ms然后置高)之后,恢复为高电平。

读取PN532的GPIO电平

程序 开发板
example_read_gpio.py Raspberry Pi
rpi_read_gpio.c Raspberry Pi
uno_read_gpio.ino Arduino UNO
stm32_read_gpio/MDK-ARM/pn532_stm32.uvprojx STM32F103CBT6

预期结果:会打印PN532的GPIO电平

Port P3: 0x3f
Port P7: 0x07
Port I: 0x07
Pin P30: 1
Pin P31: 1
Pin P32: 1
Pin P33: 1
Pin P34: 1
Pin P35: 1
Pin I0: 1
Pin I1: 0

说明:

  • PN532的P30 – P35电平会在硬件复位(RSTPDN置低2ms然后置高)之后,恢复为高电平。

Resources

FAQ

Supports

Support

If you require technical support, please go to the Support page and open a ticket.