Advertisement
Guest User

RFID code

a guest
Jun 1st, 2014
522
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.15 KB | None | 0 0
  1. #include <SPI.h>
  2. #include <Servo.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5.  
  6. //data array maxium length
  7. #define MAX_LEN 16
  8.  
  9. /////////////////////////////////////////////////////////////////////
  10. //set the pin
  11. /////////////////////////////////////////////////////////////////////
  12. const int chipSelectPin = 53;
  13. const int NRSTPD = 5;
  14. const int led = 13;
  15. int pos = 0;
  16. Servo myservo;
  17. int once = 0;
  18.  
  19. //MF522 command bits
  20. #define PCD_IDLE 0x00 //NO action; cancel current commands
  21. #define PCD_AUTHENT 0x0E //verify password key
  22. #define PCD_RECEIVE 0x08 //receive data
  23. #define PCD_TRANSMIT 0x04 //send data
  24. #define PCD_TRANSCEIVE 0x0C //send and receive data
  25. #define PCD_RESETPHASE 0x0F //reset
  26. #define PCD_CALCCRC 0x03 //CRC check and caculation
  27.  
  28. //Mifare_One card command bits
  29. #define PICC_REQIDL 0x26 //Search the cards that not into sleep mode in the antenna area
  30. #define PICC_REQALL 0x52 //Search all the cards in the antenna area
  31. #define PICC_ANTICOLL 0x93 //prevent conflict
  32. #define PICC_SElECTTAG 0x93 //select card
  33. #define PICC_AUTHENT1A 0x60 //verify A password key
  34. #define PICC_AUTHENT1B 0x61 //verify B password key
  35. #define PICC_READ 0x30 //read
  36. #define PICC_WRITE 0xA0 //write
  37. #define PICC_DECREMENT 0xC0 //deduct value
  38. #define PICC_INCREMENT 0xC1 //charge up value
  39. #define PICC_RESTORE 0xC2 //Restore data into buffer
  40. #define PICC_TRANSFER 0xB0 //Save data into buffer
  41. #define PICC_HALT 0x50 //sleep mode
  42.  
  43.  
  44. //THe mistake code that return when communicate with MF522
  45. #define MI_OK 0
  46. #define MI_NOTAGERR 1
  47. #define MI_ERR 2
  48.  
  49.  
  50. //------------------MFRC522 register ---------------
  51. //Page 0:Command and Status
  52. #define Reserved00 0x00
  53. #define CommandReg 0x01
  54. #define CommIEnReg 0x02
  55. #define DivlEnReg 0x03
  56. #define CommIrqReg 0x04
  57. #define DivIrqReg 0x05
  58. #define ErrorReg 0x06
  59. #define Status1Reg 0x07
  60. #define Status2Reg 0x08
  61. #define FIFODataReg 0x09
  62. #define FIFOLevelReg 0x0A
  63. #define WaterLevelReg 0x0B
  64. #define ControlReg 0x0C
  65. #define BitFramingReg 0x0D
  66. #define CollReg 0x0E
  67. #define Reserved01 0x0F
  68. //Page 1:Command
  69. #define Reserved10 0x10
  70. #define ModeReg 0x11
  71. #define TxModeReg 0x12
  72. #define RxModeReg 0x13
  73. #define TxControlReg 0x14
  74. #define TxAutoReg 0x15
  75. #define TxSelReg 0x16
  76. #define RxSelReg 0x17
  77. #define RxThresholdReg 0x18
  78. #define DemodReg 0x19
  79. #define Reserved11 0x1A
  80. #define Reserved12 0x1B
  81. #define MifareReg 0x1C
  82. #define Reserved13 0x1D
  83. #define Reserved14 0x1E
  84. #define SerialSpeedReg 0x1F
  85. //Page 2:CFG
  86. #define Reserved20 0x20
  87. #define CRCResultRegM 0x21
  88. #define CRCResultRegL 0x22
  89. #define Reserved21 0x23
  90. #define ModWidthReg 0x24
  91. #define Reserved22 0x25
  92. #define RFCfgReg 0x26
  93. #define GsNReg 0x27
  94. #define CWGsPReg 0x28
  95. #define ModGsPReg 0x29
  96. #define TModeReg 0x2A
  97. #define TPrescalerReg 0x2B
  98. #define TReloadRegH 0x2C
  99. #define TReloadRegL 0x2D
  100. #define TCounterValueRegH 0x2E
  101. #define TCounterValueRegL 0x2F
  102. //Page 3:TestRegister
  103. #define Reserved30 0x30
  104. #define TestSel1Reg 0x31
  105. #define TestSel2Reg 0x32
  106. #define TestPinEnReg 0x33
  107. #define TestPinValueReg 0x34
  108. #define TestBusReg 0x35
  109. #define AutoTestReg 0x36
  110. #define VersionReg 0x37
  111. #define AnalogTestReg 0x38
  112. #define TestDAC1Reg 0x39
  113. #define TestDAC2Reg 0x3A
  114. #define TestADCReg 0x3B
  115. #define Reserved31 0x3C
  116. #define Reserved32 0x3D
  117. #define Reserved33 0x3E
  118. #define Reserved34 0x3F
  119. //-----------------------------------------------
  120.  
  121. //4 bytes Serial number of card, the 5 bytes is verfiy bytes
  122. uchar serNum[5];
  123.  
  124.  
  125. void setup()
  126. {
  127. Serial.begin(57600);
  128.  
  129. SPI.begin();
  130.  
  131. pinMode(led,OUTPUT);
  132.  
  133. pinMode(chipSelectPin,OUTPUT); // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin
  134. digitalWrite(chipSelectPin, LOW); // Activate the RFID reader
  135. pinMode(NRSTPD,OUTPUT); // Set digital pin 5 , Not Reset and Power-down
  136. myservo.attach(9);
  137. MFRC522_Init();
  138. }
  139.  
  140.  
  141. void loop()
  142. {
  143.  
  144. uchar status;
  145. uchar str[MAX_LEN];
  146.  
  147.  
  148. // Search card, return card types
  149. status = MFRC522_Request(PICC_REQIDL, str);
  150. if (status != MI_OK)
  151. {
  152. if(once == 0){
  153. pos = 20;
  154. myservo.write(pos);
  155. once++;
  156. }
  157.  
  158. digitalWrite(led,LOW);
  159. return;
  160. }
  161.  
  162.  
  163. // Show card type
  164. ShowCardType(str);
  165.  
  166. //Prevent conflict, return the 4 bytes Serial number of the card
  167. status = MFRC522_Anticoll(str);
  168.  
  169. // str[0..3]: serial number of the card
  170. // str[4]: XOR checksum of the SN.
  171. if (status == MI_OK)
  172. {
  173.  
  174.  
  175. Serial.print("The card's number is: ");
  176. memcpy(serNum, str, 5);
  177. ShowCardID(serNum);
  178. digitalWrite(led,HIGH);
  179. pos = 180;
  180. myservo.write(pos);
  181. once = 0;
  182. delay(10000);
  183.  
  184. }
  185.  
  186.  
  187.  
  188. MFRC522_Halt(); //command the card into sleep mode
  189.  
  190. delay(200);
  191. }
  192.  
  193. /*
  194. * Function:ShowCardID
  195. * Description:Show Card ID
  196. * Input parameter:ID string
  197. * Return:Null
  198. */
  199. void ShowCardID(uchar *id)
  200. {
  201. int IDlen=4;
  202. for(int i=0; i<IDlen; i++){
  203. Serial.print(0x0F & (id[i]>>4), HEX);
  204. Serial.print(0x0F & id[i],HEX);
  205. }
  206. Serial.println("");
  207. }
  208.  
  209. /*
  210. * Function:ShowCardType
  211. * Description:Show Card type
  212. * Input parameter:Type string
  213. * Return:Null
  214. */
  215. void ShowCardType(uchar* type)
  216. {
  217. Serial.print("Card type: ");
  218. if(type[0]==0x04&&type[1]==0x00)
  219. Serial.println("MFOne-S50");
  220. else if(type[0]==0x02&&type[1]==0x00)
  221. Serial.println("MFOne-S70");
  222. else if(type[0]==0x44&&type[1]==0x00)
  223. Serial.println("MF-UltraLight");
  224. else if(type[0]==0x08&&type[1]==0x00)
  225. Serial.println("MF-Pro");
  226. else if(type[0]==0x44&&type[1]==0x03)
  227. Serial.println("MF Desire");
  228. else
  229. Serial.println("Unknown");
  230. }
  231.  
  232. /*
  233. * Function:Write_MFRC5200
  234. * Description:write a byte data into one register of MR RC522
  235. * Input parameter:addr--register address;val--the value that need to write in
  236. * Return:Null
  237. */
  238. void Write_MFRC522(uchar addr, uchar val)
  239. {
  240. digitalWrite(chipSelectPin, LOW);
  241.  
  242. //address format:0XXXXXX0
  243. SPI.transfer((addr<<1)&0x7E);
  244. SPI.transfer(val);
  245.  
  246. digitalWrite(chipSelectPin, HIGH);
  247. }
  248.  
  249.  
  250. /*
  251. * Function:Read_MFRC522
  252. * Description:read a byte data into one register of MR RC522
  253. * Input parameter:addr--register address
  254. * Return:return the read value
  255. */
  256. uchar Read_MFRC522(uchar addr)
  257. {
  258. uchar val;
  259.  
  260. digitalWrite(chipSelectPin, LOW);
  261.  
  262. //address format:1XXXXXX0
  263. SPI.transfer(((addr<<1)&0x7E) | 0x80);
  264. val =SPI.transfer(0x00);
  265.  
  266. digitalWrite(chipSelectPin, HIGH);
  267.  
  268. return val;
  269. }
  270.  
  271. /*
  272. * Function:SetBitMask
  273. * Description:set RC522 register bit
  274. * Input parameter:reg--register address;mask--value
  275. * Return:null
  276. */
  277. void SetBitMask(uchar reg, uchar mask)
  278. {
  279. uchar tmp;
  280. tmp = Read_MFRC522(reg);
  281. Write_MFRC522(reg, tmp | mask); // set bit mask
  282. }
  283.  
  284.  
  285. /*
  286. * Function:ClearBitMask
  287. * Description:clear RC522 register bit
  288. * Input parameter:reg--register address;mask--value
  289. * Return:null
  290. */
  291. void ClearBitMask(uchar reg, uchar mask)
  292. {
  293. uchar tmp;
  294. tmp = Read_MFRC522(reg);
  295. Write_MFRC522(reg, tmp & (~mask)); // clear bit mask
  296. }
  297.  
  298.  
  299. /*
  300. * Function:AntennaOn
  301. * Description:Turn on antenna, every time turn on or shut down antenna need at least 1ms delay
  302. * Input parameter:null
  303. * Return:null
  304. */
  305. void AntennaOn(void)
  306. {
  307. uchar temp;
  308.  
  309. temp = Read_MFRC522(TxControlReg);
  310. if (!(temp & 0x03))
  311. {
  312. SetBitMask(TxControlReg, 0x03);
  313. }
  314. }
  315.  
  316.  
  317. /*
  318. * Function:AntennaOff
  319. * Description:Turn off antenna, every time turn on or shut down antenna need at least 1ms delay
  320. * Input parameter:null
  321. * Return:null
  322. */
  323. void AntennaOff(void)
  324. {
  325. ClearBitMask(TxControlReg, 0x03);
  326. }
  327.  
  328.  
  329. /*
  330. * Function:ResetMFRC522
  331. * Description: reset RC522
  332. * Input parameter:null
  333. * Return:null
  334. */
  335. void MFRC522_Reset(void)
  336. {
  337. Write_MFRC522(CommandReg, PCD_RESETPHASE);
  338. }
  339.  
  340.  
  341. /*
  342. * Function:InitMFRC522
  343. * Description:initilize RC522
  344. * Input parameter:null
  345. * Return:null
  346. */
  347. void MFRC522_Init(void)
  348. {
  349. digitalWrite(NRSTPD,HIGH);
  350.  
  351. MFRC522_Reset();
  352.  
  353. //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
  354. Write_MFRC522(TModeReg, 0x8D); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
  355. Write_MFRC522(TPrescalerReg, 0x3E); //TModeReg[3..0] + TPrescalerReg
  356. Write_MFRC522(TReloadRegL, 30);
  357. Write_MFRC522(TReloadRegH, 0);
  358.  
  359. Write_MFRC522(TxAutoReg, 0x40); //100%ASK
  360. Write_MFRC522(ModeReg, 0x3D); //CRC initilizate value 0x6363 ???
  361.  
  362. //ClearBitMask(Status2Reg, 0x08); //MFCrypto1On=0
  363. //Write_MFRC522(RxSelReg, 0x86); //RxWait = RxSelReg[5..0]
  364. //Write_MFRC522(RFCfgReg, 0x7F); //RxGain = 48dB
  365.  
  366. AntennaOn(); //turn on antenna
  367. }
  368.  
  369.  
  370. /*
  371. * Function:MFRC522_Request
  372. * Description:Searching card, read card type
  373. * Input parameter:reqMode--search methods,
  374. * TagType--return card types
  375. * 0x4400 = Mifare_UltraLight
  376. * 0x0400 = Mifare_One(S50)
  377. * 0x0200 = Mifare_One(S70)
  378. * 0x0800 = Mifare_Pro(X)
  379. * 0x4403 = Mifare_DESFire
  380. * return:return MI_OK if successed
  381. */
  382. uchar MFRC522_Request(uchar reqMode, uchar *TagType)
  383. {
  384. uchar status;
  385. uint backBits; //the data bits that received
  386.  
  387. Write_MFRC522(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0] ???
  388.  
  389. TagType[0] = reqMode;
  390. status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
  391.  
  392. if ((status != MI_OK) || (backBits != 0x10))
  393. {
  394. status = MI_ERR;
  395. }
  396.  
  397. return status;
  398. }
  399.  
  400.  
  401. /*
  402. * Function:MFRC522_ToCard
  403. * Description:communicate between RC522 and ISO14443
  404. * Input parameter:command--MF522 command bits
  405. * sendData--send data to card via rc522
  406. * sendLen--send data length
  407. * backData--the return data from card
  408. * backLen--the length of return data
  409. * return:return MI_OK if successed
  410. */
  411. uchar MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen)
  412. {
  413. uchar status = MI_ERR;
  414. uchar irqEn = 0x00;
  415. uchar waitIRq = 0x00;
  416. uchar lastBits;
  417. uchar n;
  418. uint i;
  419.  
  420. switch (command)
  421. {
  422. case PCD_AUTHENT: //verify card password
  423. {
  424. irqEn = 0x12;
  425. waitIRq = 0x10;
  426. break;
  427. }
  428. case PCD_TRANSCEIVE: //send data in the FIFO
  429. {
  430. irqEn = 0x77;
  431. waitIRq = 0x30;
  432. break;
  433. }
  434. default:
  435. break;
  436. }
  437.  
  438. Write_MFRC522(CommIEnReg, irqEn|0x80); //Allow interruption
  439. ClearBitMask(CommIrqReg, 0x80); //Clear all the interrupt bits
  440. SetBitMask(FIFOLevelReg, 0x80); //FlushBuffer=1, FIFO initilizate
  441.  
  442. Write_MFRC522(CommandReg, PCD_IDLE); //NO action;cancel current command ???
  443.  
  444. //write data into FIFO
  445. for (i=0; i<sendLen; i++)
  446. {
  447. Write_MFRC522(FIFODataReg, sendData[i]);
  448. }
  449.  
  450. //procceed it
  451. Write_MFRC522(CommandReg, command);
  452. if (command == PCD_TRANSCEIVE)
  453. {
  454. SetBitMask(BitFramingReg, 0x80); //StartSend=1,transmission of data starts
  455. }
  456.  
  457. //waite receive data is finished
  458. i = 2000; //i should adjust according the clock, the maxium the waiting time should be 25 ms???
  459. do
  460. {
  461. //CommIrqReg[7..0]
  462. //Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
  463. n = Read_MFRC522(CommIrqReg);
  464. i--;
  465. }
  466. while ((i!=0) && !(n&0x01) && !(n&waitIRq));
  467.  
  468. ClearBitMask(BitFramingReg, 0x80); //StartSend=0
  469.  
  470. if (i != 0)
  471. {
  472. if(!(Read_MFRC522(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
  473. {
  474. status = MI_OK;
  475. if (n & irqEn & 0x01)
  476. {
  477. status = MI_NOTAGERR; //??
  478. }
  479.  
  480. if (command == PCD_TRANSCEIVE)
  481. {
  482. n = Read_MFRC522(FIFOLevelReg);
  483. lastBits = Read_MFRC522(ControlReg) & 0x07;
  484. if (lastBits)
  485. {
  486. *backLen = (n-1)*8 + lastBits;
  487. }
  488. else
  489. {
  490. *backLen = n*8;
  491. }
  492.  
  493. if (n == 0)
  494. {
  495. n = 1;
  496. }
  497. if (n > MAX_LEN)
  498. {
  499. n = MAX_LEN;
  500. }
  501.  
  502. //read the data from FIFO
  503. for (i=0; i<n; i++)
  504. {
  505. backData[i] = Read_MFRC522(FIFODataReg);
  506. }
  507. }
  508. }
  509. else
  510. {
  511. status = MI_ERR;
  512. }
  513.  
  514. }
  515.  
  516. //SetBitMask(ControlReg,0x80); //timer stops
  517. //Write_MFRC522(CommandReg, PCD_IDLE);
  518.  
  519. return status;
  520. }
  521.  
  522.  
  523. /*
  524. * Function:MFRC522_Anticoll
  525. * Description:Prevent conflict, read the card serial number
  526. * Input parameter:serNum--return the 4 bytes card serial number, the 5th byte is recheck byte
  527. * return:return MI_OK if successed
  528. */
  529. uchar MFRC522_Anticoll(uchar *serNum)
  530. {
  531. uchar status;
  532. uchar i;
  533. uchar serNumCheck=0;
  534. uint unLen;
  535.  
  536. //ClearBitMask(Status2Reg, 0x08); //strSensclear
  537. //ClearBitMask(CollReg,0x80); //ValuesAfterColl
  538. Write_MFRC522(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0]
  539.  
  540. serNum[0] = PICC_ANTICOLL;
  541. serNum[1] = 0x20;
  542. status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
  543.  
  544. if (status == MI_OK)
  545. {
  546. //Verify card serial number
  547. for (i=0; i<4; i++)
  548. {
  549. serNumCheck ^= serNum[i];
  550. }
  551. if (serNumCheck != serNum[i])
  552. {
  553. status = MI_ERR;
  554. }
  555. }
  556.  
  557. //SetBitMask(CollReg, 0x80); //ValuesAfterColl=1
  558.  
  559. return status;
  560. }
  561.  
  562.  
  563. /*
  564. * Function:CalulateCRC
  565. * Description:Use MF522 to caculate CRC
  566. * Input parameter:pIndata--the CRC data need to be read,len--data length,pOutData-- the caculated result of CRC
  567. * return:Null
  568. */
  569. void CalulateCRC(uchar *pIndata, uchar len, uchar *pOutData)
  570. {
  571. uchar i, n;
  572.  
  573. ClearBitMask(DivIrqReg, 0x04); //CRCIrq = 0
  574. SetBitMask(FIFOLevelReg, 0x80); //Clear FIFO pointer
  575. //Write_MFRC522(CommandReg, PCD_IDLE);
  576.  
  577. //Write data into FIFO
  578. for (i=0; i<len; i++)
  579. {
  580. Write_MFRC522(FIFODataReg, *(pIndata+i));
  581. }
  582. Write_MFRC522(CommandReg, PCD_CALCCRC);
  583.  
  584. //waite CRC caculation to finish
  585. i = 0xFF;
  586. do
  587. {
  588. n = Read_MFRC522(DivIrqReg);
  589. i--;
  590. }
  591. while ((i!=0) && !(n&0x04)); //CRCIrq = 1
  592.  
  593. //read CRC caculation result
  594. pOutData[0] = Read_MFRC522(CRCResultRegL);
  595. pOutData[1] = Read_MFRC522(CRCResultRegM);
  596. }
  597.  
  598.  
  599.  
  600. /*
  601. * Function:MFRC522_Write
  602. * Description:write block data
  603. * Input parameters:blockAddr--block address;writeData--Write 16 bytes data into block
  604. * return:return MI_OK if successed
  605. */
  606. uchar MFRC522_Write(uchar blockAddr, uchar *writeData)
  607. {
  608. uchar status;
  609. uint recvBits;
  610. uchar i;
  611. uchar buff[18];
  612.  
  613. buff[0] = PICC_WRITE;
  614. buff[1] = blockAddr;
  615. CalulateCRC(buff, 2, &buff[2]);
  616. status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);
  617.  
  618. if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
  619. {
  620. status = MI_ERR;
  621. }
  622.  
  623. if (status == MI_OK)
  624. {
  625. for (i=0; i<16; i++) //Write 16 bytes data into FIFO
  626. {
  627. buff[i] = *(writeData+i);
  628. }
  629. CalulateCRC(buff, 16, &buff[16]);
  630. status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);
  631.  
  632. if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
  633. {
  634. status = MI_ERR;
  635. }
  636. }
  637.  
  638. return status;
  639. }
  640.  
  641.  
  642. /*
  643. * Function:MFRC522_Halt
  644. * Description:Command the cards into sleep mode
  645. * Input parameters:null
  646. * return:null
  647. */
  648. void MFRC522_Halt(void)
  649. {
  650. uchar status;
  651. uint unLen;
  652. uchar buff[4];
  653.  
  654. buff[0] = PICC_HALT;
  655. buff[1] = 0;
  656. CalulateCRC(buff, 2, &buff[2]);
  657.  
  658. status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff,&unLen);
  659. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement