RC522模块不但可以读取标签中的数据,还能将数据写入标签中,本篇介绍S50卡的写卡操作。

1. S50卡介绍

S50非接触式IC卡的容量为1K字节EEPROM,又称M1卡。内部EEPROM又分为16个扇区,每个扇区分4个块,以块为存取单位,每个块由16个字节组成。

1. M1卡主要指标:

  • 每个扇区有独立的一组密码和访问控制。
  • 每张卡有唯一32位序列号。
  • 无电源,自带天线,内含加密控制逻辑和通讯逻辑电路。
  • 数据保存期为10年,可改写10万次,读无限次
  • 工作频率:13.56MHZ
  • 通信速率:106 KBPS
  • 工作温度:-20℃~50℃(湿度为90%)

2. M1卡存储结构

存储结构如下图,16个扇区,每个扇区4个块,可将16个扇区的64个块按绝对地址编号0-63。

其中第0扇区的块0,用于存放厂商代码,一般前四字节为UID,已经固化,一般不可更改。

每个扇区的块0、块1、块2为数据块,可用于存储数据,块3为控制块,包括了密码A,存取控制,密码B。

3. 读写流程

每个扇区的密码和存取控制都是独立的,可根据实际需要设定各自的密码及存取控制。出厂默认的密码6个字节都为0xFF。

扇区中每个块的存取条件是由密码和存取控制共同决定的,每个块有相应的三个控制位,按照一定规则进行约束,具体可以参照M1卡数据手册。

本篇演示向扇区1的块0,绝对地址为块4中写入数据。主要流程为:模块进行卡扫描读取卡片信息,通过密码进行身份认证,然后读取写入前的块数据,然后再次进行身份认证并写入自定义数据,然后再次身份认证读取写入后的块数据来检测是否写入成功。

2. 实验材料

  • Uno R3开发板
  • 配套USB数据线
  • 面包板及配套连接线
  • RFID-RC522模块及配套S50白卡和异形卡

3. 实验步骤

1. 根据原理图搭建电路图。

RC522模块的3.3V、GND分别对应连接开发板的3.3V、GND,模块的MOSI、MISO、SCK分别连接开发板的SPI接口11、12、13,模块的SDA、RST分别连接开发板数字管脚10、9。

实验原理图如下图所示:

实物连接图如下图所示:

2. 新建sketch,拷贝如下代码替换自动生成的代码并进行保存。

#include <SPI.h>
#include <MFRC522.h>#define RST_PIN         9
#define SS_PIN          10MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;void setup() {Serial.begin(9600);while (!Serial);    // 等待串口打开SPI.begin();mfrc522.PCD_Init();// 出厂默认使用FF FF FF FF FF FF作为密码A和Bfor (byte i = 0; i < 6; i++) {key.keyByte[i] = 0xFF;}Serial.println(F("开始扫描卡进行读写..."));Serial.print(F("使用密码:"));dump_byte_array(key.keyByte, MFRC522::MF_KEY_SIZE);Serial.println();Serial.println(F("数据将被写入到#1扇区"));
}void loop() {//寻找新卡if ( ! mfrc522.PICC_IsNewCardPresent())return;//验证UID是否可读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("不支持读取此卡类型"));return;}// 操作扇区1// 扇区1包括:块4~块7byte sector         = 1;byte blockAddr      = 4;byte dataBlock[]    = {0x01, 0x02, 0x03, 0x04,0x05, 0x06, 0x07, 0x08,0x09, 0x0A, 0x0B, 0x0C,0x0D, 0x0E, 0x0F, 0x10};//要写入的数据byte trailerBlock   = 7;MFRC522::StatusCode status;byte buffer[18];byte size = sizeof(buffer);// 使用密码A进行身份认证Serial.println(F("使用密码A进行身份认证..."));status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));if (status != MFRC522::STATUS_OK) {Serial.print(F("身份认证失败 "));Serial.println(mfrc522.GetStatusCodeName(status));return;}// 显示当前扇区数据Serial.println(F("当前扇区数据:"));mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);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();// 使用密码B进行身份认证Serial.println(F("使用密码B进行身份认证..."));status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));if (status != MFRC522::STATUS_OK) {Serial.print(F("身份认证失败 "));Serial.println(mfrc522.GetStatusCodeName(status));return;}//写入数据Serial.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("当前扇区数据:"));mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);Serial.println();//使放置在读卡区的IC卡进入休眠状态,不再重复读卡mfrc522.PICC_HaltA();// 停止读卡模块编码mfrc522.PCD_StopCrypto1();
}// 十六进制输出
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);}
}

3. 连接开发板,设置好对应端口号和开发板类型,进行程序下载。

4. 实验现象

打开串口监视器,波特率设置成与程序中相一致的9600。将卡靠近模块,根据打印信息可看到数据被写入到指定块中。


关注公众号「TonyCode」,更多精彩内容分享。
回复「1024」获取1000G学习资料。
个人博客

