2025年ESP32开发之旅——RC522模块的使用

ESP32开发之旅——RC522模块的使用ESP32 开发之旅 RC522 模块的使用 前言 在本文中 您将学会如何使用 ESP32 连接 RFID 模块 RC522 本文提供了简单的示例供学习参考 需要注意的是 本文中的 ESP32 是使用 Micro Python 进行开发的 同时 ESP8266 也可按照本文进行开发 本文中出现的代码是从 GitHub 开源库中搬运而来 GitHub 链接已放在文尾 RFID RC522 模块的简单介绍

ESP32开发之旅——RC522模块的使用

前言

在本文中,您将学会如何使用ESP32连接RFID模块RC522,本文提供了简单的示例供学习参考。

需要注意的是,本文中的ESP32是使用Micro Python进行开发的,(同时ESP8266也可按照本文进行开发)。

本文中出现的代码是从GitHub开源库中搬运而来,GitHub链接已放在文尾。

RFID-RC522模块的简单介绍

​ 射频识别RFID(Radio Frequency Identification)是一种无线数据传输系统,用于在标签和读取器设备之间传输数据,而RC522模块则是用于读取和写入RFID卡和标签,该模块的工作频率为13.56MHz。

正文

所需材料

ESP32开发板(已刷入MicroPython固件,未刷入的小伙伴可以参考我前面的教程)

RC522读卡器以及对应频率的RFID卡

Thonny(其他支持MicroPython开发的IDE皆可)

连线说明

​ 在RC522模块上共有8个引脚,实际上我们只需使用7个引脚就可以完成本次的开发。引脚对应表如下:

SignalSCKMOSIMISORSTCS(SDA)
ESP32/ESP8266P0P2P4P5P14

​ (注意:VCC与GND在表格中未标出来,但也需要连接,且VCC使用3.3V电源)

核心代码

mfrc522.py
from machine import Pin, SPI
from os import uname

class MFRC522:

OK = 0
NOTAGERR = 1
ERR = 2

REQIDL = 0x26
REQALL = 0x52
AUTHENT1A = 0x60
AUTHENT1B = 0x61

def __init__(self, sck, mosi, miso, rst, cs):

self.sck = Pin(sck, Pin.OUT)
self.mosi = Pin(mosi, Pin.OUT)
self.miso = Pin(miso)
self.rst = Pin(rst, Pin.OUT)
self.cs = Pin(cs, Pin.OUT)

self.rst.value(0)
self.cs.value(1)

board = uname()[0]

self.spi = SPI(baudrate=100000, polarity=0, phase=0, sck=self.sck, mosi=self.mosi, miso=self.miso)
self.spi.init()

self.rst.value(1)
self.init()

def _wreg(self, reg, val):

self.cs.value(0)
self.spi.write(b'%c' % int(0xff & ((reg << 1) & 0x7e)))
self.spi.write(b'%c' % int(0xff & val))
self.cs.value(1)

def _rreg(self, reg):

self.cs.value(0)
self.spi.write(b'%c' % int(0xff & (((reg << 1) & 0x7e) | 0x80)))
val = self.spi.read(1)
self.cs.value(1)

return val[0]

def _sflags(self, reg, mask):
self._wreg(reg, self._rreg(reg) | mask)

def _cflags(self, reg, mask):
self._wreg(reg, self._rreg(reg) & (~mask))

def _tocard(self, cmd, send):

recv = []
bits = irq_en = wait_irq = n = 0
stat = self.ERR

if cmd == 0x0E:
irq_en = 0x12
wait_irq = 0x10
elif cmd == 0x0C:
irq_en = 0x77
wait_irq = 0x30

self._wreg(0x02, irq_en | 0x80)
self._cflags(0x04, 0x80)
self._sflags(0x0A, 0x80)
self._wreg(0x01, 0x00)

for c in send:
self._wreg(0x09, c)
self._wreg(0x01, cmd)

if cmd == 0x0C:
self._sflags(0x0D, 0x80)

i = 2000
while True:
n = self._rreg(0x04)
i -= 1
if ~((i != 0) and ~(n & 0x01) and ~(n & wait_irq)):
break

self._cflags(0x0D, 0x80)

if i:
if (self._rreg(0x06) & 0x1B) == 0x00:
stat = self.OK

if n & irq_en & 0x01:
stat = self.NOTAGERR
elif cmd == 0x0C:
n = self._rreg(0x0A)
lbits = self._rreg(0x0C) & 0x07
if lbits != 0:
bits = (n - 1) * 8 + lbits
else:
bits = n * 8

if n == 0:
n = 1
elif n > 16:
n = 16

