
第一次把 RC522 模块接到 ESP32 上是在一个周六下午。当时手里只有一块几十块钱的乐鑫开发板、一个十块钱不到的读卡模块加上公司门禁卡。接线、烧录、放卡串口监视器里跳出那串十六进制 UID 的瞬间我突然觉得“刷卡”这个听起来很高端的能力其实就是几行代码的事。RFID 无线射频识别听上去很玄但拆开看就是一个模块负责发无线电波、一张卡负责回应、单片机负责读编号。这个项目要做的事很明确让 ESP32 通过 RC522 模块识别 13.56MHz 的 M1 卡把卡号读出来再根据需要控制灯光、蜂鸣器甚至是舵机。学会之后门禁、考勤、会员签到、宿舍门锁这些常见场景你都能用同一套思路去搭。文章的受众就是零基础想玩硬件的朋友不用会画电路不用懂电磁场只要会复制代码、会插杜邦线跟着走一遍就能跑起来。整个系列我按“原理 → 接线 → 环境 → 代码 → 中断进阶 → 场景 → 排错”的顺序来写过程中会夹一些我踩过的坑。读完你不仅能点亮一个 RFID 读卡器还能把它变成一个能“认人”的小门禁模型。1. 项目拆解RFID 读卡到底是怎么一回事1.1 为什么选 RC522 而不是其他模块市面上常见的 RFID 读卡模块大致分两类。一类是工作在 125kHz 低频的模块比如 RDM6300主要搭配 EM4100 这种只读 ID 卡常用于老式门禁。另一类是工作在 13.56MHz 高频的模块代表就是 RC522核心芯片是 NXP 的 MFRC522支持 ISO/IEC 14443A 协议能读 Mifare Classic 系列卡也就是我们最常见的 M1 卡、S50 卡。选择 RC522 的理由非常实在便宜、资料多、库成熟。一个模块加两张卡总成本控制在二十元以内。Arduino 生态里有维护了很久的 MFRC522 库几乎所有功能都有现成 API不需要从寄存器层面开始写。相比之下低频模块虽然便宜但协议封闭和手机 NFC 也不互通玩起来受限。RC522 工作频率和公交卡、门禁卡相同这意味着你手头的卡片大概率可以直接拿来做实验。实际购买时RC522 模块常见蓝色和红色两种 PCB功能一样价格差别不大。区别在于个别版本的天线走线有细微调整读卡距离会有几毫米的差异这点后面排查部分会提到。需要注意的是一些超低价模块焊接质量一般拿到手先看一下天线线圈有没有虚焊。1.2 RFID、NFC 与 13.56MHz 的关系很多新手会把 RFID 和 NFC 混为一谈其实 NFC 是 RFID 的一个子集。RFID 是“无线射频识别”的总称低频、高频、超高频都算NFC 特指工作在 13.56MHz 的一套标准包含多种协议和交互模式。手机上的刷卡、碰一碰传输底层都是这套东西。RC522 工作在 13.56MHz支持 ISO/IEC 14443A。这个标准把通信分为 Type A 和 Type B 两种国内门禁、公交领域大量使用 Type A 的 Mifare 卡。所以当你把门禁卡放到 RC522 上时模块通过天线产生射频场卡内芯片感应取电然后回传一串数据。整个过程不需要物理接触也不需要精确对准离线圈一两厘米就能读到这就是“无线”二字的含义。生活类的类比读卡器和卡片的关系很像两台对讲机一个持续喊话另一个听到后回话。RC522 的职责就是不断发出询问信号一旦有卡进入射频场双方就开始“对话”最终把卡片的唯一编号传给单片机。1.3 M1 卡的结构扇区、块和 UID要理解读卡程序至少要对 M1 卡的内部结构有个基本概念。M1 卡Mifare Classic 1K内部有 16 个扇区每个扇区有 4 个块每个块 16 字节。第 0 扇区的第 0 块是厂商块里面存着卡的 UID、校验位和厂商数据这部分出厂就写死了普通用户改不了。UID 就是卡的唯一编号常见长度是 4 字节也有 7 字节的卡。对于门禁、考勤这类应用大多数场景只是把 UID 当作用户标识比对一下就够了并不需要读取扇区数据。这也是零基础最友好的切入点你不需要理解加密算法不需要操作密钥只要能读出卡号项目就已经成功了一大半。至于扇区读写和密钥验证那是做会员储值、票务系统时才需要深入的部分。项目可以先把 UID 通道打通后面真有需求再去啃数据区操作。我见过不少人一上来就想读扇区结果被密钥和块地址搞得头大其实完全没必要。2. 硬件准备与接线零基础也能一次接对2.1 物料清单做这个项目不需要多少东西我列一下最低配和推荐配。最低配需要一块 ESP32 开发板经典 DevKit、NodeMCU-32S、S3 Super Mini 都行、一个 RC522 模块、一张 M1 空白卡或者钥匙扣卡、若干杜邦线。如果你手头有公司门禁卡或校园卡先确认是 13.56MHz 的 M1 卡就能直接用但测试时请用合法持有的卡。推荐配再加一个无源蜂鸣器、一颗 LED 灯珠加电阻、一块 OLED 显示屏。这些东西后续做门禁模型时会用到反正单价都便宜一次备齐省得再下单。特别说明RC522 模块自带天线不需要额外焊接天线卡片可以用空白卡十几块钱能买一沓。2.2 RC522 引脚功能RC522 模块引出 8 个引脚分别是 VCC、RST、GND、MISO、MOSI、SCK、SDA、IRQ。逐个说VCC 接 3.3V绝对不能接 5V。模块上的芯片是 3.3V 供电5V 可能直接烧掉。RST 是复位引脚接 ESP32 的一个 GPIO让程序可以软复位模块。GND 接地。SDA 在 SPI 模式下是片选信号也叫 SS。模块上写 SDA但功能就是片选。SCK、MOSI、MISO 是 SPI 时钟和数据线。IRQ 是中断输出引脚卡片进入射频场时能拉低电平本章可以先不接进阶部分再讲。这里要养成一个习惯拿到任何模块先看丝印再查数据手册。RC522 模块引脚顺序在不同批次里可能有细微差异网上搜到的引脚图不一定和你手上这块完全一致。我有一块蓝色板子的丝印把 MOSI 和 MISO 标反了幸好上电前多看了一眼。2.3 ESP32 与 RC522 的 SPI 接线表ESP32 的 SPI 外设比较多Arduino 环境下默认使用 VSPI经典 DevKit 上默认引脚是 SCKGPIO18、MISOGPIO19、MOSIGPIO23。片选和复位可以自定义我习惯用 GPIO21 做 SDA、GPIO22 做 RSTIRQ 用 GPIO27。接线对应如下RC522 引脚ESP32 GPIO说明SDAGPIO21片选 SSSCKGPIO18SPI 时钟MOSIGPIO23主机输出从机输入MISOGPIO19主机输入从机输出IRQGPIO27中断输出可先不接RSTGPIO22模块复位GNDGND共地VCC3.3V供电如果你用的是 S3 Super Mini 这类板子引脚布局不同不要照着这个表硬接。方法是查一下你所用开发板的引脚图找出一组支持 SPI 的引脚把代码里的 SCK、MOSI、MISO 对应的 GPIO 数字改成和接线一致就行。接线本身不难难的是很多人懒得对照引脚图。2.4 供电与电平为什么不能图省事接 5VRC522 模块的 VCC 必须接 3.3V这是硬性规定。ESP32 开发板上的 3.3V 引脚能给 RC522 供电吗可以。RC522 工作电流在几十毫安级别ESP32 板载稳压器一般能输出几百毫安带动这个模块没有压力。但如果你同时接了 OLED、蜂鸣器、舵机等外设3.3V 轨的电流预算就会吃紧表现为读卡不稳定、模块随机复位。这种时候不要硬撑可以外接一个 AMS1117-3.3 稳压模块或者使用独立供电的 3.3V 电源。信号线方面ESP32 和 RC522 都是 3.3V 逻辑电平不需要转换直接连即可。间距问题也要提一句杜邦线别贪长10cm 以内最佳。SPI 虽然速度不算高但太长或接触不良会导致时序混乱现象就是“编译烧录都正常就是读不到卡”。我见过不少新手折腾半天最后发现是母头杜邦线松了。3. 开发环境搭建装好 ESP32 开发板支持包3.1 Arduino IDE 与开发板管理器地址这个项目用 Arduino IDE 开发最省心。去官网装最新版 IDE注意安装路径别带中文。装完后打开“文件 → 首选项”在“附加开发板管理器网址”里填写 ESP32 的支持包地址。官方地址是https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json如果这个地址访问不畅可以换成 GitHub Pages 的镜像地址。填好之后在“工具 → 开发板 → 开发板管理器”里搜索“esp32”会看到 Espressif 官方的支持包点安装。这个包体积不小首次下载可能要花一段时间取决于网络环境。3.2 国内下载慢或失败的离线包方案很多人卡在开发板管理器下载 esp32 支持包这一步进度条不动等半小时还是失败。这里分享一个离线安装的方法。先去网上找一个对应版本的 esp32 离线包一般是一个压缩文件里面包含 esp32 的工具链和固件。然后找到 Arduino 的“staging”目录Windows 在C:\Users\你的用户名\AppData\Local\Arduino15\staging\packagesmacOS/Linux 在~/.arduino15/staging/packages。把这个离线包的内容放进去再回到开发板管理器点安装Arduino 就会优先使用本地文件速度飞快。判断离线包是否放对位置可以在开发板管理器里看安装进度是否瞬间跳到 100%。如果点了安装还是从零开始下载多半是文件名或目录层级不对。这个方法也适用于 PlatformIO 用户不过 PlatformIO 的离线包路径不同原理类似。3.3 选对开发板型号与烧录方式开发板支持包装好后第一件事是选择正确的板型。经典 ESP32 DevKit 选“ESP32 Dev Module”ESP32-S3 选“ESP32S3 Dev Module”ESP32-C3 选“ESP32C3 Dev Module”。选错型号轻则编译报错重则烧录后跑不起来。判断方法很简单看你的开发板主控芯片丝印ESP32、ESP32-S3、ESP32-C3 外观和引脚完全不同。然后选串口端口。Windows 下打开设备管理器查看“端口 (COM 和 LPT)”常见的是COM3、COM5这种编号。如果插上开发板后没有出现新端口说明缺驱动。经典 DevKit 多用 CP2102 或 CH340 芯片需要对应装驱动。装好驱动后端口会识别出来。烧录时有个经典问题点击上传后日志停在“Connecting.....”进度条不动。解决方法是用手指按住开发板上的 BOOT 键点击烧录等日志出现下载进度后再松开 BOOT。对于部分自动下载电路做得比较好的板子不需要手动按但如果遇到问题这个手动操作永远是最稳的后备方案。烧录完成后按一下开发板上的 EN/RST 键让程序重启。3.4 串口监视器验证基础输出环境有没有配好可以用一个空程序验证。新建草稿写入最简单的Serial.begin(115200)加loop里每秒钟打印一行ESP32 OK烧录后打开串口监视器波特率选 115200。能看到滚动输出说明整个链路——驱动、端口、板型、工具链——全部正常。这一步值得做因为排错时我们可以把变量缩小到“硬件接线”和“代码逻辑”而不是环境问题。4. 核心代码实现让 ESP32 读出一张卡的 UID4.1 安装 MFRC522 库Arduino 环境下的 RC522 驱动社区最常用的是 Miguel Balboa 维护的 MFRC522 库。打开“工具 → 管理库”搜索“MFRC522”找到由 GithubCommunity 维护的那个安装即可。这个库封装了访问寄存器、初始化模块、轮询卡片、读取序列号等操作零基础完全不用关心底层协议细节。有一点要提醒如果之前装过其他版本的 RFID 库项目里可能会出现函数冲突。建议先卸载无关库保持环境干净。装好后可以在“文件 → 示例 → MFRC522”里看到官方示例先把ReadUID这个示例编译一遍能编译通过就说明库装好了。4.2 轮询读卡号完整代码接下来写第一个真正能跑的程序。功能很简单循环检测有没有卡片靠近读到就通过串口打印 UID。代码如下#include SPI.h #include MFRC522.h #define RST_PIN 22 #define SS_PIN 21 MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { Serial.begin(115200); SPI.begin(); mfrc522.PCD_Init(); Serial.println(RFID Reader Ready); } void loop() { // 检测是否有新卡进入射频场 if (!mfrc522.PICC_IsNewCardPresent()) { return; } // 读取卡片序列号 if (!mfrc522.PICC_ReadCardSerial()) { return; } Serial.print(UID: ); for (byte i 0; i mfrc522.uid.size; i) { Serial.print(mfrc522.uid.uidByte[i], HEX); if (i mfrc522.uid.size - 1) { Serial.print(:); } } Serial.println(); // 停止与当前卡片的通信 mfrc522.PICC_HaltA(); }这段代码看着不长但该有的都有。SS_PIN对应接线的片选脚RST_PIN对应复位脚。如果你的接线不是 GPIO21/GPIO22改这两个宏定义即可。4.3 代码逐段拆解每个函数在干什么MFRC522 mfrc522(SS_PIN, RST_PIN);这行创建了模块对象两个参数就是片选和复位引脚。构造函数内部不做初始化真正的初始化在setup里。SPI.begin()启动 ESP32 的 SPI 外设。mfrc522.PCD_Init()对 RC522 模块执行复位和初始化配置包括设置波特率、天线增益等。执行完成后模块应该处于持续发射射频场的状态这时候把卡放上去就能检测到。loop里的流程是“先查再读”。PICC_IsNewCardPresent()查询模块的寄存器看是否有新卡进入射频场。注意这个函数名容易误导新手它不是说“是否有一张卡在附近”而是“自上次检测以来是否有新的卡片出现”。如果你把卡一直放在天线上面不拿走这个函数每次循环返回的可能都是 false因为卡片没有“变化”。读完之后把卡移开再放回去它才会返回 true。PICC_ReadCardSerial()执行防碰撞算法选出一张卡并读取其序列号结果存放在mfrc522.uid结构体里。uid.size表示 UID 字节数uid.uidByte[]是具体的字节数组。打印时用HEX格式是为了显示十六进制不然会输出十进制数字不好辨认。最后PICC_HaltA()让卡片进入 HALT 状态停止当前操作。如果省略这一步某些情况下会影响下一次读卡。4.4 运行验证与预期输出烧录完成后打开串口监视器波特率选 115200。如果一切正常你会看到一行RFID Reader Ready。这时候把一张 M1 卡放到 RC522 天线线圈上方串口会弹出一行 UID类似UID: A1:B2:C3:D4放第二张卡UID 不同。这个编号就是卡片出厂固化的唯一标识。如果放卡后没有任何输出先检查串口监视器的换行符设置为“换行”或“无”有些设置会影响输出显示再看接线有没有松动VCC 是否真的是 3.3V。我第一次做的时候把 SDA 和 RST 接反了现象就是模块能通电但完全读不到卡。如果输出的 UID 后面出现乱码大概率是波特率没选对或者 RX/TX 接反。这个项目只用到 ESP32 通过 USB 串口打印不涉及和 RC522 的 UART 通信所以 RX/TX 反了的可能性不大重点检查波特率。5. 从轮询到中断刷卡响应升级5.1 为什么要用外部中断第 4 章的循环方式叫轮询程序不断让 CPU 去问“来卡了吗来卡了吗”。这在大多数教学演示里够用但有两个短板。第一整个loop被读卡操作占住如果后面还要处理屏幕刷新、网络请求、舵机控制等卡的时候 CPU 是空转的响应不及时。第二如果要做低功耗场景比如电池供电的宿舍门锁轮询意味着系统无法深度睡眠因为得一直醒着看有没有卡。外部中断的思路是RC522 的 IRQ 引脚在检测到卡片进入射频场时会输出一个低电平信号。这个信号连接到 ESP32 的一个 GPIO当 GPIO 检测到电平变化CPU 会暂停当前任务跳去执行一个中断服务函数。整个过程由硬件触发不需要 CPU 反复查询。生活化的类比轮询像一个保安每隔几秒巡查一次门口外部中断是门口装了门铃有人按铃保安立刻知道。显然后者在等待的时候可以做别的功耗也更低。5.2 让 RC522 的 IRQ 引脚真正工作起来RC522 支持中断输出但不是默认全开。MFRC522 库初始化后IRQ 引脚处于什么状态取决于寄存器配置想让“检测到新卡”这一事件通过 IRQ 通知外部需要手动使能相关中断位。在初始化代码里PCD_Init()之后加上这几行寄存器配置// 使能 MFRC522 的 IRQ 输出 // ComIrq 中的 TimerIrq、RxIrq、IdleIrq 使能 // DivIrq 中的 CRC 中断使能不同版本的库对寄存器掩码的支持略有差异所以我把这部分单独拿出来说明。最省事的做法是先用轮询版本验证硬件没问题再接 IRQ 引脚然后逐步加上寄存器配置。如果配置完 IRQ 还是不动先退回轮询版本别在寄存器的坑里浪费时间。我实际测过RC522 的 IRQ 触发逻辑在不同厂的模块上表现不一致有的模块 IRQ 引脚在卡片进入时拉低很明显有的模块输出电平很微弱需要接上拉电阻才能稳定识别。5.3 中断版代码接好 IRQ让卡片“自己敲门”接线时把 RC522 的 IRQ 引脚连到 ESP32 的 GPIO27其余接线不变。代码在轮询版本基础上改造#include SPI.h #include MFRC522.h #define RST_PIN 22 #define SS_PIN 21 #define IRQ_PIN 27 MFRC522 mfrc522(SS_PIN, RST_PIN); // 中断标志位ISR 里置位主循环里处理 volatile bool cardDetected false; void IRAM_ATTR onCardDetect() { cardDetected true; } void setup() { Serial.begin(115200); pinMode(IRQ_PIN, INPUT_PULLUP); SPI.begin(); mfrc522.PCD_Init(); // 尝试使能 RC522 的 IRQ 事件输出 mfrc522.PCD_WriteRegister(mfrc522.ComIEnReg, 0xA0); mfrc522.PCD_WriteRegister(mfrc522.DivIEnReg, 0x01); attachInterrupt(digitalPinToInterrupt(IRQ_PIN), onCardDetect, FALLING); Serial.println(Interrupt RFID Ready); } void loop() { if (!cardDetected) { return; } // 清除标志位并在主循环中完成实际的读卡操作 cardDetected false; delay(50); // 等待模块稳定 if (mfrc522.PICC_IsNewCardPresent() mfrc522.PICC_ReadCardSerial()) { Serial.print(Card UID: ); for (byte i 0; i mfrc522.uid.size; i) { Serial.print(mfrc522.uid.uidByte[i], HEX); if (i mfrc522.uid.size - 1) { Serial.print(:); } } Serial.println(); mfrc522.PICC_HaltA(); } }5.4 中断服务函数的三个铁律ESP32 的中断服务函数ISR有严格限制。不能在里面调用delay不能做耗时操作不能使用Serial.print。原因很简单中断服务函数是在特殊上下文里执行的运行时间过长会导致系统不稳定甚至触发看门狗复位。正确的做法是只在 ISR 里置位一个标志变量然后立刻返回。主循环检测到标志位后再执行真正的读卡、打印、控制外设等操作。这段代码里的volatile关键字不能省略它告诉编译器这个变量可能在中断里被修改每次使用都要从内存读取避免优化导致漏读。实测经验加了中断后卡放上去会有一种“立刻知道”的感觉非常跟手。但从触发中断到真正调用PICC_ReadCardSerial()中间要留一个短暂延时因为 RC522 内部状态机需要一个过程完成防碰撞和选卡。延时 50ms 是我调试下来比较稳的数值太短会读失败太长则失去中断的“即时感”。中断版和轮询版怎么选我的建议是新手阶段用轮询先把功能跑通进阶做低功耗或复杂系统时再切中断。不要为了追求技术感强行用中断给自己增加排错难度。6. 做一个小门禁模型把“刷卡能力”变成场景6.1 功能设计与接线扩展读卡号本身没有实际意义把它变成应用才有意思。最简单的小门禁模型预先在程序里存一张“白名单”卡号读到卡后比对匹配成功就把 GPIO 拉高几秒钟点亮 LED 或者驱动蜂鸣器响一声模拟“开门放行”不匹配就在串口打印“拒绝访问”。接线在原有基础上加两个外设LED 正极接 GPIO2经典 ESP32 DevKit 上板载 LED 就在这个脚串一个 220Ω 电阻到 GND无源蜂鸣器正极接 GPIO4负极接 GND。不需要额外库digitalWrite和tone就够用。6.2 白名单匹配代码在中断版代码的读卡成功分支里加入 UID 比对逻辑。先把你手里那张测试卡的 UID 拿纸记下来然后替换下面代码里的示例值// 白名单替换成你实际读到的那张卡的 UID 字节 byte allowedUID[4] {0xA1, 0xB2, 0xC3, 0xD4}; bool checkUID(byte uid[], byte size) { if (size ! 4) return false; for (byte i 0; i 4; i) { if (uid[i] ! allowedUID[i]) return false; } return true; }在主循环中调用if (checkUID(mfrc522.uid.uidByte, mfrc522.uid.size)) { digitalWrite(LED_PIN, HIGH); tone(BUZZER_PIN, 1000, 200); delay(2000); digitalWrite(LED_PIN, LOW); Serial.println(Door Open); } else { tone(BUZZER_PIN, 200, 300); Serial.println(Access Denied); }支持多张卡的做法是把allowedUID改成二维数组循环比对。比如定义 5 个允许通过的卡号用一个 for 循环逐个检查匹配一个就开门。这种静态白名单适合演示和单人场景真正的门禁系统肯定要把白名单放到服务器端但在本地跑通这套逻辑你就掌握了核心。6.3 扩展方向OLED 显示、考勤上报与远程联动小门禁模型跑通之后能往很多方向延伸。最常见的是加一块 OLED显示刷卡人的卡号和通过状态这样就不用一直盯着串口监视器看。OLED 用的是 I2C 接口和 RC522 的 SPI 不冲突能同时工作。另一个方向是考勤系统。ESP32 读到 UID 后可以通过串口把卡号和当前时间发给 PC 端上位机程序也可以用板载 WiFi 把数据 POST 到局域网服务器。C# 做上位机收串口数据、写数据库、做报表是很经典的组合。原理不复杂ESP32 这边负责“刷卡采集”上位机那边负责“记录比对”中间的通信协议就是一行拼接字符串。当年我做第一个考勤原型时就是让 ESP32 在读到卡后打印一行 CSV 格式数据上位机用串口读取后按逗号分割非常朴素但非常实用。再进一步可以用 ESP32 的 WiFi 结合小程序或 App 做远程开门、临时密码下发。这些方向都建立在“ESP32 能读到卡号”这个基础上所以阅读到这里你已经把底座打牢了。7. 常见问题与排查技巧7.1 常见问题速查表这个项目我前前后后帮人调试过不少次把最高频的问题整理成一张表现象可能原因解决办法串口监视器没有任何输出波特率错误/模块未收到电源/板型选错确认 115200、VCC 接 3.3V、开发板选择正确模块 LED 不亮供电问题或模块损坏用万用表量 VCC 与 GND 电压放卡后读不到 UID片选/复位接反、杜邦线虚接核对 SDA 与 RST换线重插读卡距离小于 5mm天线线圈有问题/卡片类型不匹配换模块或换卡M1 卡读距 1-3cm 是正常的烧录时报 “Connecting”未进入下载模式按住 BOOT 再点上传编译报错找不到 MFRC522.h库没装或版本不对重新在库管理器安装程序跑一会就崩供电不足外接 3.3V 电源减少杜邦线长度读卡时灵时不灵IRQ 配置干扰/接线接触不良先退回轮询模式测试7.2 几个我实际踩过的坑第一杜邦线是最大的不稳定源。RC522 需要的连线不算多但两根线之间如果接触不良现象就是时好时坏。排查时优先把每根线都重新插拔一遍或者干脆用烙铁把线焊到模块上一劳永逸。第二金属桌面会严重拉低读卡距离。RC522 的天线本质是一个线圈靠近金属物体时射频场会被金属吸收或干扰。我最早是在笔记本金属外壳上调试读卡距离只有几毫米后来把模块悬空距离立刻变回两三厘米。实验时尽量让模块远离金属。第三手机 NFC 模拟的卡不一定能读。很多手机自带 NFC 模拟门禁卡功能但模拟的可能是加密卡转换后的格式RC522 默认配置读不到。这个问题不是硬件故障不用折腾。第四RC522 读卡距离本来就不远。宣传“几厘米”指的是理想环境实际使用时一到两厘米是常态。很多模块出厂天线没有调谐好距离会更短这是模块本身的物理限制不是代码问题。7.3 上手实测中的一些体会这个项目我后来在一台废弃的树莓派旁边搭了个宿舍门锁原型用舵机把锁舌拨开配上 OLED 显示欢迎信息。运行了几个月的体会是RC522 这种模块性能上限不算高但胜在稳定可靠、逻辑简单非常适合做入门项目。给我的经验是先把轮询版本跑通再把中断加上最后再往里面扩展业务逻辑。每一步都保持“能跑”的状态出了问题能快速定位。不要试图一步到位同时写中断和 OLED 和网络请求一旦出错排查成本会翻很多倍。按这个节奏走零基础的人一个下午也能完成从零到刷卡的跨越。