使用Adafruit PN532库向NTAG203写入字节数组时被截断的问题
问题原因与解决方案
首先,你遇到的核心问题是误用了Mifare Classic的操作方法来处理NTAG203标签——这两种NFC标签的内存结构和通信协议完全不同,直接混用方法会导致写入/读取数据异常。
具体原因分析
- 标签类型不匹配:NTAG203属于NFC Type 2标签,而
mifare_classic_write_block()/mifare_classic_read_block()是专门为Mifare Classic(Type 1/4)设计的方法。Type 2标签的内存以4字节页面为单位,而Mifare Classic以16字节块为单位,强行用块操作方法写入Type 2标签,会导致数据被错误地拆分或写入到非预期的内存区域,最终出现截断、零值等异常。 - 写入数据的结构错误:你构造的16字节
byte_data试图将12字节内容放在索引3-15,但NTAG203的页面无法直接接收16字节的块数据,因此写入过程中数据被损坏。
修正后的代码实现
我们需要改用Adafruit PN532库中针对NFC Type 2标签的页面操作方法,步骤如下:
import sys import binascii from adafruit_pn532.spi import PN532_SPI import board import digitalio # 初始化PN532(根据你的连接方式调整,这里是SPI示例) spi = board.SPI() cs_pin = digitalio.DigitalInOut(board.D5) pn532 = PN532_SPI(spi, cs_pin, debug=False) pn532.SAM_configuration() # 等待检测标签 print("等待NTAG203标签...") while True: uid = pn532.read_passive_target(timeout=0.5) if uid is not None: print(f"检测到标签,UID: {binascii.hexlify(uid).decode('utf-8')}") break # 你的原始十六进制字符串 hex_string = '59e7168f267df300018e15b0' formatted_hex = bytearray.fromhex(hex_string) # 将12字节数据拆分为3个4字节的页面数据 pages = [formatted_hex[i:i+4] for i in range(0, len(formatted_hex), 4)] # 写入页面4、5、6(NTAG203用户区域从页面4开始) start_page = 4 for i, page_data in enumerate(pages): # 确保每个页面数据是4字节,不足补零(这里原始数据刚好12字节,无需补零) page_data = page_data.ljust(4, b'\x00') if not pn532.nfc_tag.write_page(start_page + i, page_data): print(f"写入页面{start_page + i}失败!") sys.exit(-1) print("数据写入成功!") # 读取写入的页面并拼接 read_data = bytearray() for page_num in range(start_page, start_page + len(pages)): page = pn532.nfc_tag.read_page(page_num) read_data.extend(page) # 转换为十六进制字符串(可直接用于数据库查询) result_hex = binascii.hexlify(read_data).decode('utf-8') print(f"读取到的十六进制数据: 0x{result_hex}")
额外注意事项
- NTAG203的用户内存总共有132个页面(页面4到页面135),每个页面4字节,注意不要超出写入范围。
- 写入前确保标签没有被锁定,默认情况下标签是未锁定状态。
- 如果读取后需要去掉末尾可能的补零,可以用
result_hex.rstrip('0'),但需根据你的实际数据格式判断是否需要。
内容的提问来源于stack exchange,提问作者Sai
相关产品推荐
相关产品推荐