for _ in range(n):
recv.append(self._rreg(0x09))
else:
stat = self.ERR

return stat, recv, bits

def _crc(self, data):

self._cflags(0x05, 0x04)
self._sflags(0x0A, 0x80)

for c in data:
self._wreg(0x09, c)

self._wreg(0x01, 0x03)

i = 0xFF
while True:
n = self._rreg(0x05)
i -= 1
if not ((i != 0) and not (n & 0x04)):
break

return [self._rreg(0x22), self._rreg(0x21)]

def init(self):

self.reset()
self._wreg(0x2A, 0x8D)
self._wreg(0x2B, 0x3E)
self._wreg(0x2D, 30)
self._wreg(0x2C, 0)
self._wreg(0x15, 0x40)
self._wreg(0x11, 0x3D)
self.antenna_on()

def reset(self):
self._wreg(0x01, 0x0F)

def antenna_on(self, on=True):

if on and ~(self._rreg(0x14) & 0x03):
self._sflags(0x14, 0x03)
else:
self._cflags(0x14, 0x03)

def request(self, mode):

self._wreg(0x0D, 0x07)
(stat, recv, bits) = self._tocard(0x0C, [mode])

if (stat != self.OK) | (bits != 0x10):
stat = self.ERR

return stat, bits

def anticoll(self):

ser_chk = 0
ser = [0x93, 0x20]

self._wreg(0x0D, 0x00)
(stat, recv, bits) = self._tocard(0x0C, ser)

if stat == self.OK:
if len(recv) == 5:
for i in range(4):
ser_chk = ser_chk ^ recv[i]
if ser_chk != recv[4]:
stat = self.ERR
else:
stat = self.ERR

return stat, recv

def select_tag(self, ser):

buf = [0x93, 0x70] + ser[:5]
buf += self._crc(buf)
(stat, recv, bits) = self._tocard(0x0C, buf)
return self.OK if (stat == self.OK) and (bits == 0x18) else self.ERR

def auth(self, mode, addr, sect, ser):
return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]

def stop_crypto1(self):
self._cflags(0x08, 0x08)

def read(self, addr):

data = [0x30, addr]
data += self._crc(data)
(stat, recv, _) = self._tocard(0x0C, data)
return recv if stat == self.OK else None

def write(self, addr, data):

buf = [0xA0, addr]
buf += self._crc(buf)
(stat, recv, bits) = self._tocard(0x0C, buf)

if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
stat = self.ERR
else:
buf = []
for i in range(16):
buf.append(data[i])
buf += self._crc(buf)
(stat, recv, bits) = self._tocard(0x0C, buf)
if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
stat = self.ERR

return stat
read.py
import mfrc522
from os import uname
import time

def do_read():
rdr = mfrc522.MFRC522(0, 2, 4, 5, 14)
index = True ###用于标记是否读到卡片
try:
while True:
(stat, tag_type) = rdr.request(rdr.REQIDL)
if stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll()
if stat == rdr.OK:
print("识别到卡片:")
print("uid: 0x%02x%02x%02x%02x" % (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3]))
print("")
index = False
if rdr.select_tag(raw_uid) == rdr.OK:

key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]

if rdr.auth(rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK:
print("Address 8 data: %s" % rdr.read(8))
rdr.stop_crypto1()
else:
print("Authentication error")

except KeyboardInterrupt:
print("Bye")
write.py
import mfrc522
from os import uname
def do_write():
rdr = mfrc522.MFRC522(0, 2, 4, 5, 14)
try:
while True:
(stat, tag_type) = rdr.request(rdr.REQIDL)
if stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll()
if stat == rdr.OK:
print(" - uid: 0x%02x%02x%02x%02x" % (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3]))
print("")

if rdr.select_tag(raw_uid) == rdr.OK:

key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]

if rdr.auth(rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK:
stat = rdr.write(8, b"这里输入你要写入的数据,16进制")
rdr.stop_crypto1()
if stat == rdr.OK:
print("数据已写入")
else:
print("数据写入失败")
else:
print("Authentication error")
else:
print("Failed to select tag")

except KeyboardInterrupt:
print("Bye")

函数调用

此时,您可以通过调用库的方式来实现简单的功能。

如果您想要读取卡的相关信息的话,可以通过下面两行代码进行实现:

import read
read.do_read()

如果您想将信息写入卡的话,可以通过下面两行代码进行实现:

import write
write.do_write()

结尾

本文中出现的代码大部分是在GitHub开源库中搬运过来,并在原有基础上加以修改。

参考文献:

GitHub源码地址

编程小号
上一篇 2025-02-16 16:33
下一篇 2025-02-27 15:06

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/hz/116095.html