RFID-MFRC522射频识别S50白卡

硬件介绍

RFID

无线射频识别即射频识别技术(Radio Frequency Identification,RFID),是自动识别技术的一种,通过无线射频方式进行非接触双向数据通信,利用无线射频方式对记录媒体(电子标签或射频卡)进行读写,从而达到识别目标和数据交换的目的。

MFRC522

MFRC522是高度集成的非接触式读写卡芯片,是一款低电压、低成本、体积小的非接触式读写卡芯片,是智能仪表和便携式手持设备研发的较好选择。

S50卡

S50卡是采用NXP MF1 IC S50制作的非接触智能卡,通常简称S50卡或Mifare 1K,符合ISO14443A标准,4或7字节UID。具有1K数据存储区,数据有密钥保护。

一、主要指标:

· 容量为 8K 位 EEPROM
· 分为 16 个扇区,每个扇区为 4 块,每块 16 个字节,以块为存取单位
· 每个扇区有独立的一组密码及访问控制
· 每张卡有唯一序列号,为 32 位
· 具有防冲突机制,支持多卡操作
· 无电源,自带天线,内含加密控制逻辑和通讯逻辑电路
· 数据保存期为 10 年,可改写 10 万次,读无限次
· 工作温度: -20℃ ~50℃ (湿度为 90%)
· 工作频率: 13.56MHZ
· 通信速率: 106 KBPS
· 读写距离: 10 cm 以内(与读写器有关)

二、存储结构

具体了解S50卡的相关信息请查看相关的中文说明书,链接放下方了。

点击下载——提取码:6666

系统设计(一个刷卡门禁系统)

设计要求

(1)在S50白卡的第15扇区第2块写入系统特征码,前三字节AAH BBH CCH + 其他(任意,各组不同);异形卡不做任何设置。

(2)当刷本组的白卡时,液晶屏显示欢迎词,否则(异形卡或者他组白卡)液晶屏显示拒绝信息,并闪烁LED灯3次以示报警。

(3)在液晶屏上显示当日(开机或重启后)刷卡总次数。

Fritzing图

线路连接

RC522

RC522 NodeMcu
SDA D2(GPIO4)
SCK D5(GPIO14)
MOSI D7(GPIO13)
MISO D6(GPIO12)
IRQ
GND GND
RST D1(GPIO5)
3.3V 3.3V

SSD1306

SSD1306 NodeMcu
GND GND
VCC 3.3V
D0 D5(DPIO14)
D1 D7(GPIO13)
RES D8(GPIO15)
DC D4(GPIO2)
CS D10(GPIO1)

代码设计

1.特征码写入

