找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6127|回复: 0
打印 上一主题 下一主题
收起左侧

RC522适用库arduino

[复制链接]
跳转到指定楼层
楼主
RC522适用,本人在arduino1.05上已测。包含rfid.h rfid.cpp,还有两个例子。


源程序如下:
  1. /*
  2. * RFID.cpp - Library to use ARDUINO RFID MODULE KIT 13.56 MHZ WITH TAGS SPI W AND R BY COOQROBOT.
  3. * Based on code Dr.Leong
  4. * Created by Miguel Balboa, Jan, 2012.
  5. * Released into the public domain.
  6. * TIDY BY YFRobot
  7. */

  8. /******************************************************************************
  9. * 包含文件
  10. ******************************************************************************/
  11. #include <Arduino.h>
  12. #include <RFID.h>

  13. /******************************************************************************
  14. * 构造 RFID
  15. * int chipSelectPin RFID /ENABLE pin
  16. ******************************************************************************/
  17. RFID::RFID(int chipSelectPin, int NRSTPD)
  18. {
  19.   _chipSelectPin = chipSelectPin;
  20.   _NRSTPD = NRSTPD;

  21.   pinMode(_chipSelectPin,OUTPUT);     // 设置管脚_chipSelectPin为输出并连接到模块使能口
  22.   digitalWrite(_chipSelectPin, LOW);


  23.   pinMode(_NRSTPD,OUTPUT);            // 设置管脚NRSTPD为输出,非重置或掉电
  24.   digitalWrite(_NRSTPD, HIGH);
  25. }

  26. /******************************************************************************
  27. * 用户 API
  28. ******************************************************************************/

  29. /******************************************************************************
  30. * 函 数 名:init
  31. * 功能描述:初始化RC522
  32. * 输入参数:无
  33. * 返 回 值:无
  34. ******************************************************************************/
  35. void RFID::init()
  36. {
  37.   digitalWrite(_NRSTPD,HIGH);

  38.   reset();

  39.   //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
  40.   writeMFRC522(TModeReg, 0x8D);   //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
  41.   writeMFRC522(TPrescalerReg, 0x3E);  //TModeReg[3..0] + TPrescalerReg
  42.   writeMFRC522(TReloadRegL, 30);
  43.   writeMFRC522(TReloadRegH, 0);
  44.   writeMFRC522(TxAutoReg, 0x40);    //100%ASK
  45.   writeMFRC522(ModeReg, 0x3D);    // CRC valor inicial de 0x6363

  46.   //ClearBitMask(Status2Reg, 0x08); //MFCrypto1On=0
  47.   //writeMFRC522(RxSelReg, 0x86);   //RxWait = RxSelReg[5..0]
  48.   //writeMFRC522(RFCfgReg, 0x7F);     //RxGain = 48dB

  49.   antennaOn();    //打开天线
  50. }

  51. /******************************************************************************
  52. * 函 数 名:reset
  53. * 功能描述:复位RC522
  54. * 输入参数:无
  55. * 返 回 值:无
  56. ******************************************************************************/
  57. void RFID::reset()
  58. {
  59.   writeMFRC522(CommandReg, PCD_RESETPHASE);
  60. }

  61. /******************************************************************************
  62. * 函 数 名:writeMFRC522
  63. * 功能描述:向MFRC522的某一寄存器写一个字节数据
  64. * 输入参数:addr--寄存器地址;val--要写入的值
  65. * 返 回 值:无
  66. ******************************************************************************/
  67. void RFID::writeMFRC522(unsigned char addr, unsigned char val)
  68. {
  69.   digitalWrite(_chipSelectPin, LOW);

  70.   //地址格式:0XXXXXX0
  71.   SPI.transfer((addr<<1)&0x7E);
  72.   SPI.transfer(val);

  73.   digitalWrite(_chipSelectPin, HIGH);
  74. }

  75. /******************************************************************************
  76. * 函 数 名:readMFRC522
  77. * 功能描述:从MFRC522的某一寄存器读一个字节数据
  78. * 输入参数:addr--寄存器地址
  79. * 返 回 值:返回读取到的一个字节数据
  80. ******************************************************************************/
  81. unsigned char RFID::readMFRC522(unsigned char addr)
  82. {
  83.   unsigned char val;
  84.   digitalWrite(_chipSelectPin, LOW);
  85.   SPI.transfer(((addr<<1)&0x7E) | 0x80);
  86.   val =SPI.transfer(0x00);
  87.   digitalWrite(_chipSelectPin, HIGH);
  88.   return val;
  89. }

  90. /******************************************************************************
  91. * 函 数 名:setBitMask
  92. * 功能描述:置RC522寄存器位
  93. * 输入参数:reg--寄存器地址;mask--置位值
  94. * 返 回 值:无
  95. ******************************************************************************/
  96. void RFID::setBitMask(unsigned char reg, unsigned char mask)
  97. {
  98.   unsigned char tmp;
  99.   tmp = readMFRC522(reg);
  100.   writeMFRC522(reg, tmp | mask);  // set bit mask
  101. }

  102. /******************************************************************************
  103. * 函 数 名:clearBitMask
  104. * 功能描述:清RC522寄存器位
  105. * 输入参数:reg--寄存器地址;mask--清位值
  106. * 返 回 值:无
  107. ******************************************************************************/
  108. void RFID::clearBitMask(unsigned char reg, unsigned char mask)
  109. {
  110.   unsigned char tmp;
  111.   tmp = readMFRC522(reg);
  112.   writeMFRC522(reg, tmp & (~mask));  // clear bit mask
  113. }

  114. /******************************************************************************
  115. * 函 数 名:antennaOn
  116. * 功能描述:开启天线,每次启动或关闭天险发射之间应至少有1ms的间隔
  117. * 输入参数:无
  118. * 返 回 值:无
  119. ******************************************************************************/
  120. void RFID::antennaOn(void)
  121. {
  122.   unsigned char temp;

  123.   temp = readMFRC522(TxControlReg);
  124.   if (!(temp & 0x03))
  125.   {
  126.     setBitMask(TxControlReg, 0x03);
  127.   }
  128. }

  129. /******************************************************************************
  130. * 函 数 名:antennaOff
  131. * 功能描述:关闭天线,每次启动或关闭天险发射之间应至少有1ms的间隔
  132. * 输入参数:无
  133. * 返 回 值:无
  134. ******************************************************************************/
  135. void RFID::antennaOff(void)
  136. {
  137.   unsigned char temp;

  138.   temp = readMFRC522(TxControlReg);
  139.   if (!(temp & 0x03))
  140.   {
  141.     clearBitMask(TxControlReg, 0x03);
  142.   }
  143. }

  144. /******************************************************************************
  145. * 函 数 名:calculateCRC
  146. * 功能描述:用MF522计算CRC
  147. * 输入参数:pIndata--要读数CRC的数据,len--数据长度,pOutData--计算的CRC结果
  148. * 返 回 值:无
  149. ******************************************************************************/
  150. void RFID::calculateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData)
  151. {
  152.   unsigned char i, n;

  153.   clearBitMask(DivIrqReg, 0x04);      //CRCIrq = 0
  154.   setBitMask(FIFOLevelReg, 0x80);     //清FIFO指针
  155.   //Write_MFRC522(CommandReg, PCD_IDLE);

  156.   //向FIFO中写入数据
  157.   for (i=0; i<len; i++)
  158.     writeMFRC522(FIFODataReg, *(pIndata+i));
  159.   writeMFRC522(CommandReg, PCD_CALCCRC);

  160.   //等待CRC计算完成
  161.   i = 0xFF;
  162.   do
  163.   {
  164.     n = readMFRC522(DivIrqReg);
  165.     i--;
  166.   }
  167.   while ((i!=0) && !(n&0x04));      //CRCIrq = 1

  168.   //读取CRC计算结果
  169.   pOutData[0] = readMFRC522(CRCResultRegL);
  170.   pOutData[1] = readMFRC522(CRCResultRegM);
  171. }

  172. /******************************************************************************
  173. * 函 数 名:MFRC522ToCard
  174. * 功能描述:RC522和ISO14443卡通讯
  175. * 输入参数:command--MF522命令字,
  176. *           sendData--通过RC522发送到卡片的数据,
  177. *                     sendLen--发送的数据长度
  178. *                     backData--接收到的卡片返回数据,
  179. *                     backLen--返回数据的位长度
  180. * 返 回 值:成功返回MI_OK
  181. ******************************************************************************/
  182. unsigned char RFID::MFRC522ToCard(unsigned char command, unsigned char *sendData, unsigned char sendLen, unsigned char *backData, unsigned int *backLen)
  183. {
  184.   unsigned char status = MI_ERR;
  185.   unsigned char irqEn = 0x00;
  186.   unsigned char waitIRq = 0x00;
  187.   unsigned char lastBits;
  188.   unsigned char n;
  189.   unsigned int i;

  190.   switch (command)
  191.   {
  192.     case PCD_AUTHENT:   //认证卡密
  193.     {
  194.       irqEn = 0x12;
  195.       waitIRq = 0x10;
  196.       break;
  197.     }
  198.     case PCD_TRANSCEIVE:  //发送FIFO中数据
  199.     {
  200.       irqEn = 0x77;
  201.       waitIRq = 0x30;
  202.       break;
  203.     }
  204.     default:
  205.       break;
  206.   }

  207.   writeMFRC522(CommIEnReg, irqEn|0x80); //允许中断请求
  208.   clearBitMask(CommIrqReg, 0x80);       //清除所有中断请求位
  209.   setBitMask(FIFOLevelReg, 0x80);       //FlushBuffer=1, FIFO初始化

  210.   writeMFRC522(CommandReg, PCD_IDLE);   //无动作,取消当前命令

  211.   //向FIFO中写入数据
  212.   for (i=0; i<sendLen; i++)
  213.     writeMFRC522(FIFODataReg, sendData[i]);

  214.   //执行命令
  215.   writeMFRC522(CommandReg, command);
  216.   if (command == PCD_TRANSCEIVE)
  217.     setBitMask(BitFramingReg, 0x80);    //StartSend=1,transmission of data starts

  218.   //等待接收数据完成
  219.   i = 2000; //i根据时钟频率调整,操作M1卡最大等待时间25ms
  220.   do
  221.   {
  222.     //CommIrqReg[7..0]
  223.     //Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
  224.     n = readMFRC522(CommIrqReg);
  225.     i--;
  226.   }
  227.   while ((i!=0) && !(n&0x01) && !(n&waitIRq));

  228.   clearBitMask(BitFramingReg, 0x80);      //StartSend=0

  229.   if (i != 0)
  230.   {
  231.     if(!(readMFRC522(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
  232.     {
  233.       status = MI_OK;
  234.       if (n & irqEn & 0x01)
  235.         status = MI_NOTAGERR;     //??

  236.       if (command == PCD_TRANSCEIVE)
  237.       {
  238.         n = readMFRC522(FIFOLevelReg);
  239.         lastBits = readMFRC522(ControlReg) & 0x07;
  240.         if (lastBits)
  241.           *backLen = (n-1)*8 + lastBits;
  242.         else
  243.           *backLen = n*8;

  244.         if (n == 0)
  245.           n = 1;
  246.         if (n > MAX_LEN)
  247.           n = MAX_LEN;

  248.         //读取FIFO中接收到的数据
  249.         for (i=0; i<n; i++)
  250.           backData[i] = readMFRC522(FIFODataReg);
  251.       }
  252.     }
  253.     else
  254.       status = MI_ERR;
  255.   }

  256.   //SetBitMask(ControlReg,0x80);           //timer stops
  257.   //Write_MFRC522(CommandReg, PCD_IDLE);

  258.   return status;
  259. }


  260. /******************************************************************************
  261. * 函 数 名:findCard
  262. * 功能描述:寻卡,读取卡类型号
  263. * 输入参数:reqMode--寻卡方式,
  264. *           TagType--返回卡片类型
  265. *                    0x4400 = Mifare_UltraLight
  266. *                    0x0400 = Mifare_One(S50)
  267. *                    0x0200 = Mifare_One(S70)
  268. *                    0x0800 = Mifare_Pro(X)
  269. *                    0x4403 = Mifare_DESFire
  270. * 返 回 值:成功返回MI_OK
  271. ******************************************************************************/
  272. unsigned char RFID::findCard(unsigned char reqMode, unsigned char *TagType)
  273. {
  274.   unsigned char status;
  275.   unsigned int backBits;      //接收到的数据位数

  276.   writeMFRC522(BitFramingReg, 0x07);    //TxLastBists = BitFramingReg[2..0] ???

  277.   TagType[0] = reqMode;
  278.   status = MFRC522ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);

  279.   if ((status != MI_OK) || (backBits != 0x10))
  280.     status = MI_ERR;

  281.   return status;
  282. }

  283. /******************************************************************************
  284. * 函 数 名:anticoll
  285. * 功能描述:防冲突检测,读取选中卡片的卡序列号
  286. * 输入参数:serNum--返回4字节卡序列号,第5字节为校验字节
  287. * 返 回 值:成功返回MI_OK
  288. ******************************************************************************/
  289. unsigned char RFID::anticoll(unsigned char *serNum)
  290. {
  291.   unsigned char status;
  292.   unsigned char i;
  293.   unsigned char serNumCheck=0;
  294.   unsigned int unLen;

  295.   clearBitMask(Status2Reg, 0x08);   //TempSensclear
  296.   clearBitMask(CollReg,0x80);     //ValuesAfterColl
  297.   writeMFRC522(BitFramingReg, 0x00);    //TxLastBists = BitFramingReg[2..0]

  298.   serNum[0] = PICC_ANTICOLL;
  299.   serNum[1] = 0x20;

  300.   status = MFRC522ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);

  301.   if (status == MI_OK)
  302.   {
  303.     //校验卡序列号
  304.         for (i=0; i<4; i++){
  305.           *(serNum+i)  = serNum[i];
  306.       serNumCheck ^= serNum[i];
  307.         }
  308.     if (serNumCheck != serNum[i]){
  309.       status = MI_ERR;
  310.         }
  311.   }

  312.   setBitMask(CollReg, 0x80);    //ValuesAfterColl=1

  313.   return status;
  314. }

  315. /******************************************************************************
  316. * 函 数 名:auth
  317. * 功能描述:验证卡片密码
  318. * 输入参数:authMode--密码验证模式
  319. *                     0x60 = 验证A密钥
  320. *                     0x61 = 验证B密钥
  321. *           BlockAddr--块地址
  322. *           Sectorkey--扇区密码
  323. *           serNum--卡片序列号,4字节
  324. * 返 回 值:成功返回MI_OK
  325. ******************************************************************************/
  326. unsigned char RFID::auth(unsigned char authMode, unsigned char BlockAddr, unsigned char *Sectorkey, unsigned char *serNum)
  327. {
  328.   unsigned char status;
  329.   unsigned int recvBits;
  330.   unsigned char i;
  331.   unsigned char buff[12];

  332.   //验证指令+块地址+扇区密码+卡序列号
  333.   buff[0] = authMode;
  334.   buff[1] = BlockAddr;
  335.   for (i=0; i<6; i++)
  336.     buff[i+2] = *(Sectorkey+i);
  337.   for (i=0; i<4; i++)
  338.     buff[i+8] = *(serNum+i);
  339.    
  340.   status = MFRC522ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);
  341.   if ((status != MI_OK) || (!(readMFRC522(Status2Reg) & 0x08)))
  342.     status = MI_ERR;

  343.   return status;
  344. }

  345. /******************************************************************************
  346. * 函 数 名:read
  347. * 功能描述:读块数据
  348. * 输入参数:blockAddr--块地址;recvData--读出的块数据
  349. * 返 回 值:成功返回MI_OK
  350. ******************************************************************************/
  351. unsigned char RFID::read(unsigned char blockAddr, unsigned char *recvData)
  352. {
  353.   unsigned char status;
  354.   unsigned int unLen;

  355.   recvData[0] = PICC_READ;
  356.   recvData[1] = blockAddr;
  357.   calculateCRC(recvData,2, &recvData[2]);
  358.   status = MFRC522ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen);

  359.   if ((status != MI_OK) || (unLen != 0x90))
  360.     status = MI_ERR;

  361.   return status;
  362. }

  363. /******************************************************************************
  364. * 函 数 名:write
  365. * 功能描述:写块数据
  366. * 输入参数:blockAddr--块地址;writeData--向块写16字节数据
  367. * 返 回 值:成功返回MI_OK
  368. ******************************************************************************/
  369. unsigned char RFID::write(unsigned char blockAddr, unsigned char *writeData)
  370. {
  371.   unsigned char status;
  372.   unsigned int recvBits;
  373.   unsigned char i;
  374.   unsigned char buff[18];

  375.   buff[0] = PICC_WRITE;
  376.   buff[1] = blockAddr;
  377.   calculateCRC(buff, 2, &buff[2]);
  378.   status = MFRC522ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);

  379.   if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
  380.     status = MI_ERR;

  381.   if (status == MI_OK)
  382.   {
  383.     for (i=0; i<16; i++)    //?FIFO?16Byte?? Datos a la FIFO 16Byte escribir
  384.       buff[i] = *(writeData+i);
  385.       
  386.     calculateCRC(buff, 16, &buff[16]);
  387.     status = MFRC522ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);

  388.     if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
  389.       status = MI_ERR;
  390.   }

  391.   return status;
  392. }

  393. /******************************************************************************
  394. * 函 数 名:selectTag
  395. * 功能描述:选卡,读取卡存储器容量
  396. * 输入参数:serNum--传入卡序列号
  397. * 返 回 值:成功返回卡容量
  398. ******************************************************************************/
  399. unsigned char RFID::selectTag(unsigned char *serNum)
  400. {
  401.   unsigned char i;
  402.   unsigned char status;
  403.   unsigned char size;
  404.   unsigned int recvBits;
  405.   unsigned char buffer[9];

  406.   //ClearBitMask(Status2Reg, 0x08);                        //MFCrypto1On=0

  407.   buffer[0] = PICC_SElECTTAG;
  408.   buffer[1] = 0x70;

  409.   for (i=0; i<5; i++)
  410.     buffer[i+2] = *(serNum+i);

  411.   calculateCRC(buffer, 7, &buffer[7]);
  412.   
  413.   status = MFRC522ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);
  414.   if ((status == MI_OK) && (recvBits == 0x18))
  415.     size = buffer[i];
  416.   else
  417.     size = 0;
  418.   return size;
  419. }

  420. /******************************************************************************
  421. * 函 数 名:Halt
  422. * 功能描述:命令卡片进入休眠状态
  423. * 输入参数:无
  424. * 返 回 值:无
  425. ******************************************************************************/
  426. void RFID::halt()
  427. {
  428.   unsigned char status;
  429.   unsigned int unLen;
  430.   unsigned char buff[4];

  431.   buff[0] = PICC_HALT;
  432.   buff[1] = 0;
  433.   calculateCRC(buff, 2, &buff[2]);

  434.   status = MFRC522ToCard(PCD_TRANSCEIVE, buff, 4, buff,&unLen);
  435. }
复制代码

所有资料51hei提供下载:
RFID.zip (8.97 KB, 下载次数: 86)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表