找回密码
 立即注册

QQ登录

只需一步,快速开始

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

MF RC-522 RC522程序

[复制链接]
跳转到指定楼层
楼主
ID:202591 发表于 2017-5-19 16:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. /*
  2. 读取卡号(ID),以及Block1的前8个字节的内容(Str),如两者都符合就触发继电器(Relay)。
  3. Block1的前8个字节的内容(Str),可以通过《RFID522_Serial_write_block.ino》写入。

  4. * 文 件 名:RFID522_READ_Comp_ID_Str_Relay.ino
  5. * 修 改 者:mc.six

  6. * 功能描述:Mifare1 寻卡→防冲突→选卡→读卡→触发继电器
  7. */

  8. // the sensor communicates using SPI, so include the library:
  9. #include <SPI.h>

  10. #define        uchar        unsigned char
  11. #define        uint        unsigned int

  12. //数组最大长度
  13. #define MAX_LEN 16

  14. /////////////////////////////////////////////////////////////////////
  15. //set the pin
  16. /////////////////////////////////////////////////////////////////////
  17. const int chipSelectPin = 10;//如果控制板为UNO,328,168
  18. //const int chipSelectPin = 53; //如果控制板为mega 2560,1280
  19. const int NRSTPD = 9;

  20. //MF522命令字
  21. #define PCD_IDLE              0x00               //NO action;取消当前命令
  22. #define PCD_AUTHENT           0x0E               //验证密钥
  23. #define PCD_RECEIVE           0x08               //接收数据
  24. #define PCD_TRANSMIT          0x04               //发送数据
  25. #define PCD_TRANSCEIVE        0x0C               //发送并接收数据
  26. #define PCD_RESETPHASE        0x0F               //复位
  27. #define PCD_CALCCRC           0x03               //CRC计算

  28. //Mifare_One卡片命令字
  29. #define PICC_REQIDL           0x26               //寻天线区内未进入休眠状态
  30. #define PICC_REQALL           0x52               //寻天线区内全部卡
  31. #define PICC_ANTICOLL         0x93               //防冲撞
  32. #define PICC_SElECTTAG        0x93               //选卡
  33. #define PICC_AUTHENT1A        0x60               //验证A密钥
  34. #define PICC_AUTHENT1B        0x61               //验证B密钥
  35. #define PICC_READ             0x30               //读块
  36. #define PICC_WRITE            0xA0               //写块
  37. #define PICC_DECREMENT        0xC0               
  38. #define PICC_INCREMENT        0xC1               
  39. #define PICC_RESTORE          0xC2               //调块数据到缓冲区
  40. #define PICC_TRANSFER         0xB0               //保存缓冲区中数据
  41. #define PICC_HALT             0x50               //休眠


  42. //和MF522通讯时返回的错误代码
  43. #define MI_OK                 0
  44. #define MI_NOTAGERR           1
  45. #define MI_ERR                2


  46. //------------------MFRC522寄存器---------------
  47. //Page 0:Command and Status
  48. #define     Reserved00            0x00   
  49. #define     CommandReg            0x01   
  50. #define     CommIEnReg            0x02   
  51. #define     DivlEnReg             0x03   
  52. #define     CommIrqReg            0x04   
  53. #define     DivIrqReg             0x05
  54. #define     ErrorReg              0x06   
  55. #define     Status1Reg            0x07   
  56. #define     Status2Reg            0x08   
  57. #define     FIFODataReg           0x09
  58. #define     FIFOLevelReg          0x0A
  59. #define     WaterLevelReg         0x0B
  60. #define     ControlReg            0x0C
  61. #define     BitFramingReg         0x0D
  62. #define     CollReg               0x0E
  63. #define     Reserved01            0x0F
  64. //Page 1:Command     
  65. #define     Reserved10            0x10
  66. #define     ModeReg               0x11
  67. #define     TxModeReg             0x12
  68. #define     RxModeReg             0x13
  69. #define     TxControlReg          0x14
  70. #define     TxAutoReg             0x15
  71. #define     TxSelReg              0x16
  72. #define     RxSelReg              0x17
  73. #define     RxThresholdReg        0x18
  74. #define     DemodReg              0x19
  75. #define     Reserved11            0x1A
  76. #define     Reserved12            0x1B
  77. #define     MifareReg             0x1C
  78. #define     Reserved13            0x1D
  79. #define     Reserved14            0x1E
  80. #define     SerialSpeedReg        0x1F
  81. //Page 2:CFG   
  82. #define     Reserved20            0x20  
  83. #define     CRCResultRegM         0x21
  84. #define     CRCResultRegL         0x22
  85. #define     Reserved21            0x23
  86. #define     ModWidthReg           0x24
  87. #define     Reserved22            0x25
  88. #define     RFCfgReg              0x26
  89. #define     GsNReg                0x27
  90. #define     CWGsPReg                  0x28
  91. #define     ModGsPReg             0x29
  92. #define     TModeReg              0x2A
  93. #define     TPrescalerReg         0x2B
  94. #define     TReloadRegH           0x2C
  95. #define     TReloadRegL           0x2D
  96. #define     TCounterValueRegH     0x2E
  97. #define     TCounterValueRegL     0x2F
  98. //Page 3:TestRegister     
  99. #define     Reserved30            0x30
  100. #define     TestSel1Reg           0x31
  101. #define     TestSel2Reg           0x32
  102. #define     TestPinEnReg          0x33
  103. #define     TestPinValueReg       0x34
  104. #define     TestBusReg            0x35
  105. #define     AutoTestReg           0x36
  106. #define     VersionReg            0x37
  107. #define     AnalogTestReg         0x38
  108. #define     TestDAC1Reg           0x39  
  109. #define     TestDAC2Reg           0x3A   
  110. #define     TestADCReg            0x3B   
  111. #define     Reserved31            0x3C   
  112. #define     Reserved32            0x3D   
  113. #define     Reserved33            0x3E   
  114. #define     Reserved34            0x3F
  115. //-----------------------------------------------
  116. #define Relay 2
  117. //4字节卡序列号,第5字节为校验字节
  118. uchar serNum[5];
  119. uchar  writeDate[16] ={'\0'};
  120. //扇区A密码,16个扇区,每个扇区密码6Byte
  121. uchar sectorKeyA[16][16] = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
  122.                              {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
  123.                              {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
  124.                             };
  125. uchar sectorNewKeyA[16][16] = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
  126.                                 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xff,0x07,0x80,0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
  127.                                 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xff,0x07,0x80,0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
  128.                                };

  129. void setup() {               
  130.    Serial.begin(9600);                       // RFID reader SOUT pin connected to Serial RX pin at 2400bps
  131. // start the SPI library:
  132.   SPI.begin();
  133.   
  134.   pinMode(chipSelectPin,OUTPUT);             // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin
  135.     digitalWrite(chipSelectPin, LOW);          // Activate the RFID reader
  136.   pinMode(NRSTPD,OUTPUT);               // Set digital pin 10 , Not Reset and Power-down
  137.     digitalWrite(NRSTPD, HIGH);

  138.   MFRC522_Init();  
  139. }

  140. void loop()
  141. {
  142.           uchar i,tmp;
  143.         uchar status;
  144.         uchar str[MAX_LEN];
  145.         uchar RC_size;
  146.         uchar blockAddr;        //选择操作的块地址0~63


  147.                 //寻卡,返回卡类型        
  148.                 status = MFRC522_Request(PICC_REQIDL, str);        
  149.                 if (status == MI_OK)
  150.                 {
  151.                 }

  152.                 //防冲撞,返回卡的序列号 4字节
  153.                 status = MFRC522_Anticoll(str);
  154.                 memcpy(serNum, str, 5);
  155.                 if (status == MI_OK)
  156.                 {
  157.                         Serial.println("The card's number is  : ");
  158.                         Serial.print(serNum[0],HEX);
  159.                         Serial.print(serNum[1],HEX);
  160.                         Serial.print(serNum[2],HEX);
  161.                         Serial.print(serNum[3],HEX);
  162.                         Serial.print(serNum[4],HEX);
  163.                         Serial.println(" ");
  164.                 }

  165.                 //选卡,返回卡容量
  166.                 RC_size = MFRC522_SelectTag(serNum);
  167.                 if (RC_size != 0)
  168.                 {}

  169.                 //读卡
  170.                 blockAddr = 7;                //数据块7               
  171.                 status = MFRC522_Auth(PICC_AUTHENT1A, blockAddr, sectorNewKeyA[blockAddr/4], serNum);        //认证
  172.                 if (status == MI_OK)
  173.                 {
  174.                         //读数据
  175.                         blockAddr = blockAddr - 3 ;
  176.                         status = MFRC522_Read(blockAddr, str);
  177.                         if (status == MI_OK)
  178.                         {
  179.                                 Serial.println("Read from the card ,the data is : ");
  180.                                 for (i=0; i<16; i++)
  181.                                 {
  182.                                  char aa=(char)str[i];         
  183.                                   Serial.print(aa);
  184.                                 }
  185.                                 Serial.println(" ");
  186.                         }
  187.                 }
  188.                // Serial.println(" ");
  189.                //////////////////////////////////////////////////// Check people associated with card ID
  190.             unsigned char* id = serNum;
  191.             if( id[0]==0xF1 && id[1]==0x9A && id[2]==0xD6 && id[3]==0x0E && str[0]=='a'&& str[1]=='u'&& str[2]=='g'&& str[3]=='u'&& str[4]=='s'&& str[5]=='t'&& str[6]=='0'&& str[7]=='1' ) //根据需要手动修改每个的内容
  192.             {

  193.    

  194.                 digitalWrite(Relay,HIGH);        //打开继电器
  195.                                 Serial.println("The Host 1!");
  196.             }
  197.             else if(id[0]==0xCD && id[1]==0x83 && id[2]==0xFE && id[3]==0xC9)  //根据需要手动修改每个的内容
  198.             {
  199.                 digitalWrite(Relay,LOW);        //继电器
  200.                                 Serial.println("The Host 2!");
  201.             }
  202.                         else
  203.                         {
  204.                                 Serial.println("Stranger!");
  205.                         }
  206. /////////////////////////////////////////////////////////////////////////////////////////////   
  207.                 MFRC522_Halt();                        //命令卡片进入休眠状态              
  208.          
  209. }

  210. /*
  211. * 函 数 名:Write_MFRC5200
  212. * 功能描述:向MFRC522的某一寄存器写一个字节数据
  213. * 输入参数:addr--寄存器地址;val--要写入的值
  214. * 返 回 值:无
  215. */
  216. void Write_MFRC522(uchar addr, uchar val)
  217. {
  218.         digitalWrite(chipSelectPin, LOW);

  219.         //地址格式:0XXXXXX0
  220.         SPI.transfer((addr<<1)&0x7E);        
  221.         SPI.transfer(val);
  222.         
  223.         digitalWrite(chipSelectPin, HIGH);
  224. }


  225. /*
  226. * 函 数 名:Read_MFRC522
  227. * 功能描述:从MFRC522的某一寄存器读一个字节数据
  228. * 输入参数:addr--寄存器地址
  229. * 返 回 值:返回读取到的一个字节数据
  230. */
  231. uchar Read_MFRC522(uchar addr)
  232. {
  233.         uchar val;

  234.         digitalWrite(chipSelectPin, LOW);

  235.         //地址格式:1XXXXXX0
  236.         SPI.transfer(((addr<<1)&0x7E) | 0x80);        
  237.         val =SPI.transfer(0x00);
  238.         
  239.         digitalWrite(chipSelectPin, HIGH);
  240.         
  241.         return val;        
  242. }

  243. /*
  244. * 函 数 名:SetBitMask
  245. * 功能描述:置RC522寄存器位
  246. * 输入参数:reg--寄存器地址;mask--置位值
  247. * 返 回 值:无
  248. */
  249. void SetBitMask(uchar reg, uchar mask)  
  250. {
  251.     uchar tmp;
  252.     tmp = Read_MFRC522(reg);
  253.     Write_MFRC522(reg, tmp | mask);  // set bit mask
  254. }


  255. /*
  256. * 函 数 名:ClearBitMask
  257. * 功能描述:清RC522寄存器位
  258. * 输入参数:reg--寄存器地址;mask--清位值
  259. * 返 回 值:无
  260. */
  261. void ClearBitMask(uchar reg, uchar mask)  
  262. {
  263.     uchar tmp;
  264.     tmp = Read_MFRC522(reg);
  265.     Write_MFRC522(reg, tmp & (~mask));  // clear bit mask
  266. }


  267. /*
  268. * 函 数 名:AntennaOn
  269. * 功能描述:开启天线,每次启动或关闭天险发射之间应至少有1ms的间隔
  270. * 输入参数:无
  271. * 返 回 值:无
  272. */
  273. void AntennaOn(void)
  274. {
  275.         uchar temp;

  276.         temp = Read_MFRC522(TxControlReg);
  277.         if (!(temp & 0x03))
  278.         {
  279.                 SetBitMask(TxControlReg, 0x03);
  280.         }
  281. }


  282. /*
  283. * 函 数 名:AntennaOff
  284. * 功能描述:关闭天线,每次启动或关闭天险发射之间应至少有1ms的间隔
  285. * 输入参数:无
  286. * 返 回 值:无
  287. */
  288. void AntennaOff(void)
  289. {
  290.         ClearBitMask(TxControlReg, 0x03);
  291. }


  292. /*
  293. * 函 数 名:ResetMFRC522
  294. * 功能描述:复位RC522
  295. * 输入参数:无
  296. * 返 回 值:无
  297. */
  298. void MFRC522_Reset(void)
  299. {
  300.     Write_MFRC522(CommandReg, PCD_RESETPHASE);
  301. }


  302. /*
  303. * 函 数 名:InitMFRC522
  304. * 功能描述:初始化RC522
  305. * 输入参数:无
  306. * 返 回 值:无
  307. */
  308. void MFRC522_Init(void)
  309. {
  310.         digitalWrite(NRSTPD,HIGH);

  311.         MFRC522_Reset();
  312.                  
  313.         //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
  314.     Write_MFRC522(TModeReg, 0x8D);                //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
  315.     Write_MFRC522(TPrescalerReg, 0x3E);        //TModeReg[3..0] + TPrescalerReg
  316.     Write_MFRC522(TReloadRegL, 30);           
  317.     Write_MFRC522(TReloadRegH, 0);
  318.         
  319.         Write_MFRC522(TxAutoReg, 0x40);                //100%ASK
  320.         Write_MFRC522(ModeReg, 0x3D);                //CRC初始值0x6363        ???

  321.         //ClearBitMask(Status2Reg, 0x08);                //MFCrypto1On=0
  322.         //Write_MFRC522(RxSelReg, 0x86);                //RxWait = RxSelReg[5..0]
  323.         //Write_MFRC522(RFCfgReg, 0x7F);                   //RxGain = 48dB

  324.         AntennaOn();                //打开天线
  325. }


  326. /*
  327. * 函 数 名:MFRC522_Request
  328. * 功能描述:寻卡,读取卡类型号
  329. * 输入参数:reqMode--寻卡方式,
  330. *                         TagType--返回卡片类型
  331. *                                 0x4400 = Mifare_UltraLight
  332. *                                0x0400 = Mifare_One(S50)
  333. *                                0x0200 = Mifare_One(S70)
  334. *                                0x0800 = Mifare_Pro(X)
  335. *                                0x4403 = Mifare_DESFire
  336. * 返 回 值:成功返回MI_OK
  337. */
  338. uchar MFRC522_Request(uchar reqMode, uchar *TagType)
  339. {
  340.         uchar status;  
  341.         uint backBits;                        //接收到的数据位数

  342.         Write_MFRC522(BitFramingReg, 0x07);                //TxLastBists = BitFramingReg[2..0]        ???
  343.         
  344.         TagType[0] = reqMode;
  345.         status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);

  346.         if ((status != MI_OK) || (backBits != 0x10))
  347.         {   
  348.                 status = MI_ERR;
  349.         }
  350.    
  351.         return status;
  352. }


  353. /*
  354. * 函 数 名:MFRC522_ToCard
  355. * 功能描述:RC522和ISO14443卡通讯
  356. * 输入参数:command--MF522命令字,
  357. *                         sendData--通过RC522发送到卡片的数据,
  358. *                         sendLen--发送的数据长度                 
  359. *                         backData--接收到的卡片返回数据,
  360. *                         backLen--返回数据的位长度
  361. * 返 回 值:成功返回MI_OK
  362. */
  363. uchar MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen)
  364. {
  365.     uchar status = MI_ERR;
  366.     uchar irqEn = 0x00;
  367.     uchar waitIRq = 0x00;
  368.     uchar lastBits;
  369.     uchar n;
  370.     uint i;

  371.     switch (command)
  372.     {
  373.         case PCD_AUTHENT:                //认证卡密
  374.                 {
  375.                         irqEn = 0x12;
  376.                         waitIRq = 0x10;
  377.                         break;
  378.                 }
  379.                 case PCD_TRANSCEIVE:        //发送FIFO中数据
  380.                 {
  381.                         irqEn = 0x77;
  382.                         waitIRq = 0x30;
  383.                         break;
  384.                 }
  385.                 default:
  386.                         break;
  387.     }
  388.    
  389.     Write_MFRC522(CommIEnReg, irqEn|0x80);        //允许中断请求
  390.     ClearBitMask(CommIrqReg, 0x80);                        //清除所有中断请求位
  391.     SetBitMask(FIFOLevelReg, 0x80);                        //FlushBuffer=1, FIFO初始化
  392.    
  393.         Write_MFRC522(CommandReg, PCD_IDLE);        //NO action;取消当前命令        ???

  394.         //向FIFO中写入数据
  395.     for (i=0; i<sendLen; i++)
  396.     {   
  397.                 Write_MFRC522(FIFODataReg, sendData[i]);   
  398.         }

  399.         //执行命令
  400.         Write_MFRC522(CommandReg, command);
  401.     if (command == PCD_TRANSCEIVE)
  402.     {   
  403.                 SetBitMask(BitFramingReg, 0x80);                //StartSend=1,transmission of data starts  
  404.         }   
  405.    
  406.         //等待接收数据完成
  407.         i = 2000;        //i根据时钟频率调整,操作M1卡最大等待时间25ms        ???
  408.     do
  409.     {
  410.                 //CommIrqReg[7..0]
  411.                 //Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
  412.         n = Read_MFRC522(CommIrqReg);
  413.         i--;
  414.     }
  415.     while ((i!=0) && !(n&0x01) && !(n&waitIRq));

  416.     ClearBitMask(BitFramingReg, 0x80);                        //StartSend=0
  417.         
  418.     if (i != 0)
  419.     {   
  420.         if(!(Read_MFRC522(ErrorReg) & 0x1B))        //BufferOvfl Collerr CRCErr ProtecolErr
  421.         {
  422.             status = MI_OK;
  423.             if (n & irqEn & 0x01)
  424.             {   
  425.                                 status = MI_NOTAGERR;                        //??   
  426.                         }

  427.             if (command == PCD_TRANSCEIVE)
  428.             {
  429.                        n = Read_MFRC522(FIFOLevelReg);
  430.                       lastBits = Read_MFRC522(ControlReg) & 0x07;
  431.                 if (lastBits)
  432.                 {   
  433.                                         *backLen = (n-1)*8 + lastBits;   
  434.                                 }
  435.                 else
  436.                 {   
  437.                                         *backLen = n*8;   
  438.                                 }

  439.                 if (n == 0)
  440.                 {   
  441.                                         n = 1;   
  442.                                 }
  443.                 if (n > MAX_LEN)
  444.                 {   
  445.                                         n = MAX_LEN;   
  446.                                 }
  447.                                 
  448.                                 //读取FIFO中接收到的数据
  449.                 for (i=0; i<n; i++)
  450.                 {   
  451.                                         backData[i] = Read_MFRC522(FIFODataReg);   
  452.                                 }
  453.             }
  454.         }
  455.         else
  456.         {   
  457.                         status = MI_ERR;  
  458.                 }
  459.         
  460.     }
  461.         
  462.     //SetBitMask(ControlReg,0x80);           //timer stops
  463.     //Write_MFRC522(CommandReg, PCD_IDLE);

  464.     return status;
  465. }


  466. /*
  467. * 函 数 名:MFRC522_Anticoll
  468. * 功能描述:防冲突检测,读取选中卡片的卡序列号
  469. * 输入参数:serNum--返回4字节卡序列号,第5字节为校验字节
  470. * 返 回 值:成功返回MI_OK
  471. */
  472. uchar MFRC522_Anticoll(uchar *serNum)
  473. {
  474.     uchar status;
  475.     uchar i;
  476.         uchar serNumCheck=0;
  477.     uint unLen;
  478.    

  479.     //ClearBitMask(Status2Reg, 0x08);                //TempSensclear
  480.     //ClearBitMask(CollReg,0x80);                        //ValuesAfterColl
  481.         Write_MFRC522(BitFramingReg, 0x00);                //TxLastBists = BitFramingReg[2..0]

  482.     serNum[0] = PICC_ANTICOLL;
  483.     serNum[1] = 0x20;
  484.     status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);

  485.     if (status == MI_OK)
  486.         {
  487.                 //校验卡序列号
  488.                 for (i=0; i<4; i++)
  489.                 {   
  490.                          serNumCheck ^= serNum[i];
  491.                 }
  492.                 if (serNumCheck != serNum[i])
  493.                 {   
  494.                         status = MI_ERR;   
  495.                 }
  496.     }

  497.     //SetBitMask(CollReg, 0x80);                //ValuesAfterColl=1

  498.     return status;
  499. }


  500. /*
  501. * 函 数 名:CalulateCRC
  502. * 功能描述:用MF522计算CRC
  503. * 输入参数:pIndata--要读数CRC的数据,len--数据长度,pOutData--计算的CRC结果
  504. * 返 回 值:无
  505. */
  506. void CalulateCRC(uchar *pIndata, uchar len, uchar *pOutData)
  507. {
  508.     uchar i, n;

  509.     ClearBitMask(DivIrqReg, 0x04);                        //CRCIrq = 0
  510.     SetBitMask(FIFOLevelReg, 0x80);                        //清FIFO指针
  511.     //Write_MFRC522(CommandReg, PCD_IDLE);

  512.         //向FIFO中写入数据        
  513.     for (i=0; i<len; i++)
  514.     {   
  515.                 Write_MFRC522(FIFODataReg, *(pIndata+i));   
  516.         }
  517.     Write_MFRC522(CommandReg, PCD_CALCCRC);

  518.         //等待CRC计算完成
  519.     i = 0xFF;
  520.     do
  521.     {
  522.         n = Read_MFRC522(DivIrqReg);
  523.         i--;
  524.     }
  525.     while ((i!=0) && !(n&0x04));                        //CRCIrq = 1

  526.         //读取CRC计算结果
  527.     pOutData[0] = Read_MFRC522(CRCResultRegL);
  528.     pOutData[1] = Read_MFRC522(CRCResultRegM);
  529. }


  530. /*
  531. * 函 数 名:MFRC522_SelectTag
  532. * 功能描述:选卡,读取卡存储器容量
  533. * 输入参数:serNum--传入卡序列号
  534. * 返 回 值:成功返回卡容量
  535. */
  536. uchar MFRC522_SelectTag(uchar *serNum)
  537. {
  538.     uchar i;
  539.         uchar status;
  540.         uchar size;
  541.     uint recvBits;
  542.     uchar buffer[9];

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

  544.     buffer[0] = PICC_SElECTTAG;
  545.     buffer[1] = 0x70;
  546.     for (i=0; i<5; i++)
  547.     {
  548.             buffer[i+2] = *(serNum+i);
  549.     }
  550.         CalulateCRC(buffer, 7, &buffer[7]);                //??
  551.     status = MFRC522_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);
  552.    
  553.     if ((status == MI_OK) && (recvBits == 0x18))
  554.     {   
  555.                 size = buffer[0];
  556.         }
  557.     else
  558.     {   
  559.                 size = 0;   
  560.         }

  561.     return size;
  562. }


  563. /*
  564. * 函 数 名:MFRC522_Auth
  565. * 功能描述:验证卡片密码
  566. * 输入参数:authMode--密码验证模式
  567.                  0x60 = 验证A密钥
  568.                  0x61 = 验证B密钥
  569.              BlockAddr--块地址
  570.              Sectorkey--扇区密码
  571.              serNum--卡片序列号,4字节
  572. * 返 回 值:成功返回MI_OK
  573. */
  574. uchar MFRC522_Auth(uchar authMode, uchar BlockAddr, uchar *Sectorkey, uchar *serNum)
  575. {
  576.     uchar status;
  577.     uint recvBits;
  578.     uchar i;
  579.         uchar buff[12];

  580.         //验证指令+块地址+扇区密码+卡序列号
  581.     buff[0] = authMode;
  582.     buff[1] = BlockAddr;
  583.     for (i=0; i<6; i++)
  584.     {   
  585.                 buff[i+2] = *(Sectorkey+i);   
  586.         }
  587.     for (i=0; i<4; i++)
  588.     {   
  589.                 buff[i+8] = *(serNum+i);   
  590.         }
  591.     status = MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);

  592.     if ((status != MI_OK) || (!(Read_MFRC522(Status2Reg) & 0x08)))
  593.     {   
  594.                 status = MI_ERR;   
  595.         }
  596.    
  597.     return status;
  598. }


  599. /*
  600. * 函 数 名:MFRC522_Read
  601. * 功能描述:读块数据
  602. * 输入参数:blockAddr--块地址;recvData--读出的块数据
  603. * 返 回 值:成功返回MI_OK
  604. */
  605. uchar MFRC522_Read(uchar blockAddr, uchar *recvData)
  606. {
  607.     uchar status;
  608.     uint unLen;

  609.     recvData[0] = PICC_READ;
  610.     recvData[1] = blockAddr;
  611.     CalulateCRC(recvData,2, &recvData[2]);
  612.     status = MFRC522_ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen);

  613.     if ((status != MI_OK) || (unLen != 0x90))
  614.     {
  615.         status = MI_ERR;
  616.     }
  617.    
  618.     return status;
  619. }


  620. /*
  621. * 函 数 名:MFRC522_Write
  622. * 功能描述:写块数据
  623. * 输入参数:blockAddr--块地址;writeData--向块写16字节数据
  624. * 返 回 值:成功返回MI_OK
  625. */
  626. uchar MFRC522_Write(uchar blockAddr, uchar *writeData)
  627. {
  628.     uchar status;
  629.     uint recvBits;
  630.     uchar i;
  631.         uchar buff[18];
  632.    
  633.     buff[0] = PICC_WRITE;
  634.     buff[1] = blockAddr;
  635.     CalulateCRC(buff, 2, &buff[2]);
  636.     status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);

  637.     if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
  638.     {   
  639.                 status = MI_ERR;   
  640.         }
  641.         
  642.     if (status == MI_OK)
  643.     {
  644.         for (i=0; i<16; i++)                //向FIFO写16Byte数据
  645.         {   
  646.                 buff[i] = *(writeData+i);   
  647.         }
  648.         CalulateCRC(buff, 16, &buff[16]);
  649.         status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);
  650.         
  651.                 if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
  652.         {   
  653.                         status = MI_ERR;   
  654.                 }
  655.     }
  656.    
  657.     return status;
  658. }


  659. /*
  660. * 函 数 名:MFRC522_Halt
  661. * 功能描述:命令卡片进入休眠状态
  662. * 输入参数:无
  663. * 返 回 值:无
  664. */
  665. void MFRC522_Halt(void)
  666. {
  667.         uchar status;
  668.     uint unLen;
  669.     uchar buff[4];

  670.     buff[0] = PICC_HALT;
  671.     buff[1] = 0;
  672.     CalulateCRC(buff, 2, &buff[2]);

  673.     status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff,&unLen);
  674. }


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

使用道具 举报

沙发
ID:134242 发表于 2017-7-13 14:19 | 只看该作者
各位!我司供应完全软硬件兼容RC522的国产非接芯片,成本有绝对优势,如有兴趣的可联系我Q458231727
回复

使用道具 举报

板凳
ID:134242 发表于 2017-7-13 14:21 | 只看该作者
提代RC522兼容版,需求联系Q肆伍捌贰叁壹柒贰柒
回复

使用道具 举报

地板
ID:241059 发表于 2019-4-25 19:02 | 只看该作者
实现什么功能呢?能否简要介绍一下
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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