MFRC522读卡模块接Arduino:读卡号做门禁

2026-11-10 20:21:33 17阅读

门禁卡贴上去"滴"一声就开门,这套东西拆开看其实非常简单:一张 13.56MHz 的卡,一个读卡芯片,一片主控。Arduino 玩家里最常见的读卡方案就是 MFRC522 模块,十几块钱的套件里几乎必带一张白色 MIFARE 卡和一个蓝色钥匙扣。这篇把它接到 Arduino UNO 上,读出卡片 UID,再做一个最小门禁判断:匹配的卡放行,不匹配的拒绝。

先交代器件底细。MFRC522 是 NXP 做的读写芯片,工作在 13.56MHz,走 ISO/IEC 14443A 协议,也就是 MIFARE 那一族。模块供电必须是 3.3V,这点要刻在脑子里——接 5V 会把模块烧掉。通信走 SPI,模块上八个引脚里 IRQ 大多数例程都空着不接。套件里那张白卡是 MIFARE Classic 1K,容量 1KB,分成 16 个扇区、每扇区 4 个块。

接线:六根杜邦线的事

模块引脚虽然标着 SDA,实际是 SPI 的片选(SS),不是 I2C 的数据线,这点最容易让新手犯迷糊。对 UNO 的接线如下:

  • SDA 接 D10(SPI 片选)
  • SCK 接 D13,MOSI 接 D11,MISO 接 D12(SPI 总线)
  • RST 接 D9
  • VCC 接 3.3V,GND 接 GND,IRQ 悬空

Arduino UNO 与 RFID-RC522 模块接线示意图

再强调一次:VCC 千万别接 5V 引脚。UNO 的 SPI 引脚是 5V 电平,大量玩家直接这么接也没出事,但稳妥的做法是给 SCK、MOSI、SS、RST 这几条线加分压电阻,唯独 MISO 不用管。第一次搭,先按直连来,能跑通再说。

装库:认准 GithubCommunity 那个 MFRC522

打开 Arduino IDE,左侧库管理器图标点进去,搜 MFRC522,选 by GithubCommunity 的那个(GitHub 上 miguelbalboa 维护的仓库),点安装。装完重启 IDE,文件菜单的示例里就会出现 MFRC522 一族,里面有 DumpInfo 这个经典例程——把卡贴上去,能把卡里所有扇区的内容整个倒出来看。

接线图对照:RFID-RC522 各引脚到 UNO 的对应关系,SCK 13、MISO 12、SDA 10、RST 9、MOSI 11,VCC 走 3.3V

RFID-RC522 与 Arduino UNO 引脚对应接线图

读 UID:串口监视器看卡号

先跑 DumpInfo,打开串口监视器(9600 波特率),把白卡贴到天线上,屏幕会刷出一整屏数据:卡片类型、UID、16 个扇区每个块的内容都在里面。UID 是出厂写死、只读的那 4 个字节,白色 MIFARE 卡基本都是 4 字节 UID。

串口监视器输出的 MIFARE 卡读卡信息

把自己卡的 UID 记下来,下面门禁判断要用。门禁的原理朴素得很:每张卡 UID 唯一,读到的 UID 和白名单对得上就放行,对不上就拒绝。

门禁小实验:完整代码

下面这份例程改自 Random Nerd Tutorials 的门禁示例,逻辑是逐字节拼出 UID 字符串,和预设卡号比对:

/*
 *
 * All the resources for this project: http://randomnerdtutorials.com/
 * Modified by Rui Santos
 *
 * Created by FILIPEFLOP
 *
 */

#include "SPI.h"
#include "MFRC522.h"

#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

void setup()
{
  Serial.begin(9600);   // Initiate a serial communication
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522
  Serial.println("Approximate your card to the reader...");
  Serial.println();

}
void loop()
{
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }
  //Show UID on serial monitor
  Serial.print("UID tag :");
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
     Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], HEX);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.println();
  Serial.print("Message : ");
  content.toUpperCase();
  if (content.substring(1) == "BD 31 15 2B") //change here the UID of the card/cards that you want to give access
  {
    Serial.println("Authorized access");
    Serial.println();
    delay(3000);
  }

 else   {
    Serial.println(" Access denied");
    delay(3000);
  }
} 

尖括号头文件写成了双引号形式,两者在 Arduino 工具链下编译等价,直接粘贴可用。上传后把代码里 BD 31 15 2B 换成你刚才记下的卡号,开串口监视器:授权的卡贴上去显示 Authorized access,拿钥匙扣或者别的卡试,就是 Access denied。门禁的判断环节,到这一步就闭环了。

读不出来?先查这几处

例程启动时会打印固件版本号,这一行就是接线自检:打出版本号说明 SPI 通了,打印 0x00 或 0xFF 就是通信失败——回头检查 MISO 有没有插对、3.3V 有没有接实。RC522 发射瞬间电流能到 130mA 左右,杜邦线接触电阻偏大时 3.3V 会被拉低,模块中途复位,表现为时灵时不灵,把线焊死或者换粗线能解决。

另一个坑是金属:天线贴着金属外壳放,涡流会把 13.56MHz 的谐振拖偏,读卡距离骤降甚至读不到,垫高 1 厘米以上或者加铁氧体隔磁片。

想把小实验往真门禁推进,下一步无非是加继电器驱动电磁锁、加 LED 指示、把白名单做成多卡表。逻辑还是这一套:读 UID、查表、执行。能把这个最小系统跑稳,剩下的都是加法。


作者:固件烧录仔
链接:https://www.aiddithome.com/p/4a458c46b686f.html
本作版权归作者所有,未经允许请勿转载。若存在违规行为,您可以点击 “举报”。


登录 后发表评论
3条评论
阿强焊点总飞
1楼 · 3小时前

上周刚在海鲜市场淘了个RC522套件,卡在固件版本号打印0xFF那一步,看完才知道是MISO没插对。文章里130mA拉低3.3V那段说得太对了,我用的杜邦线就是时灵时不灵,换了短粗线才稳定。提醒一句,模块千万别接5V,我朋友烧过一块,在线的兄弟们引脚核对三遍再上电。

第三次终于亮了
2楼 · 3小时前

SDA其实是SPI片选这个点讲得好,第一次接的时候我也懵了半天。

探头看一眼
3楼 · 3小时前

门禁这块能不能再加个继电器开锁的续篇?想抄作业。