Arduino提高篇20—S50卡数据读写相关推荐

  1. Arduino提高篇24—摇杆调节时钟时间

    对于电子时钟而言,虽然我们可以在程序中对RTC芯片写入初始时间数据,但按键调时功能也是必不可少的,它可以让我们更加灵活的进行时间调节校准.本篇我们使用摇杆按键来调节时间数据,采用多级菜单的思路进行设计 ...

  2. Arduino 提高篇 1 —— 电子时钟

    一.实验器材 Arduino Uno R3开发板及扩展板 公对母.母对母杜邦线若干 面包板 0.96英寸 OLED显示屏 DS1302模块 二.实验步骤 Arduino DS1302 3.3V VCC ...

  3. Arduino UNO AT24C32进行单字节数据读写(二)

    Arduino UNO AT24C32进行单字节数据读写(二) <Arduino UNO AT24C32进行单字节数据读写> 读取AT24C32的函数直接返回的是状态响应值,成功就返回0, ...

  4. Arduino提高篇11—烟雾传感器MQ-2

    MQ系列传感器是使用非常广泛的低成本传感器,广泛应用于家庭或工厂的气体泄漏监测装置.本篇介绍MQ家族中的MQ-2烟雾传感器的使用,其他MQ传感器使用都是相类似的. 1. MQ系列传感器工作原理 MQ系 ...

  5. Arduino提高篇21—RFID模块门禁设计

    RFID可应用于门禁系统,我们可以把数据写入标签,然后将有权限的标签进行记录保存,当有用户标签被扫描时,进行身份信息读取比对,然后根据权限进行相应的操作. 本篇配合OLED屏幕来模拟门禁系统,只对标签 ...

  6. Arduino提高篇22—实时时钟DS1302

    很多电子爱好者都热衷制作电子时钟来练手,这些时钟会使用数码管.点阵屏.LCD液晶屏.OLED屏.TFT屏等显示模块,所使用的RTC时钟芯片也各不相同,DS1302.DS3231.DS12C887等.通 ...

  7. Arduino提高篇23—OLED电子时钟

    在前篇文章中,我们通过库函数驱动DS1302获取到时间数据并且通过串口输出,而串口只是方便调试,要制作电子时钟,我们需要使用显示模块,本篇结合OLED对时间数据进行展示. 1. 实验材料 Uno R3 ...

  8. Arduino提高篇25—手势识别

    随着科技的发展,人机交互也发生了翻天覆地的变化,从最开始的手动控制,到后来的遥控,再到语音识别以及图像识别.一切都是为了解放人类,毕竟能吵吵就不会动手对不对,现在都懒得吵吵了,图像识别分析就好.本篇我 ...

  9. Arduino提高篇26—贪吃蛇游戏

    之前文章Processing笔记05-贪吃蛇小游戏分享过如何使用Processing来实现贪吃蛇游戏,很多小伙伴问可不可以来个Arduino版本的,那么本篇就通过Arduino,配合摇杆按键和OLED ...

最新文章

  1. Kotlin 与 Java 比较
  2. OpenCASCADE绘制测试线束:简单的向量代数和测量之测量命令
  3. 如何开发Web应用程序(非网站)
  4. 【深度学习】——利用pytorch搭建一个完整的深度学习项目(构建模型、加载数据集、参数配置、训练、模型保存、预测)
  5. 《软件需求分析(第二版)》第 16 章——需求链中的联系链 重点部分总结
  6. 初一音乐计算机教学方案,人音版七年级音乐教案
  7. 如何使用可控硅?(详细教程)
  8. scikit-klearn之 1.决策树
  9. 【机器学习】Andrew Ng——03线性代数知识回顾
  10. VB.NET 策略模式(下机用户类型选择)
  11. pycharm不能输入代码
  12. linux 二进制编辑工具,全网最全Linux的十大十进制编辑器,要接触Linux的你摆脱不了...
  13. 【Java基础知识 17】聊一聊同步代码块
  14. 国际知名芯片专家,加盟武昌理工学院人工智能学院
  15. 天津大学计算机学院王思宇,复杂计算精准化,天津大学选择了宝德HPC
  16. 曾经作为程序员的你为什么不当程序员了?现在在做什么?
  17. 冰桶挑战引来了百度搜索冰桶算法
  18. solidworks批量图号分离_SolidWorks2014基于宏实现快速图号名称分离.docx
  19. ABP微服务示例中ProductManagementHttpApiClient服务地址配置
  20. 苹果画画软件_iPad Pro绘画软件Procreate零基础教程

热门文章

  1. js实现禁止网页缩放(Ctrl+鼠标、+、-缩放有效亲测)
  2. 5分绩点转4分_5分制绩点计算器: 由于网上的绩点工具大多都是4分制的,而自己一门一门的计算绩点又非常麻烦,所以我就写了一个快速计算绩点的教程。...
  3. 蓝牙(Bluetooth)
  4. .net 日期格式化
  5. tyler cowen_Codenvy背后的技术。 首席执行官Tyler Jewell访谈
  6. 煤都也要迈向互联网 抚顺将打造东北亚一流的电商产业基地
  7. C++ accumulate()用法
  8. window系统:如何终止已占用的端口
  9. 开源视频剪辑—脑图软件
  10. 天猫精灵 python_树莓派通过snowboy唤醒引擎(Python2、Python3的都可以),自定义唤醒词、关键字,达到小爱同学、天猫精灵一样的唤醒方式的全套教程...