#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN        5           // 配置针脚
#define SS_PIN         4
MFRC522 mfrc522(SS_PIN, RST_PIN);   // 创建新的RFID实例
MFRC522::MIFARE_Key key; //6字节的密码
void dump_byte_array(byte *buffer, byte bufferSize); //声明dump_byte_array函数
void setup() {Serial.begin(9600); // 设置串口波特率为9600while (!Serial);    // 如果串口没有打开,则死循环下去不进行下面的操作SPI.begin();        // SPI开始mfrc522.PCD_Init(); // Init MFRC522 cardfor (byte i = 0; i < 6; i++) {//设置key为:FF FF FF FF FF FFkey.keyByte[i] = 0xFF;}Serial.println(F("扫描卡开始进行读或者写"));Serial.print(F("使用A和B作为键"));dump_byte_array(key.keyByte, MFRC522::MF_KEY_SIZE);Serial.println();Serial.println(F("注意,会把数据写入到卡第15扇区"));
}void loop() {// 寻找新卡if ( ! mfrc522.PICC_IsNewCardPresent())return;// 选择一张卡if ( ! mfrc522.PICC_ReadCardSerial())return;// 显示卡片的详细信息Serial.print(F("卡片 UID:"));dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);Serial.println();Serial.print(F("卡片类型: "));MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);//获取卡片类型码Serial.println(mfrc522.PICC_GetTypeName(piccType));//转换类型码为类型名称// 检查兼容性,只有MIFARE类型的卡才能读写if (    piccType != MFRC522::PICC_TYPE_MIFARE_MINI&&  piccType != MFRC522::PICC_TYPE_MIFARE_1K&&  piccType != MFRC522::PICC_TYPE_MIFARE_4K) {Serial.println(F("仅仅适合Mifare Classic卡的读写"));return;}// 我们只使用第14个扇区byte sector         = 14;byte blockAddr      = 58;//第58个块为第14个扇区第2个数据块byte dataBlock[]    = {0xaa, 0xbb, 0xcc, 0x01, //  aa,bb,cc,10x00, 0x00, 0x00, 0x00, //  0,0,0,00x00, 0x00, 0x00, 0x00, // 0,0,0,00x00, 0x00, 0x00, 0x00  // 0,0,0,0};//写入的数据定义byte trailerBlock   = 59;//第59个块为第14个扇区的控制块MFRC522::StatusCode status;byte buffer[18];byte size = sizeof(buffer);// 原来的数据Serial.println(F("显示原本的数据..."));status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));//在uid为mfrc522.uid的卡的trailerBlock块(此块为扇区控制块)验证key是否与A密码相同if (status != MFRC522::STATUS_OK) {Serial.print(F("身份验证失败?或者是卡链接失败"));Serial.println(mfrc522.GetStatusCodeName(status));return;}// 显示整个扇区Serial.println(F("显示所有扇区的数据"));mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);//串行输出uid卡,第sector扇区的数据Serial.println();// 从块儿读取数据Serial.print(F("读取块儿的数据在:")); Serial.print(blockAddr);Serial.println(F("块 ..."));status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockAddr, buffer, &size);//读取size个第blockAddr块的数据到bufferif (status != MFRC522::STATUS_OK) {Serial.print(F("读卡失败,没有连接上 "));Serial.println(mfrc522.GetStatusCodeName(status));}//开始进行写入准备Serial.println(F("开始进行写入的准备..."));status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));//验证密码Bif (status != MFRC522::STATUS_OK) {Serial.print(F("写入失败,没有连接上或者没有权限 "));Serial.println(mfrc522.GetStatusCodeName(status));return;}// Write data to the blockSerial.print(F("在第: ")); Serial.print(blockAddr);Serial.println(F("  块中写入数据..."));dump_byte_array(dataBlock, 16); Serial.println();//显示要写入的数据status = (MFRC522::StatusCode) mfrc522.MIFARE_Write(blockAddr, dataBlock, 16);//写入数据if (status != MFRC522::STATUS_OK) {Serial.print(F("写入失败... "));Serial.println(mfrc522.GetStatusCodeName(status));}Serial.println();// 再次读取卡中数据,这次是写入之后的数据Serial.print(F("读取写入后第")); Serial.print(blockAddr);Serial.println(F(" 块的数据 ..."));status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockAddr, buffer, &size);if (status != MFRC522::STATUS_OK) {Serial.print(F("读取失败... "));Serial.println(mfrc522.GetStatusCodeName(status));}Serial.print(F("块 ")); Serial.print(blockAddr); Serial.println(F("数据为 :"));dump_byte_array(buffer, 16); Serial.println();// 验证一下数据,要保证写入前后数据是相等的// 通过计算块中的字节数量Serial.println(F("等待验证结果..."));byte count = 0;for (byte i = 0; i < 16; i++) {// 比较一下缓存中的数据(我们读出来的数据) = (我们刚刚写的数据)if (buffer[i] == dataBlock[i])count++;}Serial.print(F("匹配的字节数量 = ")); Serial.println(count);if (count == 16) {Serial.println(F("验证成功 :"));} else {Serial.println(F("失败,数据不匹配"));Serial.println(F("也许写入的内容不恰当"));}Serial.println();// 转储扇区数据Serial.println(F("写入后的数据内容为::"));mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);Serial.println();// 停止 PICCmfrc522.PICC_HaltA();//停止加密PCDmfrc522.PCD_StopCrypto1();
}/*** 将字节数组串行输出为16进制字符*/
void dump_byte_array(byte *buffer, byte bufferSize) {for (byte i = 0; i < bufferSize; i++) {Serial.print(buffer[i] < 0x10 ? " 0" : " ");Serial.print(buffer[i], HEX);}
}

2.实现门禁效果

