BUONO UNO R3 with RC522 RFID Reader Kit for Makers
BUONO UNO R3 with RC522 RFID Reader Kit and sample code for Arduino AVR Learner.
Components and supplies
1
KIT
Project description
Code
ARDUINO_CODE_AN_1400001_RFID_RC522.ino
c_cpp
1/*===================================================================================== 2ARDUINO_CODE_AN_1400001_RFID_RC522.ino 3www.inhaos.com 4 5RFID RC522 Demo Code 6Rev: 1.0 7Date: 18 Mar.2014 8 9Hardware: 10 1 * BUONO UNO R3 11 1 * RFID-RC522 12 1 * RF ID Card 13 14Tested Platform: 15 Arduino 1.5.4 16 17Connection: 18 UNO <-> RFID-RC522 19 3V3 VCC 20 D5 RST 21 GND GND 22 D12 MISO 23 D11 MOSI 24 D13 SCK 25 D10 NSS 26 x IRQ 27=====================================================================================*/ 28 29#include <SPI.h> 30 31#define uchar unsigned char 32#define uint unsigned int 33 34//data array maxium length 35#define MAX_LEN 16 36 37///////////////////////////////////////////////////////////////////// 38//set the pin 39///////////////////////////////////////////////////////////////////// 40const int chipSelectPin = 10; 41const int NRSTPD = 5; 42 43 44 45//MF522 command bits 46#define PCD_IDLE 0x00 //NO action; cancel current commands 47#define PCD_AUTHENT 0x0E //verify password key 48#define PCD_RECEIVE 0x08 //receive data 49#define PCD_TRANSMIT 0x04 //send data 50#define PCD_TRANSCEIVE 0x0C //send and receive data 51#define PCD_RESETPHASE 0x0F //reset 52#define PCD_CALCCRC 0x03 //CRC check and caculation 53 54//Mifare_One card command bits 55#define PICC_REQIDL 0x26 //Search the cards that not into sleep mode in the antenna area 56#define PICC_REQALL 0x52 //Search all the cards in the antenna area 57#define PICC_ANTICOLL 0x93 //prevent conflict 58#define PICC_SElECTTAG 0x93 //select card 59#define PICC_AUTHENT1A 0x60 //verify A password key 60#define PICC_AUTHENT1B 0x61 //verify B password key 61#define PICC_READ 0x30 //read 62#define PICC_WRITE 0xA0 //write 63#define PICC_DECREMENT 0xC0 //deduct value 64#define PICC_INCREMENT 0xC1 //charge up value 65#define PICC_RESTORE 0xC2 //Restore data into buffer 66#define PICC_TRANSFER 0xB0 //Save data into buffer 67#define PICC_HALT 0x50 //sleep mode 68 69 70//THe mistake code that return when communicate with MF522 71#define MI_OK 0 72#define MI_NOTAGERR 1 73#define MI_ERR 2 74 75 76//------------------MFRC522 register --------------- 77//Page 0:Command and Status 78#define Reserved00 0x00 79#define CommandReg 0x01 80#define CommIEnReg 0x02 81#define DivlEnReg 0x03 82#define CommIrqReg 0x04 83#define DivIrqReg 0x05 84#define ErrorReg 0x06 85#define Status1Reg 0x07 86#define Status2Reg 0x08 87#define FIFODataReg 0x09 88#define FIFOLevelReg 0x0A 89#define WaterLevelReg 0x0B 90#define ControlReg 0x0C 91#define BitFramingReg 0x0D 92#define CollReg 0x0E 93#define Reserved01 0x0F 94//Page 1:Command 95#define Reserved10 0x10 96#define ModeReg 0x11 97#define TxModeReg 0x12 98#define RxModeReg 0x13 99#define TxControlReg 0x14 100#define TxAutoReg 0x15 101#define TxSelReg 0x16 102#define RxSelReg 0x17 103#define RxThresholdReg 0x18 104#define DemodReg 0x19 105#define Reserved11 0x1A 106#define Reserved12 0x1B 107#define MifareReg 0x1C 108#define Reserved13 0x1D 109#define Reserved14 0x1E 110#define SerialSpeedReg 0x1F 111//Page 2:CFG 112#define Reserved20 0x20 113#define CRCResultRegM 0x21 114#define CRCResultRegL 0x22 115#define Reserved21 0x23 116#define ModWidthReg 0x24 117#define Reserved22 0x25 118#define RFCfgReg 0x26 119#define GsNReg 0x27 120#define CWGsPReg 0x28 121#define ModGsPReg 0x29 122#define TModeReg 0x2A 123#define TPrescalerReg 0x2B 124#define TReloadRegH 0x2C 125#define TReloadRegL 0x2D 126#define TCounterValueRegH 0x2E 127#define TCounterValueRegL 0x2F 128//Page 3:TestRegister 129#define Reserved30 0x30 130#define TestSel1Reg 0x31 131#define TestSel2Reg 0x32 132#define TestPinEnReg 0x33 133#define TestPinValueReg 0x34 134#define TestBusReg 0x35 135#define AutoTestReg 0x36 136#define VersionReg 0x37 137#define AnalogTestReg 0x38 138#define TestDAC1Reg 0x39 139#define TestDAC2Reg 0x3A 140#define TestADCReg 0x3B 141#define Reserved31 0x3C 142#define Reserved32 0x3D 143#define Reserved33 0x3E 144#define Reserved34 0x3F 145//----------------------------------------------- 146 147//4 bytes Serial number of card, the 5 bytes is verfiy bytes 148uchar serNum[5]; 149 150 151void setup() 152{ 153 Serial.begin(57600); 154 155 SPI.begin(); 156 157 pinMode(chipSelectPin,OUTPUT); // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin 158 digitalWrite(chipSelectPin, LOW); // Activate the RFID reader 159 pinMode(NRSTPD,OUTPUT); // Set digital pin 5 , Not Reset and Power-down 160 161 MFRC522_Init(); 162} 163 164 165void loop() 166{ 167 168 uchar status; 169 uchar str[MAX_LEN]; 170 171 172 // Search card, return card types 173 status = MFRC522_Request(PICC_REQIDL, str); 174 if (status != MI_OK) 175 { 176 return; 177 } 178 179 180 // Show card type 181 ShowCardType(str); 182 183 //Prevent conflict, return the 4 bytes Serial number of the card 184 status = MFRC522_Anticoll(str); 185 186 // str[0..3]: serial number of the card 187 // str[4]: XOR checksum of the SN. 188 if (status == MI_OK) 189 { 190 Serial.print("The card's number is: "); 191 memcpy(serNum, str, 5); 192 ShowCardID(serNum); 193 194 // Check people associated with card ID 195 uchar* id = serNum; 196 if( id[0]==0x4B && id[1]==0xE6 && id[2]==0xD1 && id[3]==0x3B ) { 197 Serial.println("Hello Mary!"); 198 } 199 else if(id[0]==0x3B && id[1]==0xE6 && id[2]==0xD1 && id[3]==0x3B) { 200 Serial.println("Hello Greg!"); 201 } 202 else{ 203 Serial.println("Hello unkown guy!"); 204 } 205 } 206 207 208 MFRC522_Halt(); //command the card into sleep mode 209 210 delay(200); 211} 212 213/* 214 * FunctionShowCardID 215 * DescriptionShow Card ID 216 * Input parameterID string 217 * ReturnNull 218 */ 219void ShowCardID(uchar *id) 220{ 221 int IDlen=4; 222 for(int i=0; i<IDlen; i++){ 223 Serial.print(0x0F & (id[i]>>4), HEX); 224 Serial.print(0x0F & id[i],HEX); 225 } 226 Serial.println(""); 227} 228 229/* 230 * FunctionShowCardType 231 * DescriptionShow Card type 232 * Input parameterType string 233 * ReturnNull 234 */ 235void ShowCardType(uchar* type) 236{ 237 Serial.print("Card type: "); 238 if(type[0]==0x04&&type[1]==0x00) 239 Serial.println("MFOne-S50"); 240 else if(type[0]==0x02&&type[1]==0x00) 241 Serial.println("MFOne-S70"); 242 else if(type[0]==0x44&&type[1]==0x00) 243 Serial.println("MF-UltraLight"); 244 else if(type[0]==0x08&&type[1]==0x00) 245 Serial.println("MF-Pro"); 246 else if(type[0]==0x44&&type[1]==0x03) 247 Serial.println("MF Desire"); 248 else 249 Serial.println("Unknown"); 250} 251 252/* 253 * FunctionWrite_MFRC5200 254 * Descriptionwrite a byte data into one register of MR RC522 255 * Input parameteraddr--register addressval--the value that need to write in 256 * ReturnNull 257 */ 258void Write_MFRC522(uchar addr, uchar val) 259{ 260 digitalWrite(chipSelectPin, LOW); 261 262 //address format0XXXXXX0 263 SPI.transfer((addr<<1)&0x7E); 264 SPI.transfer(val); 265 266 digitalWrite(chipSelectPin, HIGH); 267} 268 269 270/* 271 * FunctionRead_MFRC522 272 * Descriptionread a byte data into one register of MR RC522 273 * Input parameteraddr--register address 274 * Returnreturn the read value 275 */ 276uchar Read_MFRC522(uchar addr) 277{ 278 uchar val; 279 280 digitalWrite(chipSelectPin, LOW); 281 282 //address format1XXXXXX0 283 SPI.transfer(((addr<<1)&0x7E) | 0x80); 284 val =SPI.transfer(0x00); 285 286 digitalWrite(chipSelectPin, HIGH); 287 288 return val; 289} 290 291/* 292 * FunctionSetBitMask 293 * Descriptionset RC522 register bit 294 * Input parameterreg--register address;mask--value 295 * Returnnull 296 */ 297void SetBitMask(uchar reg, uchar mask) 298{ 299 uchar tmp; 300 tmp = Read_MFRC522(reg); 301 Write_MFRC522(reg, tmp | mask); // set bit mask 302} 303 304 305/* 306 * FunctionClearBitMask 307 * Descriptionclear RC522 register bit 308 * Input parameterreg--register address;mask--value 309 * Returnnull 310 */ 311void ClearBitMask(uchar reg, uchar mask) 312{ 313 uchar tmp; 314 tmp = Read_MFRC522(reg); 315 Write_MFRC522(reg, tmp & (~mask)); // clear bit mask 316} 317 318 319/* 320 * FunctionAntennaOn 321 * DescriptionTurn on antenna, every time turn on or shut down antenna need at least 1ms delay 322 * Input parameternull 323 * Returnnull 324 */ 325void AntennaOn(void) 326{ 327 uchar temp; 328 329 temp = Read_MFRC522(TxControlReg); 330 if (!(temp & 0x03)) 331 { 332 SetBitMask(TxControlReg, 0x03); 333 } 334} 335 336 337/* 338 * FunctionAntennaOff 339 * DescriptionTurn off antenna, every time turn on or shut down antenna need at least 1ms delay 340 * Input parameternull 341 * Returnnull 342 */ 343void AntennaOff(void) 344{ 345 ClearBitMask(TxControlReg, 0x03); 346} 347 348 349/* 350 * FunctionResetMFRC522 351 * Description reset RC522 352 * Input parameternull 353 * Returnnull 354 */ 355void MFRC522_Reset(void) 356{ 357 Write_MFRC522(CommandReg, PCD_RESETPHASE); 358} 359 360 361/* 362 * FunctionInitMFRC522 363 * Descriptioninitilize RC522 364 * Input parameternull 365 * Returnnull 366 */ 367void MFRC522_Init(void) 368{ 369 digitalWrite(NRSTPD,HIGH); 370 371 MFRC522_Reset(); 372 373 //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms 374 Write_MFRC522(TModeReg, 0x8D); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler 375 Write_MFRC522(TPrescalerReg, 0x3E); //TModeReg[3..0] + TPrescalerReg 376 Write_MFRC522(TReloadRegL, 30); 377 Write_MFRC522(TReloadRegH, 0); 378 379 Write_MFRC522(TxAutoReg, 0x40); //100%ASK 380 Write_MFRC522(ModeReg, 0x3D); //CRC initilizate value 0x6363 ??? 381 382 //ClearBitMask(Status2Reg, 0x08); //MFCrypto1On=0 383 //Write_MFRC522(RxSelReg, 0x86); //RxWait = RxSelReg[5..0] 384 //Write_MFRC522(RFCfgReg, 0x7F); //RxGain = 48dB 385 386 AntennaOn(); //turn on antenna 387} 388 389 390/* 391 * FunctionMFRC522_Request 392 * DescriptionSearching card, read card type 393 * Input parameterreqMode--search methods 394 * TagType--return card types 395 * 0x4400 = Mifare_UltraLight 396 * 0x0400 = Mifare_One(S50) 397 * 0x0200 = Mifare_One(S70) 398 * 0x0800 = Mifare_Pro(X) 399 * 0x4403 = Mifare_DESFire 400 * returnreturn MI_OK if successed 401 */ 402uchar MFRC522_Request(uchar reqMode, uchar *TagType) 403{ 404 uchar status; 405 uint backBits; //the data bits that received 406 407 Write_MFRC522(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0] ??? 408 409 TagType[0] = reqMode; 410 status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits); 411 412 if ((status != MI_OK) || (backBits != 0x10)) 413 { 414 status = MI_ERR; 415 } 416 417 return status; 418} 419 420 421/* 422 * FunctionMFRC522_ToCard 423 * Descriptioncommunicate between RC522 and ISO14443 424 * Input parametercommand--MF522 command bits 425 * sendData--send data to card via rc522 426 * sendLen--send data length 427 * backData--the return data from card 428 * backLen--the length of return data 429 * returnreturn MI_OK if successed 430 */ 431uchar MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen) 432{ 433 uchar status = MI_ERR; 434 uchar irqEn = 0x00; 435 uchar waitIRq = 0x00; 436 uchar lastBits; 437 uchar n; 438 uint i; 439 440 switch (command) 441 { 442 case PCD_AUTHENT: //verify card password 443 { 444 irqEn = 0x12; 445 waitIRq = 0x10; 446 break; 447 } 448 case PCD_TRANSCEIVE: //send data in the FIFO 449 { 450 irqEn = 0x77; 451 waitIRq = 0x30; 452 break; 453 } 454 default: 455 break; 456 } 457 458 Write_MFRC522(CommIEnReg, irqEn|0x80); //Allow interruption 459 ClearBitMask(CommIrqReg, 0x80); //Clear all the interrupt bits 460 SetBitMask(FIFOLevelReg, 0x80); //FlushBuffer=1, FIFO initilizate 461 462 Write_MFRC522(CommandReg, PCD_IDLE); //NO action;cancel current command ??? 463 464 //write data into FIFO 465 for (i=0; i<sendLen; i++) 466 { 467 Write_MFRC522(FIFODataReg, sendData[i]); 468 } 469 470 //procceed it 471 Write_MFRC522(CommandReg, command); 472 if (command == PCD_TRANSCEIVE) 473 { 474 SetBitMask(BitFramingReg, 0x80); //StartSend=1,transmission of data starts 475 } 476 477 //waite receive data is finished 478 i = 2000; //i should adjust according the clock, the maxium the waiting time should be 25 ms??? 479 do 480 { 481 //CommIrqReg[7..0] 482 //Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq 483 n = Read_MFRC522(CommIrqReg); 484 i--; 485 } 486 while ((i!=0) && !(n&0x01) && !(n&waitIRq)); 487 488 ClearBitMask(BitFramingReg, 0x80); //StartSend=0 489 490 if (i != 0) 491 { 492 if(!(Read_MFRC522(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr 493 { 494 status = MI_OK; 495 if (n & irqEn & 0x01) 496 { 497 status = MI_NOTAGERR; //?? 498 } 499 500 if (command == PCD_TRANSCEIVE) 501 { 502 n = Read_MFRC522(FIFOLevelReg); 503 lastBits = Read_MFRC522(ControlReg) & 0x07; 504 if (lastBits) 505 { 506 *backLen = (n-1)*8 + lastBits; 507 } 508 else 509 { 510 *backLen = n*8; 511 } 512 513 if (n == 0) 514 { 515 n = 1; 516 } 517 if (n > MAX_LEN) 518 { 519 n = MAX_LEN; 520 } 521 522 //read the data from FIFO 523 for (i=0; i<n; i++) 524 { 525 backData[i] = Read_MFRC522(FIFODataReg); 526 } 527 } 528 } 529 else 530 { 531 status = MI_ERR; 532 } 533 534 } 535 536 //SetBitMask(ControlReg,0x80); //timer stops 537 //Write_MFRC522(CommandReg, PCD_IDLE); 538 539 return status; 540} 541 542 543/* 544 * FunctionMFRC522_Anticoll 545 * DescriptionPrevent conflict, read the card serial number 546 * Input parameterserNum--return the 4 bytes card serial number, the 5th byte is recheck byte 547 * returnreturn MI_OK if successed 548 */ 549uchar MFRC522_Anticoll(uchar *serNum) 550{ 551 uchar status; 552 uchar i; 553 uchar serNumCheck=0; 554 uint unLen; 555 556 //ClearBitMask(Status2Reg, 0x08); //strSensclear 557 //ClearBitMask(CollReg,0x80); //ValuesAfterColl 558 Write_MFRC522(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0] 559 560 serNum[0] = PICC_ANTICOLL; 561 serNum[1] = 0x20; 562 status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen); 563 564 if (status == MI_OK) 565 { 566 //Verify card serial number 567 for (i=0; i<4; i++) 568 { 569 serNumCheck ^= serNum[i]; 570 } 571 if (serNumCheck != serNum[i]) 572 { 573 status = MI_ERR; 574 } 575 } 576 577 //SetBitMask(CollReg, 0x80); //ValuesAfterColl=1 578 579 return status; 580} 581 582 583/* 584 * FunctionCalulateCRC 585 * DescriptionUse MF522 to caculate CRC 586 * Input parameterpIndata--the CRC data need to be readlen--data lengthpOutData-- the caculated result of CRC 587 * returnNull 588 */ 589void CalulateCRC(uchar *pIndata, uchar len, uchar *pOutData) 590{ 591 uchar i, n; 592 593 ClearBitMask(DivIrqReg, 0x04); //CRCIrq = 0 594 SetBitMask(FIFOLevelReg, 0x80); //Clear FIFO pointer 595 //Write_MFRC522(CommandReg, PCD_IDLE); 596 597 //Write data into FIFO 598 for (i=0; i<len; i++) 599 { 600 Write_MFRC522(FIFODataReg, *(pIndata+i)); 601 } 602 Write_MFRC522(CommandReg, PCD_CALCCRC); 603 604 //waite CRC caculation to finish 605 i = 0xFF; 606 do 607 { 608 n = Read_MFRC522(DivIrqReg); 609 i--; 610 } 611 while ((i!=0) && !(n&0x04)); //CRCIrq = 1 612 613 //read CRC caculation result 614 pOutData[0] = Read_MFRC522(CRCResultRegL); 615 pOutData[1] = Read_MFRC522(CRCResultRegM); 616} 617 618 619 620/* 621 * FunctionMFRC522_Write 622 * Descriptionwrite block data 623 * Input parametersblockAddr--block address;writeData--Write 16 bytes data into block 624 * returnreturn MI_OK if successed 625 */ 626uchar 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 638 if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) 639 { 640 status = MI_ERR; 641 } 642 643 if (status == MI_OK) 644 { 645 for (i=0; i<16; i++) //Write 16 bytes data into FIFO 646 { 647 buff[i] = *(writeData+i); 648 } 649 CalulateCRC(buff, 16, &buff[16]); 650 status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits); 651 652 if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) 653 { 654 status = MI_ERR; 655 } 656 } 657 658 return status; 659} 660 661 662/* 663 * FunctionMFRC522_Halt 664 * DescriptionCommand the cards into sleep mode 665 * Input parametersnull 666 * returnnull 667 */ 668void MFRC522_Halt(void) 669{ 670 uchar status; 671 uint unLen; 672 uchar buff[4]; 673 674 buff[0] = PICC_HALT; 675 buff[1] = 0; 676 CalulateCRC(buff, 2, &buff[2]); 677 678 status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff,&unLen); 679} 680 681 682
ARDUINO_CODE_AN_1400001_RFID_RC522.ino
c_cpp
1/*===================================================================================== 2ARDUINO_CODE_AN_1400001_RFID_RC522.ino 3www.inhaos.com 4 5RFID RC522 Demo Code 6Rev: 1.0 7Date: 18 Mar.2014 8 9Hardware: 10 1 * BUONO UNO R3 11 1 * RFID-RC522 12 1 * RF ID Card 13 14Tested Platform: 15 Arduino 1.5.4 16 17Connection: 18 UNO <-> RFID-RC522 19 3V3 VCC 20 D5 RST 21 GND GND 22 D12 MISO 23 D11 MOSI 24 D13 SCK 25 D10 NSS 26 x IRQ 27=====================================================================================*/ 28 29#include <SPI.h> 30 31#define uchar unsigned char 32#define uint unsigned int 33 34//data array maxium length 35#define MAX_LEN 16 36 37///////////////////////////////////////////////////////////////////// 38//set the pin 39///////////////////////////////////////////////////////////////////// 40const int chipSelectPin = 10; 41const int NRSTPD = 5; 42 43 44 45//MF522 command bits 46#define PCD_IDLE 0x00 //NO action; cancel current commands 47#define PCD_AUTHENT 0x0E //verify password key 48#define PCD_RECEIVE 0x08 //receive data 49#define PCD_TRANSMIT 0x04 //send data 50#define PCD_TRANSCEIVE 0x0C //send and receive data 51#define PCD_RESETPHASE 0x0F //reset 52#define PCD_CALCCRC 0x03 //CRC check and caculation 53 54//Mifare_One card command bits 55#define PICC_REQIDL 0x26 //Search the cards that not into sleep mode in the antenna area 56#define PICC_REQALL 0x52 //Search all the cards in the antenna area 57#define PICC_ANTICOLL 0x93 //prevent conflict 58#define PICC_SElECTTAG 0x93 //select card 59#define PICC_AUTHENT1A 0x60 //verify A password key 60#define PICC_AUTHENT1B 0x61 //verify B password key 61#define PICC_READ 0x30 //read 62#define PICC_WRITE 0xA0 //write 63#define PICC_DECREMENT 0xC0 //deduct value 64#define PICC_INCREMENT 0xC1 //charge up value 65#define PICC_RESTORE 0xC2 //Restore data into buffer 66#define PICC_TRANSFER 0xB0 //Save data into buffer 67#define PICC_HALT 0x50 //sleep mode 68 69 70//THe mistake code that return when communicate with MF522 71#define MI_OK 0 72#define MI_NOTAGERR 1 73#define MI_ERR 2 74 75 76//------------------MFRC522 register --------------- 77//Page 0:Command and Status 78#define Reserved00 0x00 79#define CommandReg 0x01 80#define CommIEnReg 0x02 81#define DivlEnReg 0x03 82#define CommIrqReg 0x04 83#define DivIrqReg 0x05 84#define ErrorReg 0x06 85#define Status1Reg 0x07 86#define Status2Reg 0x08 87#define FIFODataReg 0x09 88#define FIFOLevelReg 0x0A 89#define WaterLevelReg 0x0B 90#define ControlReg 0x0C 91#define BitFramingReg 0x0D 92#define CollReg 0x0E 93#define Reserved01 0x0F 94//Page 1:Command 95#define Reserved10 0x10 96#define ModeReg 0x11 97#define TxModeReg 0x12 98#define RxModeReg 0x13 99#define TxControlReg 0x14 100#define TxAutoReg 0x15 101#define TxSelReg 0x16 102#define RxSelReg 0x17 103#define RxThresholdReg 0x18 104#define DemodReg 0x19 105#define Reserved11 0x1A 106#define Reserved12 0x1B 107#define MifareReg 0x1C 108#define Reserved13 0x1D 109#define Reserved14 0x1E 110#define SerialSpeedReg 0x1F 111//Page 2:CFG 112#define Reserved20 0x20 113#define CRCResultRegM 0x21 114#define CRCResultRegL 0x22 115#define Reserved21 0x23 116#define ModWidthReg 0x24 117#define Reserved22 0x25 118#define RFCfgReg 0x26 119#define GsNReg 0x27 120#define CWGsPReg 0x28 121#define ModGsPReg 0x29 122#define TModeReg 0x2A 123#define TPrescalerReg 0x2B 124#define TReloadRegH 0x2C 125#define TReloadRegL 0x2D 126#define TCounterValueRegH 0x2E 127#define TCounterValueRegL 0x2F 128//Page 3:TestRegister 129#define Reserved30 0x30 130#define TestSel1Reg 0x31 131#define TestSel2Reg 0x32 132#define TestPinEnReg 0x33 133#define TestPinValueReg 0x34 134#define TestBusReg 0x35 135#define AutoTestReg 0x36 136#define VersionReg 0x37 137#define AnalogTestReg 0x38 138#define TestDAC1Reg 0x39 139#define TestDAC2Reg 0x3A 140#define TestADCReg 0x3B 141#define Reserved31 0x3C 142#define Reserved32 0x3D 143#define Reserved33 0x3E 144#define Reserved34 0x3F 145//----------------------------------------------- 146 147//4 bytes Serial number of card, the 5 bytes is verfiy bytes 148uchar serNum[5]; 149 150 151void setup() 152{ 153 Serial.begin(57600); 154 155 SPI.begin(); 156 157 pinMode(chipSelectPin,OUTPUT); // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin 158 digitalWrite(chipSelectPin, LOW); // Activate the RFID reader 159 pinMode(NRSTPD,OUTPUT); // Set digital pin 5 , Not Reset and Power-down 160 161 MFRC522_Init(); 162} 163 164 165void loop() 166{ 167 168 uchar status; 169 uchar str[MAX_LEN]; 170 171 172 // Search card, return card types 173 status = MFRC522_Request(PICC_REQIDL, str); 174 if (status != MI_OK) 175 { 176 return; 177 } 178 179 180 // Show card type 181 ShowCardType(str); 182 183 //Prevent conflict, return the 4 bytes Serial number of the card 184 status = MFRC522_Anticoll(str); 185 186 // str[0..3]: serial number of the card 187 // str[4]: XOR checksum of the SN. 188 if (status == MI_OK) 189 { 190 Serial.print("The card's number is: "); 191 memcpy(serNum, str, 5); 192 ShowCardID(serNum); 193 194 // Check people associated with card ID 195 uchar* id = serNum; 196 if( id[0]==0x4B && id[1]==0xE6 && id[2]==0xD1 && id[3]==0x3B ) { 197 Serial.println("Hello Mary!"); 198 } 199 else if(id[0]==0x3B && id[1]==0xE6 && id[2]==0xD1 && id[3]==0x3B) { 200 Serial.println("Hello Greg!"); 201 } 202 else{ 203 Serial.println("Hello unkown guy!"); 204 } 205 } 206 207 208 MFRC522_Halt(); //command the card into sleep mode 209 210 delay(200); 211} 212 213/* 214 * FunctionShowCardID 215 * DescriptionShow Card ID 216 * Input parameterID string 217 * ReturnNull 218 */ 219void ShowCardID(uchar *id) 220{ 221 int IDlen=4; 222 for(int i=0; i<IDlen; i++){ 223 Serial.print(0x0F & (id[i]>>4), HEX); 224 Serial.print(0x0F & id[i],HEX); 225 } 226 Serial.println(""); 227} 228 229/* 230 * FunctionShowCardType 231 * DescriptionShow Card type 232 * Input parameterType string 233 * ReturnNull 234 */ 235void ShowCardType(uchar* type) 236{ 237 Serial.print("Card type: "); 238 if(type[0]==0x04&&type[1]==0x00) 239 Serial.println("MFOne-S50"); 240 else if(type[0]==0x02&&type[1]==0x00) 241 Serial.println("MFOne-S70"); 242 else if(type[0]==0x44&&type[1]==0x00) 243 Serial.println("MF-UltraLight"); 244 else if(type[0]==0x08&&type[1]==0x00) 245 Serial.println("MF-Pro"); 246 else if(type[0]==0x44&&type[1]==0x03) 247 Serial.println("MF Desire"); 248 else 249 Serial.println("Unknown"); 250} 251 252/* 253 * FunctionWrite_MFRC5200 254 * Descriptionwrite a byte data into one register of MR RC522 255 * Input parameteraddr--register addressval--the value that need to write in 256 * ReturnNull 257 */ 258void Write_MFRC522(uchar addr, uchar val) 259{ 260 digitalWrite(chipSelectPin, LOW); 261 262 //address format0XXXXXX0 263 SPI.transfer((addr<<1)&0x7E); 264 SPI.transfer(val); 265 266 digitalWrite(chipSelectPin, HIGH); 267} 268 269 270/* 271 * FunctionRead_MFRC522 272 * Descriptionread a byte data into one register of MR RC522 273 * Input parameteraddr--register address 274 * Returnreturn the read value 275 */ 276uchar Read_MFRC522(uchar addr) 277{ 278 uchar val; 279 280 digitalWrite(chipSelectPin, LOW); 281 282 //address format1XXXXXX0 283 SPI.transfer(((addr<<1)&0x7E) | 0x80); 284 val =SPI.transfer(0x00); 285 286 digitalWrite(chipSelectPin, HIGH); 287 288 return val; 289} 290 291/* 292 * FunctionSetBitMask 293 * Descriptionset RC522 register bit 294 * Input parameterreg--register address;mask--value 295 * Returnnull 296 */ 297void SetBitMask(uchar reg, uchar mask) 298{ 299 uchar tmp; 300 tmp = Read_MFRC522(reg); 301 Write_MFRC522(reg, tmp | mask); // set bit mask 302} 303 304 305/* 306 * FunctionClearBitMask 307 * Descriptionclear RC522 register bit 308 * Input parameterreg--register address;mask--value 309 * Returnnull 310 */ 311void ClearBitMask(uchar reg, uchar mask) 312{ 313 uchar tmp; 314 tmp = Read_MFRC522(reg); 315 Write_MFRC522(reg, tmp & (~mask)); // clear bit mask 316} 317 318 319/* 320 * FunctionAntennaOn 321 * DescriptionTurn on antenna, every time turn on or shut down antenna need at least 1ms delay 322 * Input parameternull 323 * Returnnull 324 */ 325void AntennaOn(void) 326{ 327 uchar temp; 328 329 temp = Read_MFRC522(TxControlReg); 330 if (!(temp & 0x03)) 331 { 332 SetBitMask(TxControlReg, 0x03); 333 } 334} 335 336 337/* 338 * FunctionAntennaOff 339 * DescriptionTurn off antenna, every time turn on or shut down antenna need at least 1ms delay 340 * Input parameternull 341 * Returnnull 342 */ 343void AntennaOff(void) 344{ 345 ClearBitMask(TxControlReg, 0x03); 346} 347 348 349/* 350 * FunctionResetMFRC522 351 * Description reset RC522 352 * Input parameternull 353 * Returnnull 354 */ 355void MFRC522_Reset(void) 356{ 357 Write_MFRC522(CommandReg, PCD_RESETPHASE); 358} 359 360 361/* 362 * FunctionInitMFRC522 363 * Descriptioninitilize RC522 364 * Input parameternull 365 * Returnnull 366 */ 367void MFRC522_Init(void) 368{ 369 digitalWrite(NRSTPD,HIGH); 370 371 MFRC522_Reset(); 372 373 //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms 374 Write_MFRC522(TModeReg, 0x8D); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler 375 Write_MFRC522(TPrescalerReg, 0x3E); //TModeReg[3..0] + TPrescalerReg 376 Write_MFRC522(TReloadRegL, 30); 377 Write_MFRC522(TReloadRegH, 0); 378 379 Write_MFRC522(TxAutoReg, 0x40); //100%ASK 380 Write_MFRC522(ModeReg, 0x3D); //CRC initilizate value 0x6363 ??? 381 382 //ClearBitMask(Status2Reg, 0x08); //MFCrypto1On=0 383 //Write_MFRC522(RxSelReg, 0x86); //RxWait = RxSelReg[5..0] 384 //Write_MFRC522(RFCfgReg, 0x7F); //RxGain = 48dB 385 386 AntennaOn(); //turn on antenna 387} 388 389 390/* 391 * FunctionMFRC522_Request 392 * DescriptionSearching card, read card type 393 * Input parameterreqMode--search methods 394 * TagType--return card types 395 * 0x4400 = Mifare_UltraLight 396 * 0x0400 = Mifare_One(S50) 397 * 0x0200 = Mifare_One(S70) 398 * 0x0800 = Mifare_Pro(X) 399 * 0x4403 = Mifare_DESFire 400 * returnreturn MI_OK if successed 401 */ 402uchar MFRC522_Request(uchar reqMode, uchar *TagType) 403{ 404 uchar status; 405 uint backBits; //the data bits that received 406 407 Write_MFRC522(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0] ??? 408 409 TagType[0] = reqMode; 410 status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits); 411 412 if ((status != MI_OK) || (backBits != 0x10)) 413 { 414 status = MI_ERR; 415 } 416 417 return status; 418} 419 420 421/* 422 * FunctionMFRC522_ToCard 423 * Descriptioncommunicate between RC522 and ISO14443 424 * Input parametercommand--MF522 command bits 425 * sendData--send data to card via rc522 426 * sendLen--send data length 427 * backData--the return data from card 428 * backLen--the length of return data 429 * returnreturn MI_OK if successed 430 */ 431uchar MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen) 432{ 433 uchar status = MI_ERR; 434 uchar irqEn = 0x00; 435 uchar waitIRq = 0x00; 436 uchar lastBits; 437 uchar n; 438 uint i; 439 440 switch (command) 441 { 442 case PCD_AUTHENT: //verify card password 443 { 444 irqEn = 0x12; 445 waitIRq = 0x10; 446 break; 447 } 448 case PCD_TRANSCEIVE: //send data in the FIFO 449 { 450 irqEn = 0x77; 451 waitIRq = 0x30; 452 break; 453 } 454 default: 455 break; 456 } 457 458 Write_MFRC522(CommIEnReg, irqEn|0x80); //Allow interruption 459 ClearBitMask(CommIrqReg, 0x80); //Clear all the interrupt bits 460 SetBitMask(FIFOLevelReg, 0x80); //FlushBuffer=1, FIFO initilizate 461 462 Write_MFRC522(CommandReg, PCD_IDLE); //NO action;cancel current command ??? 463 464 //write data into FIFO 465 for (i=0; i<sendLen; i++) 466 { 467 Write_MFRC522(FIFODataReg, sendData[i]); 468 } 469 470 //procceed it 471 Write_MFRC522(CommandReg, command); 472 if (command == PCD_TRANSCEIVE) 473 { 474 SetBitMask(BitFramingReg, 0x80); //StartSend=1,transmission of data starts 475 } 476 477 //waite receive data is finished 478 i = 2000; //i should adjust according the clock, the maxium the waiting time should be 25 ms??? 479 do 480 { 481 //CommIrqReg[7..0] 482 //Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq 483 n = Read_MFRC522(CommIrqReg); 484 i--; 485 } 486 while ((i!=0) && !(n&0x01) && !(n&waitIRq)); 487 488 ClearBitMask(BitFramingReg, 0x80); //StartSend=0 489 490 if (i != 0) 491 { 492 if(!(Read_MFRC522(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr 493 { 494 status = MI_OK; 495 if (n & irqEn & 0x01) 496 { 497 status = MI_NOTAGERR; //?? 498 } 499 500 if (command == PCD_TRANSCEIVE) 501 { 502 n = Read_MFRC522(FIFOLevelReg); 503 lastBits = Read_MFRC522(ControlReg) & 0x07; 504 if (lastBits) 505 { 506 *backLen = (n-1)*8 + lastBits; 507 } 508 else 509 { 510 *backLen = n*8; 511 } 512 513 if (n == 0) 514 { 515 n = 1; 516 } 517 if (n > MAX_LEN) 518 { 519 n = MAX_LEN; 520 } 521 522 //read the data from FIFO 523 for (i=0; i<n; i++) 524 { 525 backData[i] = Read_MFRC522(FIFODataReg); 526 } 527 } 528 } 529 else 530 { 531 status = MI_ERR; 532 } 533 534 } 535 536 //SetBitMask(ControlReg,0x80); //timer stops 537 //Write_MFRC522(CommandReg, PCD_IDLE); 538 539 return status; 540} 541 542 543/* 544 * FunctionMFRC522_Anticoll 545 * DescriptionPrevent conflict, read the card serial number 546 * Input parameterserNum--return the 4 bytes card serial number, the 5th byte is recheck byte 547 * returnreturn MI_OK if successed 548 */ 549uchar MFRC522_Anticoll(uchar *serNum) 550{ 551 uchar status; 552 uchar i; 553 uchar serNumCheck=0; 554 uint unLen; 555 556 //ClearBitMask(Status2Reg, 0x08); //strSensclear 557 //ClearBitMask(CollReg,0x80); //ValuesAfterColl 558 Write_MFRC522(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0] 559 560 serNum[0] = PICC_ANTICOLL; 561 serNum[1] = 0x20; 562 status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen); 563 564 if (status == MI_OK) 565 { 566 //Verify card serial number 567 for (i=0; i<4; i++) 568 { 569 serNumCheck ^= serNum[i]; 570 } 571 if (serNumCheck != serNum[i]) 572 { 573 status = MI_ERR; 574 } 575 } 576 577 //SetBitMask(CollReg, 0x80); //ValuesAfterColl=1 578 579 return status; 580} 581 582 583/* 584 * FunctionCalulateCRC 585 * DescriptionUse MF522 to caculate CRC 586 * Input parameterpIndata--the CRC data need to be readlen--data lengthpOutData-- the caculated result of CRC 587 * returnNull 588 */ 589void CalulateCRC(uchar *pIndata, uchar len, uchar *pOutData) 590{ 591 uchar i, n; 592 593 ClearBitMask(DivIrqReg, 0x04); //CRCIrq = 0 594 SetBitMask(FIFOLevelReg, 0x80); //Clear FIFO pointer 595 //Write_MFRC522(CommandReg, PCD_IDLE); 596 597 //Write data into FIFO 598 for (i=0; i<len; i++) 599 { 600 Write_MFRC522(FIFODataReg, *(pIndata+i)); 601 } 602 Write_MFRC522(CommandReg, PCD_CALCCRC); 603 604 //waite CRC caculation to finish 605 i = 0xFF; 606 do 607 { 608 n = Read_MFRC522(DivIrqReg); 609 i--; 610 } 611 while ((i!=0) && !(n&0x04)); //CRCIrq = 1 612 613 //read CRC caculation result 614 pOutData[0] = Read_MFRC522(CRCResultRegL); 615 pOutData[1] = Read_MFRC522(CRCResultRegM); 616} 617 618 619 620/* 621 * FunctionMFRC522_Write 622 * Descriptionwrite block data 623 * Input parametersblockAddr--block address;writeData--Write 16 bytes data into block 624 * returnreturn MI_OK if successed 625 */ 626uchar 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 638 if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) 639 { 640 status = MI_ERR; 641 } 642 643 if (status == MI_OK) 644 { 645 for (i=0; i<16; i++) //Write 16 bytes data into FIFO 646 { 647 buff[i] = *(writeData+i); 648 } 649 CalulateCRC(buff, 16, &buff[16]); 650 status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits); 651 652 if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) 653 { 654 status = MI_ERR; 655 } 656 } 657 658 return status; 659} 660 661 662/* 663 * FunctionMFRC522_Halt 664 * DescriptionCommand the cards into sleep mode 665 * Input parametersnull 666 * returnnull 667 */ 668void MFRC522_Halt(void) 669{ 670 uchar status; 671 uint unLen; 672 uchar buff[4]; 673 674 buff[0] = PICC_HALT; 675 buff[1] = 0; 676 CalulateCRC(buff, 2, &buff[2]); 677 678 status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff,&unLen); 679} 680 681 682
ARDUINO_CODE_AN_1400001_RFID_RC522.ino
c_cpp
1/*===================================================================================== 2ARDUINO_CODE_AN_1400001_RFID_RC522.ino 3www.inhaos.com 4 5RFID 6 RC522 Demo Code 7Rev: 1.0 8Date: 18 Mar.2014 9 10Hardware: 11 1 * BUONO 12 UNO R3 13 1 * RFID-RC522 14 1 * RF ID Card 15 16Tested Platform: 17 Arduino 18 1.5.4 19 20Connection: 21 UNO <-> RFID-RC522 22 3V3 VCC 23 24 D5 RST 25 GND GND 26 D12 MISO 27 28 D11 MOSI 29 D13 SCK 30 D10 NSS 31 32 x IRQ 33=====================================================================================*/ 34 35#include 36 <SPI.h> 37 38#define uchar unsigned char 39#define uint unsigned int 40 41//data 42 array maxium length 43#define MAX_LEN 16 44 45///////////////////////////////////////////////////////////////////// 46//set 47 the pin 48///////////////////////////////////////////////////////////////////// 49const 50 int chipSelectPin = 10; 51const int NRSTPD = 5; 52 53 54 55//MF522 command 56 bits 57#define PCD_IDLE 0x00 //NO action; cancel current commands 58#define PCD_AUTHENT 59 0x0E //verify password key 60#define PCD_RECEIVE 0x08 //receive data 61#define 62 PCD_TRANSMIT 0x04 //send data 63#define PCD_TRANSCEIVE 0x0C //send and receive 64 data 65#define PCD_RESETPHASE 0x0F //reset 66#define PCD_CALCCRC 0x03 //CRC check 67 and caculation 68 69//Mifare_One card command bits 70#define PICC_REQIDL 0x26 71 //Search the cards that not into sleep mode in the antenna area 72#define PICC_REQALL 73 0x52 //Search all the cards in the antenna area 74#define PICC_ANTICOLL 0x93 //prevent 75 conflict 76#define PICC_SElECTTAG 0x93 //select card 77#define PICC_AUTHENT1A 78 0x60 //verify A password key 79#define PICC_AUTHENT1B 0x61 //verify B password 80 key 81#define PICC_READ 0x30 //read 82#define PICC_WRITE 0xA0 //write 83#define 84 PICC_DECREMENT 0xC0 //deduct value 85#define PICC_INCREMENT 0xC1 //charge up value 86#define 87 PICC_RESTORE 0xC2 //Restore data into buffer 88#define PICC_TRANSFER 0xB0 //Save 89 data into buffer 90#define PICC_HALT 0x50 //sleep mode 91 92 93//THe mistake 94 code that return when communicate with MF522 95#define MI_OK 0 96#define MI_NOTAGERR 97 1 98#define MI_ERR 2 99 100 101//------------------MFRC522 register --------------- 102//Page 103 0:Command and Status 104#define Reserved00 0x00 105#define CommandReg 0x01 106#define 107 CommIEnReg 0x02 108#define DivlEnReg 0x03 109#define CommIrqReg 0x04 110#define 111 DivIrqReg 0x05 112#define ErrorReg 0x06 113#define Status1Reg 0x07 114#define 115 Status2Reg 0x08 116#define FIFODataReg 0x09 117#define FIFOLevelReg 0x0A 118#define 119 WaterLevelReg 0x0B 120#define ControlReg 0x0C 121#define BitFramingReg 0x0D 122#define 123 CollReg 0x0E 124#define Reserved01 0x0F 125//Page 1:Command 126#define Reserved10 127 0x10 128#define ModeReg 0x11 129#define TxModeReg 0x12 130#define RxModeReg 0x13 131#define 132 TxControlReg 0x14 133#define TxAutoReg 0x15 134#define TxSelReg 0x16 135#define 136 RxSelReg 0x17 137#define RxThresholdReg 0x18 138#define DemodReg 0x19 139#define 140 Reserved11 0x1A 141#define Reserved12 0x1B 142#define MifareReg 0x1C 143#define 144 Reserved13 0x1D 145#define Reserved14 0x1E 146#define SerialSpeedReg 0x1F 147//Page 148 2:CFG 149#define Reserved20 0x20 150#define CRCResultRegM 0x21 151#define CRCResultRegL 152 0x22 153#define Reserved21 0x23 154#define ModWidthReg 0x24 155#define Reserved22 156 0x25 157#define RFCfgReg 0x26 158#define GsNReg 0x27 159#define CWGsPReg 0x28 160#define 161 ModGsPReg 0x29 162#define TModeReg 0x2A 163#define TPrescalerReg 0x2B 164#define 165 TReloadRegH 0x2C 166#define TReloadRegL 0x2D 167#define TCounterValueRegH 0x2E 168#define 169 TCounterValueRegL 0x2F 170//Page 3:TestRegister 171#define Reserved30 0x30 172#define 173 TestSel1Reg 0x31 174#define TestSel2Reg 0x32 175#define TestPinEnReg 0x33 176#define 177 TestPinValueReg 0x34 178#define TestBusReg 0x35 179#define AutoTestReg 0x36 180#define 181 VersionReg 0x37 182#define AnalogTestReg 0x38 183#define TestDAC1Reg 0x39 184#define 185 TestDAC2Reg 0x3A 186#define TestADCReg 0x3B 187#define Reserved31 0x3C 188#define 189 Reserved32 0x3D 190#define Reserved33 0x3E 191#define Reserved34 0x3F 192//----------------------------------------------- 193 194//4 195 bytes Serial number of card, the 5 bytes is verfiy bytes 196uchar serNum[5]; 197 198 199void 200 setup() 201{ 202 Serial.begin(57600); 203 204 SPI.begin(); 205 206 pinMode(chipSelectPin,OUTPUT); 207 // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin 208 digitalWrite(chipSelectPin, 209 LOW); // Activate the RFID reader 210 pinMode(NRSTPD,OUTPUT); // Set digital pin 211 5 , Not Reset and Power-down 212 213 MFRC522_Init(); 214} 215 216 217void loop() 218{ 219 220 221 uchar status; 222 uchar str[MAX_LEN]; 223 224 225 // Search card, return card 226 types 227 status = MFRC522_Request(PICC_REQIDL, str); 228 if (status != MI_OK) 229 230 { 231 return; 232 } 233 234 235 // Show card type 236 ShowCardType(str); 237 238 239 //Prevent conflict, return the 4 bytes Serial number of the card 240 status = 241 MFRC522_Anticoll(str); 242 243 // str[0..3]: serial number of the card 244 // 245 str[4]: XOR checksum of the SN. 246 if (status == MI_OK) 247 { 248 Serial.print("The 249 card's number is: "); 250 memcpy(serNum, str, 5); 251 ShowCardID(serNum); 252 253 254 // Check people associated with card ID 255 uchar* id = serNum; 256 if( 257 id[0]==0x4B && id[1]==0xE6 && id[2]==0xD1 && id[3]==0x3B ) { 258 Serial.println("Hello 259 Mary!"); 260 } 261 else if(id[0]==0x3B && id[1]==0xE6 && id[2]==0xD1 && 262 id[3]==0x3B) { 263 Serial.println("Hello Greg!"); 264 } 265 else{ 266 267 Serial.println("Hello unkown guy!"); 268 } 269 } 270 271 272 MFRC522_Halt(); 273 //command the card into sleep mode 274 275 delay(200); 276} 277 278/* 279 * FunctionShowCardID 280 281 * DescriptionShow Card ID 282 * Input parameterID string 283 * ReturnNull 284 */ 285void 286 ShowCardID(uchar *id) 287{ 288 int IDlen=4; 289 for(int i=0; i<IDlen; i++){ 290 291 Serial.print(0x0F & (id[i]>>4), HEX); 292 Serial.print(0x0F & id[i],HEX); 293 294 } 295 Serial.println(""); 296} 297 298/* 299 * FunctionShowCardType 300 * DescriptionShow 301 Card type 302 * Input parameterType string 303 * ReturnNull 304 */ 305void ShowCardType(uchar* 306 type) 307{ 308 Serial.print("Card type: "); 309 if(type[0]==0x04&&type[1]==0x00) 310 311 Serial.println("MFOne-S50"); 312 else if(type[0]==0x02&&type[1]==0x00) 313 314 Serial.println("MFOne-S70"); 315 else if(type[0]==0x44&&type[1]==0x00) 316 317 Serial.println("MF-UltraLight"); 318 else if(type[0]==0x08&&type[1]==0x00) 319 320 Serial.println("MF-Pro"); 321 else if(type[0]==0x44&&type[1]==0x03) 322 Serial.println("MF 323 Desire"); 324 else 325 Serial.println("Unknown"); 326} 327 328/* 329 * FunctionWrite_MFRC5200 330 331 * Descriptionwrite a byte data into one register of MR RC522 332 * Input parameteraddr--register 333 addressval--the value that need to write in 334 * ReturnNull 335 */ 336void Write_MFRC522(uchar 337 addr, uchar val) 338{ 339 digitalWrite(chipSelectPin, LOW); 340 341 //address 342 format0XXXXXX0 343 SPI.transfer((addr<<1)&0x7E); 344 SPI.transfer(val); 345 346 347 digitalWrite(chipSelectPin, HIGH); 348} 349 350 351/* 352 * FunctionRead_MFRC522 353 354 * Descriptionread a byte data into one register of MR RC522 355 * Input parameteraddr--register 356 address 357 * Returnreturn the read value 358 */ 359uchar Read_MFRC522(uchar addr) 360{ 361 362 uchar val; 363 364 digitalWrite(chipSelectPin, LOW); 365 366 //address format1XXXXXX0 367 368 SPI.transfer(((addr<<1)&0x7E) | 0x80); 369 val =SPI.transfer(0x00); 370 371 372 digitalWrite(chipSelectPin, HIGH); 373 374 return val; 375} 376 377/* 378 * 379 FunctionSetBitMask 380 * Descriptionset RC522 register bit 381 * Input parameterreg--register 382 address;mask--value 383 * Returnnull 384 */ 385void SetBitMask(uchar reg, uchar 386 mask) 387{ 388 uchar tmp; 389 tmp = Read_MFRC522(reg); 390 Write_MFRC522(reg, 391 tmp | mask); // set bit mask 392} 393 394 395/* 396 * FunctionClearBitMask 397 * 398 Descriptionclear RC522 register bit 399 * Input parameterreg--register address;mask--value 400 401 * Returnnull 402 */ 403void ClearBitMask(uchar reg, uchar mask) 404{ 405 uchar 406 tmp; 407 tmp = Read_MFRC522(reg); 408 Write_MFRC522(reg, tmp & (~mask)); // clear 409 bit mask 410} 411 412 413/* 414 * FunctionAntennaOn 415 * DescriptionTurn on antenna, 416 every time turn on or shut down antenna need at least 1ms delay 417 * Input parameternull 418 419 * Returnnull 420 */ 421void AntennaOn(void) 422{ 423 uchar temp; 424 425 temp 426 = Read_MFRC522(TxControlReg); 427 if (!(temp & 0x03)) 428 { 429 SetBitMask(TxControlReg, 430 0x03); 431 } 432} 433 434 435/* 436 * FunctionAntennaOff 437 * DescriptionTurn 438 off antenna, every time turn on or shut down antenna need at least 1ms delay 439 440 * Input parameternull 441 * Returnnull 442 */ 443void AntennaOff(void) 444{ 445 446 ClearBitMask(TxControlReg, 0x03); 447} 448 449 450/* 451 * FunctionResetMFRC522 452 453 * Description reset RC522 454 * Input parameternull 455 * Returnnull 456 */ 457void 458 MFRC522_Reset(void) 459{ 460 Write_MFRC522(CommandReg, PCD_RESETPHASE); 461} 462 463 464/* 465 466 * FunctionInitMFRC522 467 * Descriptioninitilize RC522 468 * Input parameternull 469 470 * Returnnull 471 */ 472void MFRC522_Init(void) 473{ 474 digitalWrite(NRSTPD,HIGH); 475 476 477 MFRC522_Reset(); 478 479 //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms 480 Write_MFRC522(TModeReg, 481 0x8D); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler 482 Write_MFRC522(TPrescalerReg, 483 0x3E); //TModeReg[3..0] + TPrescalerReg 484 Write_MFRC522(TReloadRegL, 30); 485 486 Write_MFRC522(TReloadRegH, 0); 487 488 Write_MFRC522(TxAutoReg, 0x40); //100%ASK 489 490 Write_MFRC522(ModeReg, 0x3D); //CRC initilizate value 0x6363 ??? 491 492 //ClearBitMask(Status2Reg, 493 0x08); //MFCrypto1On=0 494 //Write_MFRC522(RxSelReg, 0x86); //RxWait = RxSelReg[5..0] 495 496 //Write_MFRC522(RFCfgReg, 0x7F); //RxGain = 48dB 497 498 AntennaOn(); //turn 499 on antenna 500} 501 502 503/* 504 * FunctionMFRC522_Request 505 * DescriptionSearching 506 card, read card type 507 * Input parameterreqMode--search methods 508 * TagType--return 509 card types 510 * 0x4400 = Mifare_UltraLight 511 * 0x0400 = Mifare_One(S50) 512 * 513 0x0200 = Mifare_One(S70) 514 * 0x0800 = Mifare_Pro(X) 515 * 0x4403 = Mifare_DESFire 516 517 * returnreturn MI_OK if successed 518 */ 519uchar MFRC522_Request(uchar reqMode, 520 uchar *TagType) 521{ 522 uchar status; 523 uint backBits; //the data bits that 524 received 525 526 Write_MFRC522(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0] 527 ??? 528 529 TagType[0] = reqMode; 530 status = MFRC522_ToCard(PCD_TRANSCEIVE, 531 TagType, 1, TagType, &backBits); 532 533 if ((status != MI_OK) || (backBits != 534 0x10)) 535 { 536 status = MI_ERR; 537 } 538 539 return status; 540} 541 542 543/* 544 545 * FunctionMFRC522_ToCard 546 * Descriptioncommunicate between RC522 and ISO14443 547 548 * Input parametercommand--MF522 command bits 549 * sendData--send data to card via 550 rc522 551 * sendLen--send data length 552 * backData--the return data from card 553 554 * backLen--the length of return data 555 * returnreturn MI_OK if successed 556 */ 557uchar 558 MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint 559 *backLen) 560{ 561 uchar status = MI_ERR; 562 uchar irqEn = 0x00; 563 uchar waitIRq 564 = 0x00; 565 uchar lastBits; 566 uchar n; 567 uint i; 568 569 switch (command) 570 571 { 572 case PCD_AUTHENT: //verify card password 573 { 574 irqEn = 0x12; 575 576 waitIRq = 0x10; 577 break; 578 } 579 case PCD_TRANSCEIVE: //send 580 data in the FIFO 581 { 582 irqEn = 0x77; 583 waitIRq = 0x30; 584 break; 585 586 } 587 default: 588 break; 589 } 590 591 Write_MFRC522(CommIEnReg, irqEn|0x80); 592 //Allow interruption 593 ClearBitMask(CommIrqReg, 0x80); //Clear all the interrupt 594 bits 595 SetBitMask(FIFOLevelReg, 0x80); //FlushBuffer=1, FIFO initilizate 596 597 598 Write_MFRC522(CommandReg, PCD_IDLE); //NO action;cancel current command ??? 599 600 601 //write data into FIFO 602 for (i=0; i<sendLen; i++) 603 { 604 Write_MFRC522(FIFODataReg, 605 sendData[i]); 606 } 607 608 //procceed it 609 Write_MFRC522(CommandReg, command); 610 611 if (command == PCD_TRANSCEIVE) 612 { 613 SetBitMask(BitFramingReg, 0x80); 614 //StartSend=1,transmission of data starts 615 } 616 617 //waite receive data 618 is finished 619 i = 2000; //i should adjust according the clock, the maxium the 620 waiting time should be 25 ms??? 621 do 622 { 623 //CommIrqReg[7..0] 624 //Set1 625 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq 626 n = Read_MFRC522(CommIrqReg); 627 628 i--; 629 } 630 while ((i!=0) && !(n&0x01) && !(n&waitIRq)); 631 632 ClearBitMask(BitFramingReg, 633 0x80); //StartSend=0 634 635 if (i != 0) 636 { 637 if(!(Read_MFRC522(ErrorReg) 638 & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr 639 { 640 status = MI_OK; 641 642 if (n & irqEn & 0x01) 643 { 644 status = MI_NOTAGERR; //?? 645 646 } 647 648 if (command == PCD_TRANSCEIVE) 649 { 650 n = Read_MFRC522(FIFOLevelReg); 651 652 lastBits = Read_MFRC522(ControlReg) & 0x07; 653 if (lastBits) 654 655 { 656 *backLen = (n-1)*8 + lastBits; 657 } 658 else 659 660 { 661 *backLen = n*8; 662 } 663 664 if (n == 0) 665 666 { 667 n = 1; 668 } 669 if (n > MAX_LEN) 670 { 671 672 n = MAX_LEN; 673 } 674 675 //read the data from FIFO 676 677 for (i=0; i<n; i++) 678 { 679 backData[i] = Read_MFRC522(FIFODataReg); 680 681 } 682 } 683 } 684 else 685 { 686 status = MI_ERR; 687 688 } 689 690 } 691 692 //SetBitMask(ControlReg,0x80); //timer stops 693 //Write_MFRC522(CommandReg, 694 PCD_IDLE); 695 696 return status; 697} 698 699 700/* 701 * FunctionMFRC522_Anticoll 702 703 * DescriptionPrevent conflict, read the card serial number 704 * Input parameterserNum--return 705 the 4 bytes card serial number, the 5th byte is recheck byte 706 * returnreturn 707 MI_OK if successed 708 */ 709uchar MFRC522_Anticoll(uchar *serNum) 710{ 711 uchar 712 status; 713 uchar i; 714 uchar serNumCheck=0; 715 uint unLen; 716 717 //ClearBitMask(Status2Reg, 718 0x08); //strSensclear 719 //ClearBitMask(CollReg,0x80); //ValuesAfterColl 720 Write_MFRC522(BitFramingReg, 721 0x00); //TxLastBists = BitFramingReg[2..0] 722 723 serNum[0] = PICC_ANTICOLL; 724 725 serNum[1] = 0x20; 726 status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, 727 &unLen); 728 729 if (status == MI_OK) 730 { 731 //Verify card serial number 732 733 for (i=0; i<4; i++) 734 { 735 serNumCheck ^= serNum[i]; 736 } 737 738 if (serNumCheck != serNum[i]) 739 { 740 status = MI_ERR; 741 } 742 743 } 744 745 //SetBitMask(CollReg, 0x80); //ValuesAfterColl=1 746 747 return status; 748} 749 750 751 752/* 753 * FunctionCalulateCRC 754 * DescriptionUse MF522 to caculate 755 CRC 756 * Input parameterpIndata--the CRC data need to be readlen--data lengthpOutData-- 757 the caculated result of CRC 758 * returnNull 759 */ 760void CalulateCRC(uchar *pIndata, 761 uchar len, uchar *pOutData) 762{ 763 uchar i, n; 764 765 ClearBitMask(DivIrqReg, 766 0x04); //CRCIrq = 0 767 SetBitMask(FIFOLevelReg, 0x80); //Clear FIFO pointer 768 769 //Write_MFRC522(CommandReg, PCD_IDLE); 770 771 //Write data into FIFO 772 for 773 (i=0; i<len; i++) 774 { 775 Write_MFRC522(FIFODataReg, *(pIndata+i)); 776 777 } 778 Write_MFRC522(CommandReg, PCD_CALCCRC); 779 780 //waite CRC caculation 781 to finish 782 i = 0xFF; 783 do 784 { 785 n = Read_MFRC522(DivIrqReg); 786 787 i--; 788 } 789 while ((i!=0) && !(n&0x04)); //CRCIrq = 1 790 791 //read CRC 792 caculation result 793 pOutData[0] = Read_MFRC522(CRCResultRegL); 794 pOutData[1] 795 = Read_MFRC522(CRCResultRegM); 796} 797 798 799 800/* 801 * FunctionMFRC522_Write 802 803 * Descriptionwrite block data 804 * Input parametersblockAddr--block address;writeData--Write 805 16 bytes data into block 806 * returnreturn MI_OK if successed 807 */ 808uchar MFRC522_Write(uchar 809 blockAddr, uchar *writeData) 810{ 811 uchar status; 812 uint recvBits; 813 uchar 814 i; 815 uchar buff[18]; 816 817 buff[0] = PICC_WRITE; 818 buff[1] = blockAddr; 819 820 CalulateCRC(buff, 2, &buff[2]); 821 status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 822 4, buff, &recvBits); 823 824 if ((status != MI_OK) || (recvBits != 4) || ((buff[0] 825 & 0x0F) != 0x0A)) 826 { 827 status = MI_ERR; 828 } 829 830 if (status == 831 MI_OK) 832 { 833 for (i=0; i<16; i++) //Write 16 bytes data into FIFO 834 { 835 836 buff[i] = *(writeData+i); 837 } 838 CalulateCRC(buff, 16, &buff[16]); 839 840 status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits); 841 842 843 if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) 844 845 { 846 status = MI_ERR; 847 } 848 } 849 850 return status; 851} 852 853 854/* 855 856 * FunctionMFRC522_Halt 857 * DescriptionCommand the cards into sleep mode 858 * 859 Input parametersnull 860 * returnnull 861 */ 862void MFRC522_Halt(void) 863{ 864 865 uchar status; 866 uint unLen; 867 uchar buff[4]; 868 869 buff[0] = PICC_HALT; 870 871 buff[1] = 0; 872 CalulateCRC(buff, 2, &buff[2]); 873 874 status = MFRC522_ToCard(PCD_TRANSCEIVE, 875 buff, 4, buff,&unLen); 876} 877 878 879
ARDUINO_CODE_AN_1400001_RFID_RC522.ino
c_cpp
1/*===================================================================================== 2ARDUINO_CODE_AN_1400001_RFID_RC522.ino 3www.inhaos.com 4 5RFID RC522 Demo Code 6Rev: 1.0 7Date: 18 Mar.2014 8 9Hardware: 10 1 * BUONO UNO R3 11 1 * RFID-RC522 12 1 * RF ID Card 13 14Tested Platform: 15 Arduino 1.5.4 16 17Connection: 18 UNO <-> RFID-RC522 19 3V3 VCC 20 D5 RST 21 GND GND 22 D12 MISO 23 D11 MOSI 24 D13 SCK 25 D10 NSS 26 x IRQ 27=====================================================================================*/ 28 29#include <SPI.h> 30 31#define uchar unsigned char 32#define uint unsigned int 33 34//data array maxium length 35#define MAX_LEN 16 36 37///////////////////////////////////////////////////////////////////// 38//set the pin 39///////////////////////////////////////////////////////////////////// 40const int chipSelectPin = 10; 41const int NRSTPD = 5; 42 43 44 45//MF522 command bits 46#define PCD_IDLE 0x00 //NO action; cancel current commands 47#define PCD_AUTHENT 0x0E //verify password key 48#define PCD_RECEIVE 0x08 //receive data 49#define PCD_TRANSMIT 0x04 //send data 50#define PCD_TRANSCEIVE 0x0C //send and receive data 51#define PCD_RESETPHASE 0x0F //reset 52#define PCD_CALCCRC 0x03 //CRC check and caculation 53 54//Mifare_One card command bits 55#define PICC_REQIDL 0x26 //Search the cards that not into sleep mode in the antenna area 56#define PICC_REQALL 0x52 //Search all the cards in the antenna area 57#define PICC_ANTICOLL 0x93 //prevent conflict 58#define PICC_SElECTTAG 0x93 //select card 59#define PICC_AUTHENT1A 0x60 //verify A password key 60#define PICC_AUTHENT1B 0x61 //verify B password key 61#define PICC_READ 0x30 //read 62#define PICC_WRITE 0xA0 //write 63#define PICC_DECREMENT 0xC0 //deduct value 64#define PICC_INCREMENT 0xC1 //charge up value 65#define PICC_RESTORE 0xC2 //Restore data into buffer 66#define PICC_TRANSFER 0xB0 //Save data into buffer 67#define PICC_HALT 0x50 //sleep mode 68 69 70//THe mistake code that return when communicate with MF522 71#define MI_OK 0 72#define MI_NOTAGERR 1 73#define MI_ERR 2 74 75 76//------------------MFRC522 register --------------- 77//Page 0:Command and Status 78#define Reserved00 0x00 79#define CommandReg 0x01 80#define CommIEnReg 0x02 81#define DivlEnReg 0x03 82#define CommIrqReg 0x04 83#define DivIrqReg 0x05 84#define ErrorReg 0x06 85#define Status1Reg 0x07 86#define Status2Reg 0x08 87#define FIFODataReg 0x09 88#define FIFOLevelReg 0x0A 89#define WaterLevelReg 0x0B 90#define ControlReg 0x0C 91#define BitFramingReg 0x0D 92#define CollReg 0x0E 93#define Reserved01 0x0F 94//Page 1:Command 95#define Reserved10 0x10 96#define ModeReg 0x11 97#define TxModeReg 0x12 98#define RxModeReg 0x13 99#define TxControlReg 0x14 100#define TxAutoReg 0x15 101#define TxSelReg 0x16 102#define RxSelReg 0x17 103#define RxThresholdReg 0x18 104#define DemodReg 0x19 105#define Reserved11 0x1A 106#define Reserved12 0x1B 107#define MifareReg 0x1C 108#define Reserved13 0x1D 109#define Reserved14 0x1E 110#define SerialSpeedReg 0x1F 111//Page 2:CFG 112#define Reserved20 0x20 113#define CRCResultRegM 0x21 114#define CRCResultRegL 0x22 115#define Reserved21 0x23 116#define ModWidthReg 0x24 117#define Reserved22 0x25 118#define RFCfgReg 0x26 119#define GsNReg 0x27 120#define CWGsPReg 0x28 121#define ModGsPReg 0x29 122#define TModeReg 0x2A 123#define TPrescalerReg 0x2B 124#define TReloadRegH 0x2C 125#define TReloadRegL 0x2D 126#define TCounterValueRegH 0x2E 127#define TCounterValueRegL 0x2F 128//Page 3:TestRegister 129#define Reserved30 0x30 130#define TestSel1Reg 0x31 131#define TestSel2Reg 0x32 132#define TestPinEnReg 0x33 133#define TestPinValueReg 0x34 134#define TestBusReg 0x35 135#define AutoTestReg 0x36 136#define VersionReg 0x37 137#define AnalogTestReg 0x38 138#define TestDAC1Reg 0x39 139#define TestDAC2Reg 0x3A 140#define TestADCReg 0x3B 141#define Reserved31 0x3C 142#define Reserved32 0x3D 143#define Reserved33 0x3E 144#define Reserved34 0x3F 145//----------------------------------------------- 146 147//4 bytes Serial number of card, the 5 bytes is verfiy bytes 148uchar serNum[5]; 149 150 151void setup() 152{ 153 Serial.begin(57600); 154 155 SPI.begin(); 156 157 pinMode(chipSelectPin,OUTPUT); // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin 158 digitalWrite(chipSelectPin, LOW); // Activate the RFID reader 159 pinMode(NRSTPD,OUTPUT); // Set digital pin 5 , Not Reset and Power-down 160 161 MFRC522_Init(); 162} 163 164 165void loop() 166{ 167 168 uchar status; 169 uchar str[MAX_LEN]; 170 171 172 // Search card, return card types 173 status = MFRC522_Request(PICC_REQIDL, str); 174 if (status != MI_OK) 175 { 176 return; 177 } 178 179 180 // Show card type 181 ShowCardType(str); 182 183 //Prevent conflict, return the 4 bytes Serial number of the card 184 status = MFRC522_Anticoll(str); 185 186 // str[0..3]: serial number of the card 187 // str[4]: XOR checksum of the SN. 188 if (status == MI_OK) 189 { 190 Serial.print("The card's number is: "); 191 memcpy(serNum, str, 5); 192 ShowCardID(serNum); 193 194 // Check people associated with card ID 195 uchar* id = serNum; 196 if( id[0]==0x4B && id[1]==0xE6 && id[2]==0xD1 && id[3]==0x3B ) { 197 Serial.println("Hello Mary!"); 198 } 199 else if(id[0]==0x3B && id[1]==0xE6 && id[2]==0xD1 && id[3]==0x3B) { 200 Serial.println("Hello Greg!"); 201 } 202 else{ 203 Serial.println("Hello unkown guy!"); 204 } 205 } 206 207 208 MFRC522_Halt(); //command the card into sleep mode 209 210 delay(200); 211} 212 213/* 214 * FunctionShowCardID 215 * DescriptionShow Card ID 216 * Input parameterID string 217 * ReturnNull 218 */ 219void ShowCardID(uchar *id) 220{ 221 int IDlen=4; 222 for(int i=0; i<IDlen; i++){ 223 Serial.print(0x0F & (id[i]>>4), HEX); 224 Serial.print(0x0F & id[i],HEX); 225 } 226 Serial.println(""); 227} 228 229/* 230 * FunctionShowCardType 231 * DescriptionShow Card type 232 * Input parameterType string 233 * ReturnNull 234 */ 235void ShowCardType(uchar* type) 236{ 237 Serial.print("Card type: "); 238 if(type[0]==0x04&&type[1]==0x00) 239 Serial.println("MFOne-S50"); 240 else if(type[0]==0x02&&type[1]==0x00) 241 Serial.println("MFOne-S70"); 242 else if(type[0]==0x44&&type[1]==0x00) 243 Serial.println("MF-UltraLight"); 244 else if(type[0]==0x08&&type[1]==0x00) 245 Serial.println("MF-Pro"); 246 else if(type[0]==0x44&&type[1]==0x03) 247 Serial.println("MF Desire"); 248 else 249 Serial.println("Unknown"); 250} 251 252/* 253 * FunctionWrite_MFRC5200 254 * Descriptionwrite a byte data into one register of MR RC522 255 * Input parameteraddr--register addressval--the value that need to write in 256 * ReturnNull 257 */ 258void Write_MFRC522(uchar addr, uchar val) 259{ 260 digitalWrite(chipSelectPin, LOW); 261 262 //address format0XXXXXX0 263 SPI.transfer((addr<<1)&0x7E); 264 SPI.transfer(val); 265 266 digitalWrite(chipSelectPin, HIGH); 267} 268 269 270/* 271 * FunctionRead_MFRC522 272 * Descriptionread a byte data into one register of MR RC522 273 * Input parameteraddr--register address 274 * Returnreturn the read value 275 */ 276uchar Read_MFRC522(uchar addr) 277{ 278 uchar val; 279 280 digitalWrite(chipSelectPin, LOW); 281 282 //address format1XXXXXX0 283 SPI.transfer(((addr<<1)&0x7E) | 0x80); 284 val =SPI.transfer(0x00); 285 286 digitalWrite(chipSelectPin, HIGH); 287 288 return val; 289} 290 291/* 292 * FunctionSetBitMask 293 * Descriptionset RC522 register bit 294 * Input parameterreg--register address;mask--value 295 * Returnnull 296 */ 297void SetBitMask(uchar reg, uchar mask) 298{ 299 uchar tmp; 300 tmp = Read_MFRC522(reg); 301 Write_MFRC522(reg, tmp | mask); // set bit mask 302} 303 304 305/* 306 * FunctionClearBitMask 307 * Descriptionclear RC522 register bit 308 * Input parameterreg--register address;mask--value 309 * Returnnull 310 */ 311void ClearBitMask(uchar reg, uchar mask) 312{ 313 uchar tmp; 314 tmp = Read_MFRC522(reg); 315 Write_MFRC522(reg, tmp & (~mask)); // clear bit mask 316} 317 318 319/* 320 * FunctionAntennaOn 321 * DescriptionTurn on antenna, every time turn on or shut down antenna need at least 1ms delay 322 * Input parameternull 323 * Returnnull 324 */ 325void AntennaOn(void) 326{ 327 uchar temp; 328 329 temp = Read_MFRC522(TxControlReg); 330 if (!(temp & 0x03)) 331 { 332 SetBitMask(TxControlReg, 0x03); 333 } 334} 335 336 337/* 338 * FunctionAntennaOff 339 * DescriptionTurn off antenna, every time turn on or shut down antenna need at least 1ms delay 340 * Input parameternull 341 * Returnnull 342 */ 343void AntennaOff(void) 344{ 345 ClearBitMask(TxControlReg, 0x03); 346} 347 348 349/* 350 * FunctionResetMFRC522 351 * Description reset RC522 352 * Input parameternull 353 * Returnnull 354 */ 355void MFRC522_Reset(void) 356{ 357 Write_MFRC522(CommandReg, PCD_RESETPHASE); 358} 359 360 361/* 362 * FunctionInitMFRC522 363 * Descriptioninitilize RC522 364 * Input parameternull 365 * Returnnull 366 */ 367void MFRC522_Init(void) 368{ 369 digitalWrite(NRSTPD,HIGH); 370 371 MFRC522_Reset(); 372 373 //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms 374 Write_MFRC522(TModeReg, 0x8D); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler 375 Write_MFRC522(TPrescalerReg, 0x3E); //TModeReg[3..0] + TPrescalerReg 376 Write_MFRC522(TReloadRegL, 30); 377 Write_MFRC522(TReloadRegH, 0); 378 379 Write_MFRC522(TxAutoReg, 0x40); //100%ASK 380 Write_MFRC522(ModeReg, 0x3D); //CRC initilizate value 0x6363 ??? 381 382 //ClearBitMask(Status2Reg, 0x08); //MFCrypto1On=0 383 //Write_MFRC522(RxSelReg, 0x86); //RxWait = RxSelReg[5..0] 384 //Write_MFRC522(RFCfgReg, 0x7F); //RxGain = 48dB 385 386 AntennaOn(); //turn on antenna 387} 388 389 390/* 391 * FunctionMFRC522_Request 392 * DescriptionSearching card, read card type 393 * Input parameterreqMode--search methods 394 * TagType--return card types 395 * 0x4400 = Mifare_UltraLight 396 * 0x0400 = Mifare_One(S50) 397 * 0x0200 = Mifare_One(S70) 398 * 0x0800 = Mifare_Pro(X) 399 * 0x4403 = Mifare_DESFire 400 * returnreturn MI_OK if successed 401 */ 402uchar MFRC522_Request(uchar reqMode, uchar *TagType) 403{ 404 uchar status; 405 uint backBits; //the data bits that received 406 407 Write_MFRC522(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0] ??? 408 409 TagType[0] = reqMode; 410 status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits); 411 412 if ((status != MI_OK) || (backBits != 0x10)) 413 { 414 status = MI_ERR; 415 } 416 417 return status; 418} 419 420 421/* 422 * FunctionMFRC522_ToCard 423 * Descriptioncommunicate between RC522 and ISO14443 424 * Input parametercommand--MF522 command bits 425 * sendData--send data to card via rc522 426 * sendLen--send data length 427 * backData--the return data from card 428 * backLen--the length of return data 429 * returnreturn MI_OK if successed 430 */ 431uchar MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen) 432{ 433 uchar status = MI_ERR; 434 uchar irqEn = 0x00; 435 uchar waitIRq = 0x00; 436 uchar lastBits; 437 uchar n; 438 uint i; 439 440 switch (command) 441 { 442 case PCD_AUTHENT: //verify card password 443 { 444 irqEn = 0x12; 445 waitIRq = 0x10; 446 break; 447 } 448 case PCD_TRANSCEIVE: //send data in the FIFO 449 { 450 irqEn = 0x77; 451 waitIRq = 0x30; 452 break; 453 } 454 default: 455 break; 456 } 457 458 Write_MFRC522(CommIEnReg, irqEn|0x80); //Allow interruption 459 ClearBitMask(CommIrqReg, 0x80); //Clear all the interrupt bits 460 SetBitMask(FIFOLevelReg, 0x80); //FlushBuffer=1, FIFO initilizate 461 462 Write_MFRC522(CommandReg, PCD_IDLE); //NO action;cancel current command ??? 463 464 //write data into FIFO 465 for (i=0; i<sendLen; i++) 466 { 467 Write_MFRC522(FIFODataReg, sendData[i]); 468 } 469 470 //procceed it 471 Write_MFRC522(CommandReg, command); 472 if (command == PCD_TRANSCEIVE) 473 { 474 SetBitMask(BitFramingReg, 0x80); //StartSend=1,transmission of data starts 475 } 476 477 //waite receive data is finished 478 i = 2000; //i should adjust according the clock, the maxium the waiting time should be 25 ms??? 479 do 480 { 481 //CommIrqReg[7..0] 482 //Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq 483 n = Read_MFRC522(CommIrqReg); 484 i--; 485 } 486 while ((i!=0) && !(n&0x01) && !(n&waitIRq)); 487 488 ClearBitMask(BitFramingReg, 0x80); //StartSend=0 489 490 if (i != 0) 491 { 492 if(!(Read_MFRC522(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr 493 { 494 status = MI_OK; 495 if (n & irqEn & 0x01) 496 { 497 status = MI_NOTAGERR; //?? 498 } 499 500 if (command == PCD_TRANSCEIVE) 501 { 502 n = Read_MFRC522(FIFOLevelReg); 503 lastBits = Read_MFRC522(ControlReg) & 0x07; 504 if (lastBits) 505 { 506 *backLen = (n-1)*8 + lastBits; 507 } 508 else 509 { 510 *backLen = n*8; 511 } 512 513 if (n == 0) 514 { 515 n = 1; 516 } 517 if (n > MAX_LEN) 518 { 519 n = MAX_LEN; 520 } 521 522 //read the data from FIFO 523 for (i=0; i<n; i++) 524 { 525 backData[i] = Read_MFRC522(FIFODataReg); 526 } 527 } 528 } 529 else 530 { 531 status = MI_ERR; 532 } 533 534 } 535 536 //SetBitMask(ControlReg,0x80); //timer stops 537 //Write_MFRC522(CommandReg, PCD_IDLE); 538 539 return status; 540} 541 542 543/* 544 * FunctionMFRC522_Anticoll 545 * DescriptionPrevent conflict, read the card serial number 546 * Input parameterserNum--return the 4 bytes card serial number, the 5th byte is recheck byte 547 * returnreturn MI_OK if successed 548 */ 549uchar MFRC522_Anticoll(uchar *serNum) 550{ 551 uchar status; 552 uchar i; 553 uchar serNumCheck=0; 554 uint unLen; 555 556 //ClearBitMask(Status2Reg, 0x08); //strSensclear 557 //ClearBitMask(CollReg,0x80); //ValuesAfterColl 558 Write_MFRC522(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0] 559 560 serNum[0] = PICC_ANTICOLL; 561 serNum[1] = 0x20; 562 status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen); 563 564 if (status == MI_OK) 565 { 566 //Verify card serial number 567 for (i=0; i<4; i++) 568 { 569 serNumCheck ^= serNum[i]; 570 } 571 if (serNumCheck != serNum[i]) 572 { 573 status = MI_ERR; 574 } 575 } 576 577 //SetBitMask(CollReg, 0x80); //ValuesAfterColl=1 578 579 return status; 580} 581 582 583/* 584 * FunctionCalulateCRC 585 * DescriptionUse MF522 to caculate CRC 586 * Input parameterpIndata--the CRC data need to be readlen--data lengthpOutData-- the caculated result of CRC 587 * returnNull 588 */ 589void CalulateCRC(uchar *pIndata, uchar len, uchar *pOutData) 590{ 591 uchar i, n; 592 593 ClearBitMask(DivIrqReg, 0x04); //CRCIrq = 0 594 SetBitMask(FIFOLevelReg, 0x80); //Clear FIFO pointer 595 //Write_MFRC522(CommandReg, PCD_IDLE); 596 597 //Write data into FIFO 598 for (i=0; i<len; i++) 599 { 600 Write_MFRC522(FIFODataReg, *(pIndata+i)); 601 } 602 Write_MFRC522(CommandReg, PCD_CALCCRC); 603 604 //waite CRC caculation to finish 605 i = 0xFF; 606 do 607 { 608 n = Read_MFRC522(DivIrqReg); 609 i--; 610 } 611 while ((i!=0) && !(n&0x04)); //CRCIrq = 1 612 613 //read CRC caculation result 614 pOutData[0] = Read_MFRC522(CRCResultRegL); 615 pOutData[1] = Read_MFRC522(CRCResultRegM); 616} 617 618 619 620/* 621 * FunctionMFRC522_Write 622 * Descriptionwrite block data 623 * Input parametersblockAddr--block address;writeData--Write 16 bytes data into block 624 * returnreturn MI_OK if successed 625 */ 626uchar 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 638 if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) 639 { 640 status = MI_ERR; 641 } 642 643 if (status == MI_OK) 644 { 645 for (i=0; i<16; i++) //Write 16 bytes data into FIFO 646 { 647 buff[i] = *(writeData+i); 648 } 649 CalulateCRC(buff, 16, &buff[16]); 650 status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits); 651 652 if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) 653 { 654 status = MI_ERR; 655 } 656 } 657 658 return status; 659} 660 661 662/* 663 * FunctionMFRC522_Halt 664 * DescriptionCommand the cards into sleep mode 665 * Input parametersnull 666 * returnnull 667 */ 668void MFRC522_Halt(void) 669{ 670 uchar status; 671 uint unLen; 672 uchar buff[4]; 673 674 buff[0] = PICC_HALT; 675 buff[1] = 0; 676 CalulateCRC(buff, 2, &buff[2]); 677 678 status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff,&unLen); 679} 680 681 682
Downloadable files
code
BUONO UNO R3 and REID RC522 code
code
Comments
Only logged in users can leave comments