Chinaunix首页 | 论坛 | 博客
  • 博客访问: 308245
  • 博文数量: 27
  • 博客积分: 758
  • 博客等级: 军士长
  • 技术积分: 369
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-08 23:10
文章分类

全部博文(27)

文章存档

2014年(1)

2012年(26)

我的朋友

分类: 嵌入式

2012-12-20 00:12:10

最重要的是通信方式和连接方式。Arduino板子与RC522之间是SPI通信,Arduino工作在主模式下,
RC522工作在从模式下。连接方式如下:

               Arduino                                       RC522 (工作电压3.3V)
  • D5                   <------------->             RST    (这个脚不接貌似也可以)
  • D10                 <------------->             SDA   (在RC522中即为CS)
  • D11                 <------------->             MOSI
  • D12                 <------------->             MISO
  • D13                 <------------->             SCK


代码如下:


  1. #include <SPI.h>

  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. //data array maxium length
  5. #define MAX_LEN 16

  6. /////////////////////////////////////////////////////////////////////
  7. //set the pin
  8. /////////////////////////////////////////////////////////////////////
  9. const int chipSelectPin = 10;
  10. const int NRSTPD = 5;



  11. //MF522 command bits
  12. #define PCD_IDLE 0x00 //NO action; cancel current commands
  13. #define PCD_AUTHENT 0x0E //verify password key
  14. #define PCD_RECEIVE 0x08 //receive data
  15. #define PCD_TRANSMIT 0x04 //send data
  16. #define PCD_TRANSCEIVE 0x0C //send and receive data
  17. #define PCD_RESETPHASE 0x0F //reset
  18. #define PCD_CALCCRC 0x03 //CRC check and caculation

  19. //Mifare_One card command bits
  20. #define PICC_REQIDL 0x26 //Search the cards that not into sleep mode in the antenna area
  21. #define PICC_REQALL 0x52 //Search all the cards in the antenna area
  22. #define PICC_ANTICOLL 0x93 //prevent conflict
  23. #define PICC_SElECTTAG 0x93 //select card
  24. #define PICC_AUTHENT1A 0x60 //verify A password key
  25. #define PICC_AUTHENT1B 0x61 //verify B password key
  26. #define PICC_READ 0x30 //read
  27. #define PICC_WRITE 0xA0 //write
  28. #define PICC_DECREMENT 0xC0 //deduct value
  29. #define PICC_INCREMENT 0xC1 //charge up value
  30. #define PICC_RESTORE 0xC2 //Restore data into buffer
  31. #define PICC_TRANSFER 0xB0 //Save data into buffer
  32. #define PICC_HALT 0x50 //sleep mode


  33. //THe mistake code that return when communicate with MF522
  34. #define MI_OK 0
  35. #define MI_NOTAGERR 1
  36. #define MI_ERR 2


  37. //------------------MFRC522 register ---------------
  38. //Page 0:Command and Status
  39. #define Reserved00 0x00
  40. #define CommandReg 0x01
  41. #define CommIEnReg 0x02
  42. #define DivlEnReg 0x03
  43. #define CommIrqReg 0x04
  44. #define DivIrqReg 0x05
  45. #define ErrorReg 0x06
  46. #define Status1Reg 0x07
  47. #define Status2Reg 0x08
  48. #define FIFODataReg 0x09
  49. #define FIFOLevelReg 0x0A
  50. #define WaterLevelReg 0x0B
  51. #define ControlReg 0x0C
  52. #define BitFramingReg 0x0D
  53. #define CollReg 0x0E
  54. #define Reserved01 0x0F
  55. //Page 1:Command
  56. #define Reserved10 0x10
  57. #define ModeReg 0x11
  58. #define TxModeReg 0x12
  59. #define RxModeReg 0x13
  60. #define TxControlReg 0x14
  61. #define TxAutoReg 0x15
  62. #define TxSelReg 0x16
  63. #define RxSelReg 0x17
  64. #define RxThresholdReg 0x18
  65. #define DemodReg 0x19
  66. #define Reserved11 0x1A
  67. #define Reserved12 0x1B
  68. #define MifareReg 0x1C
  69. #define Reserved13 0x1D
  70. #define Reserved14 0x1E
  71. #define SerialSpeedReg 0x1F
  72. //Page 2:CFG
  73. #define Reserved20 0x20
  74. #define CRCResultRegM 0x21
  75. #define CRCResultRegL 0x22
  76. #define Reserved21 0x23
  77. #define ModWidthReg 0x24
  78. #define Reserved22 0x25
  79. #define RFCfgReg 0x26
  80. #define GsNReg 0x27
  81. #define CWGsPReg 0x28
  82. #define ModGsPReg 0x29
  83. #define TModeReg 0x2A
  84. #define TPrescalerReg 0x2B
  85. #define TReloadRegH 0x2C
  86. #define TReloadRegL 0x2D
  87. #define TCounterValueRegH 0x2E
  88. #define TCounterValueRegL 0x2F
  89. //Page 3:TestRegister
  90. #define Reserved30 0x30
  91. #define TestSel1Reg 0x31
  92. #define TestSel2Reg 0x32
  93. #define TestPinEnReg 0x33
  94. #define TestPinValueReg 0x34
  95. #define TestBusReg 0x35
  96. #define AutoTestReg 0x36
  97. #define VersionReg 0x37
  98. #define AnalogTestReg 0x38
  99. #define TestDAC1Reg 0x39
  100. #define TestDAC2Reg 0x3A
  101. #define TestADCReg 0x3B
  102. #define Reserved31 0x3C
  103. #define Reserved32 0x3D
  104. #define Reserved33 0x3E
  105. #define Reserved34 0x3F
  106. //-----------------------------------------------

  107. //4 bytes Serial number of card, the 5 bytes is verfiy bytes
  108. uchar serNum[5];


  109. void setup()
  110. {
  111.     Serial.begin(57600);
  112.     
  113.     SPI.begin();
  114.     
  115.     pinMode(chipSelectPin,OUTPUT); // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin
  116.     digitalWrite(chipSelectPin, LOW); // Activate the RFID reader
  117.     pinMode(NRSTPD,OUTPUT); // Set digital pin 5 , Not Reset and Power-down
  118.     
  119.     MFRC522_Init();
  120. }


  121. void loop()
  122. {

  123.     uchar status;
  124.     uchar str[MAX_LEN];

  125.     
  126.     // Search card, return card types
  127.     status = MFRC522_Request(PICC_REQIDL, str);
  128.     if (status != MI_OK)
  129.     {
  130.         return;
  131.     }
  132.     
  133.     
  134.     // Show card type
  135.     ShowCardType(str);
  136.     
  137.     //Prevent conflict, return the 4 bytes Serial number of the card
  138.     status = MFRC522_Anticoll(str);
  139.     
  140.     // str[0..3]: serial number of the card
  141.     // str[4]: XOR checksum of the SN.
  142.     if (status == MI_OK)
  143.     {
  144.         Serial.print("The card's number is: ");
  145.         memcpy(serNum, str, 5);
  146.         ShowCardID(serNum);
  147.     
  148.         // Check people associated with card ID
  149.         uchar* id = serNum;
  150.         if( id[0]==0x4B && id[1]==0xE6 && id[2]==0xD1 && id[3]==0x3B ) {
  151.             Serial.println("Hello Mary!");
  152.         } else if(id[0]==0x3B && id[1]==0xE6 && id[2]==0xD1 && id[3]==0x3B) {
  153.             Serial.println("Hello Greg!");
  154.         }else{
  155.             Serial.println("Hello unkown guy!");
  156.         }
  157.     }

  158.    
  159.     MFRC522_Halt(); //command the card into sleep mode

  160.     delay(200);
  161. }

  162. /*
  163.  * Function:ShowCardID
  164.  * Description:Show Card ID
  165.  * Input parameter:ID string
  166.  * Return:Null
  167.  */
  168. void ShowCardID(uchar *id)
  169. {
  170.     int IDlen=4;
  171.     for(int i=0; i<IDlen; i++){
  172.         Serial.print(0x0F & (id[i]>>4), HEX);
  173.         Serial.print(0x0F & id[i],HEX);
  174.     }
  175.     Serial.println("");
  176. }

  177. /*
  178.  * Function:ShowCardType
  179.  * Description:Show Card type
  180.  * Input parameter:Type string
  181.  * Return:Null
  182.  */
  183. void ShowCardType(uchar* type)
  184. {
  185.     Serial.print("Card type: ");
  186.     if(type[0]==0x04&&type[1]==0x00)
  187.         Serial.println("MFOne-S50");
  188.     else if(type[0]==0x02&&type[1]==0x00)
  189.         Serial.println("MFOne-S70");
  190.     else if(type[0]==0x44&&type[1]==0x00)
  191.         Serial.println("MF-UltraLight");
  192.     else if(type[0]==0x08&&type[1]==0x00)
  193.         Serial.println("MF-Pro");
  194.     else if(type[0]==0x44&&type[1]==0x03)
  195.         Serial.println("MF Desire");
  196.     else
  197.         Serial.println("Unknown");
  198. }

  199. /*
  200.  * Function:Write_MFRC5200
  201.  * Description:write a byte data into one register of MR RC522
  202.  * Input parameter:addr--register address;val--the value that need to write in
  203.  * Return:Null
  204.  */
  205. void Write_MFRC522(uchar addr, uchar val)
  206. {
  207.     digitalWrite(chipSelectPin, LOW);

  208.     //address format:0XXXXXX0
  209.     SPI.transfer((addr<<1)&0x7E);
  210.     SPI.transfer(val);
  211.     
  212.     digitalWrite(chipSelectPin, HIGH);
  213. }


  214. /*
  215.  * Function:Read_MFRC522
  216.  * Description:read a byte data into one register of MR RC522
  217.  * Input parameter:addr--register address
  218.  * Return:return the read value
  219.  */
  220. uchar Read_MFRC522(uchar addr)
  221. {
  222.     uchar val;

  223.     digitalWrite(chipSelectPin, LOW);

  224.     //address format:1XXXXXX0
  225.     SPI.transfer(((addr<<1)&0x7E) | 0x80);
  226.     val =SPI.transfer(0x00);
  227.     
  228.     digitalWrite(chipSelectPin, HIGH);
  229.     
  230.     return val;
  231. }

  232. /*
  233.  * Function:SetBitMask
  234.  * Description:set RC522 register bit
  235.  * Input parameter:reg--register address;mask--value
  236.  * Return:null
  237.  */
  238. void SetBitMask(uchar reg, uchar mask)
  239. {
  240.     uchar tmp;
  241.     tmp = Read_MFRC522(reg);
  242.     Write_MFRC522(reg, tmp | mask); // set bit mask
  243. }


  244. /*
  245.  * Function:ClearBitMask
  246.  * Description:clear RC522 register bit
  247.  * Input parameter:reg--register address;mask--value
  248.  * Return:null
  249.  */
  250. void ClearBitMask(uchar reg, uchar mask)
  251. {
  252.     uchar tmp;
  253.     tmp = Read_MFRC522(reg);
  254.     Write_MFRC522(reg, tmp & (~mask)); // clear bit mask
  255. }


  256. /*
  257.  * Function:AntennaOn
  258.  * Description:Turn on antenna, every time turn on or shut down antenna need at least 1ms delay
  259.  * Input parameter:null
  260.  * Return:null
  261.  */
  262. void AntennaOn(void)
  263. {
  264.     uchar temp;

  265.     temp = Read_MFRC522(TxControlReg);
  266.     if (!(temp & 0x03))
  267.     {
  268.         SetBitMask(TxControlReg, 0x03);
  269.     }
  270. }


  271. /*
  272.  * Function:AntennaOff
  273.  * Description:Turn off antenna, every time turn on or shut down antenna need at least 1ms delay
  274.  * Input parameter:null
  275.  * Return:null
  276.  */
  277. void AntennaOff(void)
  278. {
  279.     ClearBitMask(TxControlReg, 0x03);
  280. }


  281. /*
  282.  * Function:ResetMFRC522
  283.  * Description: reset RC522
  284.  * Input parameter:null
  285.  * Return:null
  286.  */
  287. void MFRC522_Reset(void)
  288. {
  289.     Write_MFRC522(CommandReg, PCD_RESETPHASE);
  290. }


  291. /*
  292.  * Function:InitMFRC522
  293.  * Description:initilize RC522
  294.  * Input parameter:null
  295.  * Return:null
  296.  */
  297. void MFRC522_Init(void)
  298. {
  299.     digitalWrite(NRSTPD,HIGH);

  300.     MFRC522_Reset();
  301.          
  302.     //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
  303.     Write_MFRC522(TModeReg, 0x8D); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
  304.     Write_MFRC522(TPrescalerReg, 0x3E); //TModeReg[3..0] + TPrescalerReg
  305.     Write_MFRC522(TReloadRegL, 30);
  306.     Write_MFRC522(TReloadRegH, 0);
  307.     
  308.     Write_MFRC522(TxAutoReg, 0x40); //100%ASK
  309.     Write_MFRC522(ModeReg, 0x3D); //CRC initilizate value 0x6363 ???

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

  313.     AntennaOn(); //turn on antenna
  314. }


  315. /*
  316.  * Function:MFRC522_Request
  317.  * Description:Searching card, read card type
  318.  * Input parameter:reqMode--search methods,
  319.  * TagType--return card types
  320.  * 0x4400 = Mifare_UltraLight
  321.  * 0x0400 = Mifare_One(S50)
  322.  * 0x0200 = Mifare_One(S70)
  323.  * 0x0800 = Mifare_Pro(X)
  324.  * 0x4403 = Mifare_DESFire
  325.  * return:return MI_OK if successed
  326.  */
  327. uchar MFRC522_Request(uchar reqMode, uchar *TagType)
  328. {
  329.     uchar status;
  330.     uint backBits; //the data bits that received

  331.     Write_MFRC522(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0] ???
  332.     
  333.     TagType[0] = reqMode;
  334.     status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);

  335.     if ((status != MI_OK) || (backBits != 0x10))
  336.     {
  337.         status = MI_ERR;
  338.     }
  339.    
  340.     return status;
  341. }


  342. /*
  343.  * Function:MFRC522_ToCard
  344.  * Description:communicate between RC522 and ISO14443
  345.  * Input parameter:command--MF522 command bits
  346.  * sendData--send data to card via rc522
  347.  * sendLen--send data length
  348.  * backData--the return data from card
  349.  * backLen--the length of return data
  350.  * return:return MI_OK if successed
  351.  */
  352. uchar MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen)
  353. {
  354.     uchar status = MI_ERR;
  355.     uchar irqEn = 0x00;
  356.     uchar waitIRq = 0x00;
  357.     uchar lastBits;
  358.     uchar n;
  359.     uint i;

  360.     switch (command)
  361.     {
  362.         case PCD_AUTHENT: //verify card password
  363.         {
  364.             irqEn = 0x12;
  365.             waitIRq = 0x10;
  366.             break;
  367.         }
  368.         case PCD_TRANSCEIVE: //send data in the FIFO
  369.         {
  370.             irqEn = 0x77;
  371.             waitIRq = 0x30;
  372.             break;
  373.         }
  374.         default:
  375.             break;
  376.     }
  377.    
  378.     Write_MFRC522(CommIEnReg, irqEn|0x80); //Allow interruption
  379.     ClearBitMask(CommIrqReg, 0x80); //Clear all the interrupt bits
  380.     SetBitMask(FIFOLevelReg, 0x80); //FlushBuffer=1, FIFO initilizate
  381.     
  382.     Write_MFRC522(CommandReg, PCD_IDLE); //NO action;cancel current command ???

  383.     //write data into FIFO
  384.     for (i=0; i<sendLen; i++)
  385.     {
  386.         Write_MFRC522(FIFODataReg, sendData[i]);
  387.     }

  388.     //procceed it
  389.     Write_MFRC522(CommandReg, command);
  390.     if (command == PCD_TRANSCEIVE)
  391.     {
  392.         SetBitMask(BitFramingReg, 0x80); //StartSend=1,transmission of data starts
  393.     }
  394.     
  395.     //waite receive data is finished
  396.     i = 2000; //i should adjust according the clock, the maxium the waiting time should be 25 ms???
  397.     do
  398.     {
  399.         //CommIrqReg[7..0]
  400.         //Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
  401.         n = Read_MFRC522(CommIrqReg);
  402.         i--;
  403.     }
  404.     while ((i!=0) && !(n&0x01) && !(n&waitIRq));

  405.     ClearBitMask(BitFramingReg, 0x80); //StartSend=0
  406.     
  407.     if (i != 0)
  408.     {
  409.         if(!(Read_MFRC522(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
  410.         {
  411.             status = MI_OK;
  412.             if (n & irqEn & 0x01)
  413.             {
  414.                 status = MI_NOTAGERR; //??
  415.             }
  416.             
  417.             if (command == PCD_TRANSCEIVE)
  418.             {
  419.                 n = Read_MFRC522(FIFOLevelReg);
  420.                 lastBits = Read_MFRC522(ControlReg) & 0x07;
  421.                 if (lastBits)
  422.                 {
  423.                     *backLen = (n-1)*8 + lastBits;
  424.                 }
  425.                 else
  426.                 {
  427.                     *backLen = n*8;
  428.                 }
  429.                 
  430.                 if (n == 0)
  431.                 {
  432.                     n = 1;
  433.                 }
  434.                 if (n > MAX_LEN)
  435.                 {
  436.                     n = MAX_LEN;
  437.                 }
  438.                 
  439.                 //read the data from FIFO
  440.                 for (i=0; i<n; i++)
  441.                 {
  442.                     backData[i] = Read_MFRC522(FIFODataReg);
  443.                 }
  444.             }
  445.         }
  446.         else
  447.         {
  448.             status = MI_ERR;
  449.         }
  450.         
  451.     }
  452.     
  453.     //SetBitMask(ControlReg,0x80); //timer stops
  454.     //Write_MFRC522(CommandReg, PCD_IDLE);

  455.     return status;
  456. }


  457. /*
  458.  * Function:MFRC522_Anticoll
  459.  * Description:Prevent conflict, read the card serial number
  460.  * Input parameter:serNum--return the 4 bytes card serial number, the 5th byte is recheck byte
  461.  * return:return MI_OK if successed
  462.  */
  463. uchar MFRC522_Anticoll(uchar *serNum)
  464. {
  465.     uchar status;
  466.     uchar i;
  467.     uchar serNumCheck=0;
  468.     uint unLen;
  469.     
  470.     //ClearBitMask(Status2Reg, 0x08); //strSensclear
  471.     //ClearBitMask(CollReg,0x80); //ValuesAfterColl
  472.     Write_MFRC522(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0]
  473.  
  474.     serNum[0] = PICC_ANTICOLL;
  475.     serNum[1] = 0x20;
  476.     status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);

  477.     if (status == MI_OK)
  478.     {
  479.         //Verify card serial number
  480.         for (i=0; i<4; i++)
  481.         {
  482.             serNumCheck ^= serNum[i];
  483.         }
  484.         if (serNumCheck != serNum[i])
  485.         {
  486.             status = MI_ERR;
  487.         }
  488.     }

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

  490.     return status;
  491. }


  492. /*
  493.  * Function:CalulateCRC
  494.  * Description:Use MF522 to caculate CRC
  495.  * Input parameter:pIndata--the CRC data need to be read,len--data length,pOutData-- the caculated result of CRC
  496.  * return:Null
  497.  */
  498. void CalulateCRC(uchar *pIndata, uchar len, uchar *pOutData)
  499. {
  500.     uchar i, n;

  501.     ClearBitMask(DivIrqReg, 0x04); //CRCIrq = 0
  502.     SetBitMask(FIFOLevelReg, 0x80); //Clear FIFO pointer
  503.     //Write_MFRC522(CommandReg, PCD_IDLE);

  504.     //Write data into FIFO
  505.     for (i=0; i<len; i++)
  506.     {
  507.         Write_MFRC522(FIFODataReg, *(pIndata+i));
  508.     }
  509.     Write_MFRC522(CommandReg, PCD_CALCCRC);

  510.     //waite CRC caculation to finish
  511.     i = 0xFF;
  512.     do
  513.     {
  514.         n = Read_MFRC522(DivIrqReg);
  515.         i--;
  516.     }
  517.     while ((i!=0) && !(n&0x04)); //CRCIrq = 1

  518.     //read CRC caculation result
  519.     pOutData[0] = Read_MFRC522(CRCResultRegL);
  520.     pOutData[1] = Read_MFRC522(CRCResultRegM);
  521. }



  522. /*
  523.  * Function:MFRC522_Write
  524.  * Description:write block data
  525.  * Input parameters:blockAddr--block address;writeData--Write 16 bytes data into block
  526.  * return:return MI_OK if successed
  527.  */
  528. uchar MFRC522_Write(uchar blockAddr, uchar *writeData)
  529. {
  530.     uchar status;
  531.     uint recvBits;
  532.     uchar i;
  533.     uchar buff[18];
  534.     
  535.     buff[0] = PICC_WRITE;
  536.     buff[1] = blockAddr;
  537.     CalulateCRC(buff, 2, &buff[2]);
  538.     status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);

  539.     if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
  540.     {
  541.         status = MI_ERR;
  542.     }
  543.         
  544.     if (status == MI_OK)
  545.     {
  546.         for (i=0; i<16; i++) //Write 16 bytes data into FIFO
  547.         {
  548.             buff[i] = *(writeData+i);
  549.         }
  550.         CalulateCRC(buff, 16, &buff[16]);
  551.         status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);
  552.         
  553.         if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
  554.         {
  555.             status = MI_ERR;
  556.         }
  557.     }
  558.     
  559.     return status;
  560. }


  561. /*
  562.  * Function:MFRC522_Halt
  563.  * Description:Command the cards into sleep mode
  564.  * Input parameters:null
  565.  * return:null
  566.  */
  567. void MFRC522_Halt(void)
  568. {
  569.     uchar status;
  570.     uint unLen;
  571.     uchar buff[4];

  572.     buff[0] = PICC_HALT;
  573.     buff[1] = 0;
  574.     CalulateCRC(buff, 2, &buff[2]);
  575.  
  576.     status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff,&unLen);
  577. }

阅读(33556) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

泽田纲2014-06-19 18:28:38

你的事UNO吧?Arduino5V的IO可以跟RC522板的IO直接连?RC522板不是要3.3V嘛?