#include <SPI.h>
#include <MFRC522.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64#define SS_PIN 4
#define RST_PIN 5//显示屏和LED灯定义
#define redLed 16
#define OLED_MOSI 13
#define OLED_CLK 14
#define OLED_DC 2
#define OLED_CS 1
#define OLED_RESET 15Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the classMFRC522::MIFARE_Key key; // Init array that will store new NUID
byte nuidPICC[4];
void dump_byte_array(byte *buffer, byte bufferSize); //声明dump_byte_array函数
byte cnt =0;void setup() { pinMode(redLed,OUTPUT);digitalWrite(redLed,LOW);Serial.begin(9600);display.begin(SSD1306_SWITCHCAPVCC);display.clearDisplay();display.setTextSize(1);               //字体大小display.setTextColor(WHITE);          //字体颜色display.setCursor(0,0);              //调整位置display.println(cnt);display.display();SPI.begin(); // Init SPI busrfid.PCD_Init(); // Init MFRC522 for (byte i = 0; i < 6; i++) {key.keyByte[i] = 0xFF;}Serial.println(F("This code scan the MIFARE Classsic NUID."));Serial.print(F("Using the following key:"));printHex(key.keyByte, MFRC522::MF_KEY_SIZE);
}void loop() {// 我们只使用第14个扇区byte sector         = 14;byte blockAddr      = 58;//第58个块为第14个扇区第2个数据块byte trailerBlock   = 59;//第59个块为第14个扇区的控制块MFRC522::StatusCode status;byte buffer[18];byte size = sizeof(buffer);// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.if ( ! rfid.PICC_IsNewCardPresent())return;// Verify if the NUID has been readedif ( ! rfid.PICC_ReadCardSerial())return;rfid.PICC_DumpMifareClassicSectorToSerial(&(rfid.uid), &key, sector);//串行输出uid卡,第sector扇区的数据Serial.print(F("读取写入后第:")); Serial.print(blockAddr);Serial.println(F("块的数据 ..."));status = (MFRC522::StatusCode) rfid.MIFARE_Read(blockAddr, buffer, &size);//读取size个第blockAddr块的数据到bufferif (status != MFRC522::STATUS_OK) {Serial.print(F("读卡失败,没有连接上 "));Serial.println(rfid.GetStatusCodeName(status));}Serial.print(F("该块: ")); Serial.print(blockAddr);Serial.println(F("数据为:"));dump_byte_array(buffer, 16); Serial.println();// Store NUID into nuidPICC arrayfor (byte i = 0; i < 4; i++) {nuidPICC[i] = rfid.uid.uidByte[i];}Serial.println(F("The NUID tag is:"));Serial.print(F("In hex: "));printHex(rfid.uid.uidByte, rfid.uid.size);Serial.println();Serial.print(F("In dec: "));printDec(rfid.uid.uidByte, rfid.uid.size);Serial.println();// Halt PICCrfid.PICC_HaltA();// Stop encryption on PCDrfid.PCD_StopCrypto1();
}/*** Helper routine to dump a byte array as hex values to Serial. */
void printHex(byte *buffer, byte bufferSize) {for (byte i = 0; i < bufferSize; i++) {Serial.print(buffer[i] < 0x10 ? " 0" : " ");Serial.print(buffer[i], HEX);}
}/*** Helper routine to dump a byte array as dec values to Serial.*/
void printDec(byte *buffer, byte bufferSize) {String s = "";for (byte i = 0; i < bufferSize; i++) {Serial.print(buffer[i] < 0x10 ? " 0" : " ");Serial.print(buffer[i], DEC);s += buffer[i];if(i == bufferSize-1){Serial.print(" CardID Str:  " + s);}}
}//验证卡
void dump_byte_array(byte *buffer, byte bufferSize) {byte buffer0[18] = { 0xaa, 0xbb, 0xcc };int count = 0;for(byte i =0 ;i<bufferSize ;i++) {if(i<3) {if(buffer[i] == buffer0[i]){count++;}}Serial.print(buffer[i] < 0x10 ? " 0" : " ");Serial.print(buffer[i], HEX);}Serial.println();if(count==3){Serial.println("成功");display.println("Welcome!");cnt=cnt+1;}else{Serial.println("验证失败");display.println("NO Permission!");digitalWrite(redLed,HIGH);delay(200);digitalWrite(redLed,LOW);delay(200);digitalWrite(redLed,HIGH);delay(200);digitalWrite(redLed,LOW);delay(200);digitalWrite(redLed,HIGH);delay(200);digitalWrite(redLed,LOW);delay(200);}Serial.print("成功次数:");Serial.println(cnt);display.display();delay(1000);
}

实验结果

1.修改特征码(AA BB CC 01)

2.读卡
不刷卡(显示成功的次数)

可通行(显示“Welcome!” cnt次数加一)

不可通行(显示“No permission!”;LED灯闪烁三下)

不刷卡(显示成功次数)

串口监视器(打印刷卡信息)

