RFID(Radio Frequency Identification)卡技术是一种通过无线电波进行自动识别的技术,其核心在于利用射频信号和空间耦合(电感耦合或电磁耦合)实现无接触式的数据通信,RFID系统通常由读写器(Reader)、电子标签(Tag)和后台应用系统三部分组成,其中电子标签是数据载体,根据供电方式可分为无源标签、有源标签和半有源标签,按工作频率可分为低频(LF,125-134kHz)、高频(HF,13.56MHz)、超高频(UHF,860-960MHz)和微波(2.45GHz/5.8GHz),以下将结合技术原理和源代码示例,详细解析RFID卡技术的实现逻辑。

RFID技术原理与硬件交互
RFID标签内置芯片和天线,当进入读写器产生的电磁场时,无源标签通过天线获取能量并激活芯片,随后将存储的数据通过调制方式(如ASK、FSK)发送给读写器;读写器接收到信号后进行解调和解码,将数字数据传输至后台系统,不同频段的RFID技术特性差异显著:高频(HF)标签如Mifare系列,支持加密和复杂协议,常用于门禁、支付场景;超高频(UHF)标签读取距离远(可达10米以上),适合物流盘点等批量识别场景。
以常用的HF RFID(13.56MHz,ISO/IEC 14443标准)为例,其通信流程包括:复位应答(ATR)、防冲突机制、选择卡片、认证(若有)、数据读写,防冲突机制通过时隙分配或随机数方式确保多标签同时出现时能被正确识别;认证环节则依赖密钥验证(如Mifare Classic的3DES加密),保障数据安全。
RFID读写器与标签交互的源代码实现(Python示例)
以下基于pyserial库和串口RFID读写器(模拟PCD-Reader模块),实现标签检测、UID读取及数据块写入功能,代码需配合硬件手册配置串口参数(波特率、数据位、停止位等)。
import serial
import time
class RFIDReader:
def __init__(self, port='COM3', baudrate=9600):
"""初始化串口连接"""
self.serial = serial.Serial(port=port, baudrate=baudrate, timeout=1)
if not self.serial.is_open:
self.serial.open()
def reset(self):
"""发送复位命令,等待标签响应"""
self.serial.write(b'\x02\x00\x00\x01') # 复位指令(示例帧格式)
time.sleep(0.1)
response = self.serial.read(self.serial.in_waiting)
return response
def detect_tag(self):
"""检测是否有标签进入磁场,返回UID"""
self.reset()
self.serial.write(b'\x03\x00\x01\x02') # 检测标签指令
time.sleep(0.2)
response = self.serial.read(12) # 假设响应长度为12字节
if len(response) == 12 and response[0] == 0x03: # 验证响应头
uid = response[1:9].hex() # 提取8字节UID
return uid
return None
def authenticate_block(self, block_addr, key_type=0, key=(0xFF,)*6):
"""认证指定数据块(key_type=0:A密钥,1:B密钥)"""
auth_cmd = bytes([0x04, block_addr, key_type]) + bytes(key)
self.serial.write(auth_cmd)
response = self.serial.read(4)
return response[0] == 0x04 # 认证成功返回0x04
def read_block(self, block_addr):
"""读取指定数据块(4字节)"""
if not self.authenticate_block(block_addr):
return None
read_cmd = bytes([0x05, block_addr])
self.serial.write(read_cmd)
response = self.serial.read(6) # 响应头+4字节数据
return response[2:6] if response[0] == 0x05 else None
def write_block(self, block_addr, data):
"""向指定数据块写入4字节数据"""
if not self.authenticate_block(block_addr):
return False
write_cmd = bytes([0x06, block_addr]) + bytes(data)
self.serial.write(write_cmd)
response = self.serial.read(4)
return response[0] == 0x06
def close(self):
"""关闭串口连接"""
self.serial.close()
# 使用示例
if __name__ == "__main__":
reader = RFIDReader()
try:
uid = reader.detect_tag()
if uid:
print(f"检测到标签UID: {uid}")
# 读取第0块数据(通常为UID,部分标签需认证)
block0_data = reader.read_block(0)
print(f"第0块数据: {block0_data.hex() if block0_data else '读取失败'}")
# 写入第1块数据(示例:写入0x12,0x34,0x56,0x78)
write_success = reader.write_block(1, [0x12, 0x34, 0x56, 0x78])
print(f"第1块写入结果: {'成功' if write_success else '失败'}")
else:
print("未检测到标签")
finally:
reader.close()
源代码解析与关键逻辑
- 串口通信:通过
pyserial库与读写器硬件交互,命令帧格式需遵循硬件协议(如示例中的帧头、命令字、地址、校验位等)。 - 标签检测流程:发送复位命令激活标签,通过检测响应中的UID判断标签是否存在。
- 认证机制:Mifare Classic等标签需先认证才能读写数据,密钥需提前配置(如默认密钥或自定义密钥)。
- 数据读写:认证成功后,通过读写指令操作指定数据块(每块16字节,部分协议为4字节),需注意数据格式转换(如字节序)。
不同硬件平台的指令集可能不同,例如基于RC522模块的Arduino代码需调用MFRC522库,通过SPI接口通信,核心逻辑类似(复位、防冲突、认证、读写)。

RFID技术常见应用场景与协议适配
| 应用场景 | 常用频段 | 协议标准 | 典型标签类型 | 源代码适配要点 |
|---|---|---|---|---|
| 门禁/支付 | HF | ISO/IEC 14443A | Mifare Classic/S50 | 需实现3DES认证,数据块加密存储 |
| 物流/库存管理 | UHF | EPC Gen2 | Alien Higgs-3 | 需处理EPC编码,支持批量读取防冲突 |
| 动物识别 | LF/HF | ISO/IEC 11784/85 | FDX-B | LF标签读取距离近,需优化天线设计 |
| 图书管理 | HF | ISO/IEC 15693 | ICODE SLIX | 支持多标签快速读取,无需认证 |
相关问答FAQs
Q1: RFID标签数据写入失败可能的原因及解决方法?
A: 可能原因包括:① 未通过认证(密钥错误或权限不足);② 数据块为只读区域(如厂商保留块);③ 硬件连接问题(串口波特率不匹配、天线故障),解决方法:首先验证密钥是否正确,检查数据块地址是否可写(如Mifare S50的0-3块为厂商数据块,不可直接写入),使用串口调试工具测试硬件通信是否正常,确保读写器天线与标签距离在有效范围内(HF标签通常<5cm)。
Q2: 如何实现多标签同时读取时的防冲突处理?
A: RFID防冲突机制基于ALOHA协议或二进制树搜索算法,以ISO/IEC 14443A标准为例,防冲突流程为:① 读写器发送REQ_ALL命令,激活所有标签;② 标签返回UID的一部分(如 cascade level 1 的5位UID);③ 读写器根据返回的UID片段,通过SELECT命令选择唯一标签,完成通信后释放该标签,重复上述步骤直至所有标签被识别,源代码中需实现防冲突指令(如anticollision_cmd)和UID碰撞检测逻辑,部分硬件库(如MFRC522)已封装该功能,可直接调用。