RFID-MFRC522射频识别S50白卡相关推荐

  1. IC卡探索记录- MFRC522+STM32F103C8 操作IC卡(M1卡) ---附代码

    目录 1 源码 2 操作对象是什么? 2.1 对象 2.1.1 使用硬件 2.1.1.1 RC522 2.1.1.2 主控 2.1.1.3 IC卡 2.1.2 电路 2.1.3 对象说明 2.1.3. ...

  2. Arduino 控制RFID读写器读写 IC卡

    Arduino 控制RFID读写器读写 IC卡 一.IC卡的认识   IC卡可以通过频段进行划分,低频(125KHz~134kHz,典型工作频率是12KHz).高频(13.56MHz)和超高频(860 ...

  3. RFID第一期——各种IC卡ID卡详解

    起因 放假闲来无事,在B站冲浪,看到有人在讨论IC卡,我在这方面刚好还是有这么一点了解,就拿MF1卡给别人举了个例子,然后MF1卡就被开除出IC卡籍了. 有点气,但是仔细想想,网上关于这些卡的介绍知识 ...

  4. S50 14443卡和15693卡 读写研究

    杂文 02C3A448  2D   0804008500AABBCCDDEEFF 17B5A448  4E   0804008500AABBCCDDEEFF A5AFA448  E6   080400 ...

  5. 各种手机测试卡,sim卡,藕合测试白卡,链接仪器的测试卡的介绍

    深圳市华海智能卡有限公司是专业从事各种PVC卡.IC卡.ID卡.SIM卡.智能电子标签卡等产品的生产.IC卡系统集成.RFID卡读卡机具制造.考勤系统的生产与销售等.通过全体员工的不懈努力,年生产能力 ...

  6. 树莓派复制MFRC522 门禁IC卡(支持block0写入,亲测可用)

    1. 基本原理 友情提示:本篇文章只用于学习交流使用,请不要用于其它用途 我们总共需要三个组件:树莓派,MFRC522模块,IC卡 树莓派与MFRC522模块的交互通过SPI方式:树莓派首先通过&qu ...

  7. 基于STM32F407+RFID的模拟公交车刷卡收费系统小项目

    BusChargeSystem 项目介绍 基于STM32F407+RFID的模拟公交车刷卡收费系统 开源仓库地址: github:https://github.com/DaXiongRen/BusCh ...

  8. RFID无线射频识别技术基本介绍

    RFID无线射频识别技术基本介绍: 无线射频识别技术(Radio Frequency Idenfication,RFID)是一种非接触的自动识别技术,其基本原理是利用射频信号和空间耦合(电感或电磁耦合 ...

  9. S50 Mifare卡块操作控制权限

    S50 M卡内存大小为1K,分为16个扇区,每个扇区4个块,每个块16个字节.第一个扇区的第0个块内容为制造厂商信息,第1,2个块为数据块,第3个块为控制块:其他扇区前三个块都为数据块,最后一个块为控 ...

最新文章

  1. Spring MVC基础知识整理➣国际化和异常处理
  2. Concurrent——Atomic原子操作类
  3. 六角填数---第五届蓝桥杯
  4. 【渝粤教育】电大中专电大中专职业健康与安全考试考核试题作业 题库
  5. 点游出行提供内地与香港游客高质量的旅程
  6. python读取音频文件_python 读取wav 音频文件的两种方式
  7. Javascript函数调用的四种方法
  8. abcde依次进入一个队列_数据结构与算法(6):队列
  9. 劝退与转行:没有什么是普适的
  10. excel与python生成正态分布的数据,实践
  11. 国美易卡MVCC读取,国美易卡DB_ROW_ID唯一值
  12. 简单介绍下微信群大全500人大群及免费微信互投群万人群
  13. 将示波器数据传入电脑用matlab作FFT
  14. 安卓电池校正_笔记本电池损耗55%后一波三折的挽救经历
  15. 安卓sdk过高,没法打开摄像头权限
  16. 微积分基础知识note
  17. 人行计算机面试真题,2018中国人民银行招聘面试真题(附答案)
  18. 用 vue-cli 手脚架 建立一个 webpack 模板 vue 项目
  19. Google Earth Engine(GEE)——在GEE上画出论文研究区图(彩色)
  20. 自动化控制编程软件(PLC/软PLC/Labviw/C#)特点

热门文章

  1. 秒表计时器怎么读_秒表使用说明书
  2. 免费开源解压缩软件7-Zip
  3. Linux使用uinput实现虚拟鼠标
  4. 唯品会狂飙突进的去向
  5. 产品设计指南:如何从零设计一款手机端产品(APP)?
  6. 微信的红包算法 了解一下两种就可以了
  7. 你的简历能帮你争取到面试机会吗
  8. 机器学习数据集!CV、NLP 一应俱全
  9. 商米机V2和V1内置打印机说明
  10. 2021届硕士生年初java春招实习面试和正式校招面试经验汇总(收割腾讯,百度,美团,网易等offer)