欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5633|回復: 0
打印 上一主題 下一主題
收起左側

51單片機MFRC522程序注釋

[復制鏈接]
跳轉到指定樓層
樓主
ID:424242 發表于 2018-11-10 20:14 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
單片機源程序如下(帶有詳細的代碼注釋):
  1. #include <intrins.h>
  2. #include "reg52.h"
  3. #include "main.h"
  4. #include "mfrc522.h"
  5. #include <string.h>
  6. #define MAXRLEN 18      

  7. /******* RxModeReg默認為106kbit/s的通信速率 ******************/
  8.                  
  9. /***********************************************************************
  10. * 功    能:尋卡
  11. * 參數說明: req_code[IN]:尋卡方式
  12. *                 0x52 = 尋感應區內所有符合14443A標準的卡
  13. *                 0x26 = 尋未進入休眠狀態的卡
  14. *           pTagType[OUT]:卡片類型代碼
  15. *                 0x4400 = Mifare_UltraLight
  16. *                 0x0400 = Mifare_One(S50)
  17. *                 0x0200 = Mifare_One(S70)
  18. *                 0x0800 = Mifare_Pro(X)
  19. *                 0x4403 = Mifare_DESFire
  20. * 返    回: 成功返回MI_OK
  21. ***********************************************************************/
  22. char PcdRequest(unsigned char req_code,unsigned char *pTagType)
  23. {
  24.    char status;  
  25.    unsigned int  unLen;
  26.    unsigned char ucComMF522Buf[MAXRLEN];
  27. //  unsigned char xTest ;
  28.    ClearBitMask(Status2Reg,0x08);  // 清MFCrypto1On,只能通過軟件清零,該位用來指示Crypto1的接通情況,MFAuthent(驗證密鑰)命令成功執行后置1
  29.    WriteRawRC(BitFramingReg,0x07); // TxLastBits([2-0])表示發送的最后一個字節7位發送

  30. //  xTest = ReadRawRC(BitFramingReg);
  31. //  if(xTest == 0x07 )
  32. //   { LED_GREEN  =0 ;}
  33. // else {LED_GREEN =1 ;while(1){}}
  34.    SetBitMask(TxControlReg,0x03); // TxControlReg低2位(Tx2RFEn和Tx1RFEn)置1,Tx2和Tx1管腳輸出信號調制在13.56MHz的載波上

  35.    ucComMF522Buf[0] = req_code;

  36.    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);  // PCD_TRANSCEIVE == 0x0c發送并接收數據
  37. //     if(status  == MI_OK )
  38. //   { LED_GREEN  =0 ;}
  39. //   else {LED_GREEN =1 ;}
  40.    if ((status == MI_OK) && (unLen == 0x10))   // 發送成功并且接收16位數據
  41.    {   
  42.        *pTagType     = ucComMF522Buf[0];
  43.        *(pTagType+1) = ucComMF522Buf[1];  // 接收的卡片類型保存在pTagType中
  44.    }
  45.    else
  46.    {   status = MI_ERR;   }
  47.    
  48.    return status;
  49. }

  50. /**********************************************************************
  51. * 功    能:防沖撞
  52. * 參數說明: pSnr[OUT]:卡片序列號,4字節
  53. * 返    回: 成功返回MI_OK
  54. **********************************************************************/  
  55. char PcdAnticoll(unsigned char *pSnr)
  56. {
  57.     char status;
  58.     unsigned char i,snr_check=0;
  59.     unsigned int  unLen;
  60.     unsigned char ucComMF522Buf[MAXRLEN];
  61.    

  62.     ClearBitMask(Status2Reg,0x08);   // 清MFCrypto1On,只能通過軟件清零,該位用來指示Crypto1的接通情況,MFAuthent(驗證密鑰)命令成功執行后置1
  63.     WriteRawRC(BitFramingReg,0x00);  // TxLastBits([2-0])表示發送的最后一個字節的所有位都發送
  64.     ClearBitMask(CollReg,0x80);      // 高位置0,所有接收的位在沖突后清除

  65.     ucComMF522Buf[0] = PICC_ANTICOLL1; // 防沖撞(0x93)
  66.     ucComMF522Buf[1] = 0x20;

  67.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);

  68.     if (status == MI_OK)
  69.     {
  70.              for (i=0; i<4; i++)
  71.          {   
  72.              *(pSnr+i)  = ucComMF522Buf[i];  // 讀取卡片序列號
  73.              snr_check ^= ucComMF522Buf[i];
  74.          }
  75.          if (snr_check != ucComMF522Buf[i])
  76.          {   status = MI_ERR;    }
  77.     }
  78.    
  79.     SetBitMask(CollReg,0x80);  // 置1,回歸正常
  80.     return status;
  81. }

  82. /**********************************************************************
  83. * 功    能:選定卡片
  84. * 參數說明: pSnr[IN]:卡片序列號,4字節
  85. * 返    回: 成功返回MI_OK
  86. **********************************************************************/
  87. char PcdSelect(unsigned char *pSnr)
  88. {
  89.     char status;
  90.     unsigned char i;
  91.     unsigned int  unLen;
  92.     unsigned char ucComMF522Buf[MAXRLEN];
  93.    
  94.     ucComMF522Buf[0] = PICC_ANTICOLL1;  // 防沖撞
  95.     ucComMF522Buf[1] = 0x70;
  96.     ucComMF522Buf[6] = 0;
  97.     for (i=0; i<4; i++)
  98.     {
  99.             ucComMF522Buf[i+2] = *(pSnr+i);   // 將卡片序列號寫進去
  100.             ucComMF522Buf[6]  ^= *(pSnr+i);
  101.     }
  102.     CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);  // CRC校驗卡片序列號
  103.   
  104.     ClearBitMask(Status2Reg,0x08);  // 清MFCrypto1On,只能通過軟件清零,該位用來指示Crypto1的接通情況,MFAuthent(驗證密鑰)命令成功執行后置1

  105.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);  // 發送卡片的序列號及其校驗碼
  106.    
  107.     if ((status == MI_OK) && (unLen == 0x18))  // 接收24位
  108.     {   status = MI_OK;  }
  109.     else
  110.     {   status = MI_ERR;    }

  111.     return status;
  112. }

  113. /**********************************************************************
  114. * 功    能:驗證卡片密碼
  115. * 參數說明: auth_mode[IN]: 密碼驗證模式
  116. *                  0x60 = 驗證A密鑰
  117. *                  0x61 = 驗證B密鑰
  118. *           addr[IN]:塊地址
  119. *           pKey[IN]:密碼
  120. *           pSnr[IN]:卡片序列號,4字節
  121. * 返    回: 成功返回MI_OK
  122. **********************************************************************/               
  123. char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr)
  124. {
  125.     char status;
  126.     unsigned int  unLen;
  127.     unsigned char i,ucComMF522Buf[MAXRLEN];

  128.     ucComMF522Buf[0] = auth_mode;   // 驗證模式
  129.     ucComMF522Buf[1] = addr;        // 塊地址
  130.     for (i=0; i<6; i++)
  131.     {    ucComMF522Buf[i+2] = *(pKey+i);   }  // 密碼
  132.     for (i=0; i<4; i++)                                          /*源代碼是6,不知道正不正確*/
  133.     {    ucComMF522Buf[i+8] = *(pSnr+i);   }  // 防沖撞卡號
  134. //   memcpy(&ucComMF522Buf[2], pKey, 6);
  135. //   memcpy(&ucComMF522Buf[8], pSnr, 4);
  136.    
  137.     status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);
  138.     if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
  139.     {   status = MI_ERR;   }
  140.    
  141.     return status;
  142. }

  143. /**********************************************************************
  144. * 功    能:讀取M1卡一塊數據
  145. * 參數說明: addr[IN]:塊地址
  146. *           pData[OUT]:讀出的數據,16字節
  147. * 返    回: 成功返回MI_OK
  148. ***********************************************************************/
  149. char PcdRead(unsigned char addr,unsigned char *pData)
  150. {
  151.     char status;
  152.     unsigned int  unLen;
  153.     unsigned char i,ucComMF522Buf[MAXRLEN];

  154.     ucComMF522Buf[0] = PICC_READ;  // 0x30,讀塊
  155.     ucComMF522Buf[1] = addr;
  156.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);  // 計算CRC,存放在ucComMF522Buf[2]和ucComMF522Buf[3]中
  157.    
  158.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);  // 將4個字節放松出去,并接收數據
  159.     if ((status == MI_OK) && (unLen == 0x90))  // 接收144位(18字節)
  160. //   {   memcpy(pData, ucComMF522Buf, 16);   }
  161.     {
  162.         for (i=0; i<16; i++)
  163.         {    *(pData+i) = ucComMF522Buf[i];   }  // 將前16字節讀出
  164.     }
  165.     else
  166.     {   status = MI_ERR;   }
  167.    
  168.     return status;
  169. }

  170. /********************************************************************
  171. * 功    能:寫數據到M1卡一塊
  172. * 參數說明: addr[IN]:塊地址
  173. *           pData[IN]:寫入的數據,16字節
  174. * 返    回: 成功返回MI_OK
  175. ********************************************************************/                  
  176. char PcdWrite(unsigned char addr,unsigned char *pData)
  177. {
  178.     char status;
  179.     unsigned int  unLen;
  180.     unsigned char i,ucComMF522Buf[MAXRLEN];
  181.    
  182.     ucComMF522Buf[0] = PICC_WRITE;  // 0xa0 寫塊
  183.     ucComMF522Buf[1] = addr;
  184.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);  // 計算CRC

  185.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);  // 發送寫命令和地址

  186.     if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) // 接收低四位為1010
  187.     {   status = MI_ERR;   }
  188.         
  189.     if (status == MI_OK)
  190.     {
  191.         //memcpy(ucComMF522Buf, pData, 16);
  192.         for (i=0; i<16; i++)
  193.         {    ucComMF522Buf[i] = *(pData+i);   }  // 16字節數據
  194.         CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]); // 兩位CRC計算字節

  195.         status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);  // 發送18字節
  196.         if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) // 返回低四位為1010
  197.         {   status = MI_ERR;   }
  198.     }
  199.    
  200.     return status;
  201. }



  202. /*********************************************************************
  203. * 功    能:命令卡片進入休眠狀態
  204. * 返    回: 成功返回MI_OK
  205. *********************************************************************/
  206. char PcdHalt(void)
  207. {
  208.     char status;
  209.     unsigned int  unLen;
  210.     unsigned char ucComMF522Buf[MAXRLEN];

  211.     ucComMF522Buf[0] = PICC_HALT;  // 0x50,休眠
  212.     ucComMF522Buf[1] = 0;
  213.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); // 計算校驗位

  214.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen); // 發送

  215.     return MI_OK;
  216. }

  217. /*********************************************************************
  218. * 用MF522計算CRC16函數
  219. *********************************************************************/
  220. void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData)
  221. {
  222.     unsigned char i,n;
  223.     ClearBitMask(DivIrqReg,0x04);    // CRCIRQ清零
  224.     WriteRawRC(CommandReg,PCD_IDLE); // 空閑命令
  225.     SetBitMask(FIFOLevelReg,0x80);   // FIFOLevelReg中FlushBuffer位置1,表示緩沖區讀和寫指針清除,即緩沖區無數據,用來存放一下批數據,ErrReg的BufferOvfl清楚
  226.     for (i=0; i<len; i++)
  227.     {   WriteRawRC(FIFODataReg, *(pIndata+i));   }  // 將數據寫入緩沖區
  228.     WriteRawRC(CommandReg, PCD_CALCCRC);            // 啟動CRC計算,結果存于CRCResultReg中
  229.     i = 0xFF;
  230.     do
  231.     {
  232.         n = ReadRawRC(DivIrqReg);
  233.         i--;
  234.     }
  235.     while ((i!=0) && !(n&0x04));        // CRCIRQ置位,當CRC有效且所有數據被處理則需要置1,退出循環,或者是執行了127次讀取認為完成CRC也退出循環
  236.     pOutData[0] = ReadRawRC(CRCResultRegL);  
  237.     pOutData[1] = ReadRawRC(CRCResultRegM);  // 計算結果輸出到pOutData中
  238. }

  239. /*********************************************************************
  240. * 功    能:復位RC522
  241. * 返    回: 成功返回MI_OK
  242. *********************************************************************/
  243. char PcdReset(void)
  244. {
  245.     MF522_RST=1;
  246.     _nop_();
  247.     MF522_RST=0;   // 復位
  248.     _nop_();
  249.     MF522_RST=1;
  250.      _nop_();
  251.     WriteRawRC(CommandReg,PCD_RESETPHASE); // 0x0F,軟件復位
  252.     _nop_();
  253.    
  254.     WriteRawRC(ModeReg,0x3D);            // 和Mifare卡通訊,CRC初始值0x6363
  255.     WriteRawRC(TReloadRegL,30);          // 48
  256.     WriteRawRC(TReloadRegH,0);
  257.     WriteRawRC(TModeReg,0x8D);           // 10001101(141):發送完開始計時,接收時停止計時,自動重裝
  258.     WriteRawRC(TPrescalerReg,0x3E);      // 00111110(62),3390  定時時間:3391*49/6.78=24.5ms
  259.     WriteRawRC(TxAutoReg,0x40);          // 控制驅動天線
  260.     return MI_OK;
  261. }
  262. /*********************************************************************
  263. * 設置RC632的工作方式
  264. *********************************************************************/
  265. char M500PcdConfigISOType(unsigned char type)
  266. {
  267.    if (type == 'A')                     //ISO14443_A
  268.    {
  269.        ClearBitMask(Status2Reg,0x08);

  270. /*     WriteRawRC(CommandReg,0x20);    //as default   
  271.        WriteRawRC(ComIEnReg,0x80);     //as default
  272.        WriteRawRC(DivlEnReg,0x0);      //as default
  273.            WriteRawRC(ComIrqReg,0x04);     //as default
  274.            WriteRawRC(DivIrqReg,0x0);      //as default
  275.            WriteRawRC(Status2Reg,0x0);//80    //trun off temperature sensor
  276.            WriteRawRC(WaterLevelReg,0x08); //as default
  277.        WriteRawRC(ControlReg,0x20);    //as default
  278.            WriteRawRC(CollReg,0x80);    //as default
  279. */
  280.        WriteRawRC(ModeReg,0x3D);//3F
  281. /*           WriteRawRC(TxModeReg,0x0);      //as default???
  282.            WriteRawRC(RxModeReg,0x0);      //as default???
  283.            WriteRawRC(TxControlReg,0x80);  //as default???

  284.            WriteRawRC(TxSelReg,0x10);      //as default???
  285.    */
  286.        WriteRawRC(RxSelReg,0x86);//84  // 內部模擬部分的調制信號作為非接觸式UART輸入,發送后接收器啟動延時6個位時鐘
  287. //      WriteRawRC(RxThresholdReg,0x84);//as default
  288. //      WriteRawRC(DemodReg,0x4D);      //as default

  289. //      WriteRawRC(ModWidthReg,0x13);//26
  290.        WriteRawRC(RFCfgReg,0x7F);   //4F  // 接收信號電壓增益23dB
  291.         /*   WriteRawRC(GsNReg,0x88);        //as default???
  292.            WriteRawRC(CWGsCfgReg,0x20);    //as default???
  293.        WriteRawRC(ModGsCfgReg,0x20);   //as default???
  294. */
  295.               WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec)
  296.            WriteRawRC(TReloadRegH,0);
  297.        WriteRawRC(TModeReg,0x8D);
  298.            WriteRawRC(TPrescalerReg,0x3E);
  299.            

  300.   //     PcdSetTmo(106);
  301.                                 delay(10);
  302.        PcdAntennaOn();
  303.    }
  304.    else{ return -1; }
  305.    
  306.    return MI_OK;
  307. }
  308. /********************************************************************
  309. * 功    能:讀RC632寄存器     SPI方式
  310. * 參數說明:Address[IN]:寄存器地址
  311. * 返    回:讀出的值
  312. *********************************************************************/
  313. unsigned char ReadRawRC(unsigned char Address)
  314. {
  315.      unsigned char i, ucAddr;
  316.      unsigned char ucResult=0;

  317.      MF522_SCK = 0;
  318.      MF522_NSS = 0;
  319.      ucAddr = ((Address<<1)&0x7E)|0x80;

  320.      for(i=8;i>0;i--)
  321.      {
  322.          MF522_SI = ((ucAddr&0x80)==0x80);
  323.          MF522_SCK = 1;
  324.          ucAddr <<= 1;
  325.          MF522_SCK = 0;
  326.      }

  327.      for(i=8;i>0;i--)
  328.      {
  329.          MF522_SCK = 1;
  330.          ucResult <<= 1;
  331.          ucResult|=(bit)MF522_SO;
  332.          MF522_SCK = 0;
  333.      }

  334.      MF522_NSS = 1;
  335.      MF522_SCK = 1;
  336.      return ucResult;
  337. }

  338. /*********************************************************************
  339. * 功    能:寫RC632寄存器
  340. * 參數說明:Address[IN]:寄存器地址
  341. *           value[IN]:寫入的值
  342. **********************************************************************/
  343. void WriteRawRC(unsigned char Address, unsigned char value)
  344. {  
  345.     unsigned char i, ucAddr;

  346.     MF522_SCK = 0;
  347.     MF522_NSS = 0;
  348.     ucAddr = ((Address<<1)&0x7E);  // 地址高位為0表示寫,地位必須為0

  349.     for(i=8;i>0;i--)
  350.     {
  351.         MF522_SI = ((ucAddr&0x80)==0x80);
  352.         MF522_SCK = 1;
  353.         ucAddr <<= 1;
  354.         MF522_SCK = 0;
  355.     }

  356.     for(i=8;i>0;i--)
  357.     {
  358.         MF522_SI = ((value&0x80)==0x80);
  359.         MF522_SCK = 1;
  360.         value <<= 1;
  361.         MF522_SCK = 0;
  362.     }
  363.     MF522_NSS = 1;
  364.     MF522_SCK = 1;
  365. }

  366. /*********************************************************************
  367. * 功    能:置RC522寄存器位
  368. * 參數說明:reg[IN]:寄存器地址
  369. *           mask[IN]:置位值
  370. *********************************************************************/
  371. void SetBitMask(unsigned char reg,unsigned char mask)  
  372. {
  373.     char tmp = 0x0;
  374.     tmp = ReadRawRC(reg);
  375.     WriteRawRC(reg,tmp | mask);  // set bit mask
  376. }

  377. /*********************************************************************
  378. * 功    能:清RC522寄存器位
  379. * 參數說明:reg[IN]:寄存器地址
  380. *           mask[IN]:清位值
  381. *********************************************************************/
  382. void ClearBitMask(unsigned char reg,unsigned char mask)  
  383. {
  384.     char tmp = 0x0;
  385.     tmp = ReadRawRC(reg);
  386.     WriteRawRC(reg, tmp & ~mask);  // clear bit mask
  387. }

  388. /*********************************************************************
  389. * 功    能:通過RC522和ISO14443卡通訊
  390. * 參數說明:Command[IN]:RC522命令字
  391. *           pInData[IN]:通過RC522發送到卡片的數據
  392. *           InLenByte[IN]:發送數據的字節長度
  393. *           pOutData[OUT]:接收到的卡片返回數據
  394. *           *pOutLenBit[OUT]:返回數據的位長度
  395. *********************************************************************/
  396. char PcdComMF522(unsigned char Command,
  397.                  unsigned char *pInData,
  398.                  unsigned char InLenByte,
  399.                  unsigned char *pOutData,
  400.                  unsigned int  *pOutLenBit)
  401. {
  402.     char status = MI_ERR;
  403.     unsigned char irqEn   = 0x00;
  404.     unsigned char waitFor = 0x00;
  405.     unsigned char lastBits;
  406.     unsigned char n;
  407.     unsigned int i;
  408.     switch (Command)
  409.     {
  410.        case PCD_AUTHENT:      // 驗證密鑰
  411.           irqEn   = 0x12;
  412.           waitFor = 0x10;
  413.           break;
  414.        case PCD_TRANSCEIVE:   // 發送并接收數據
  415.           irqEn   = 0x77;
  416.           waitFor = 0x30;
  417.           break;
  418.        default:
  419.          break;
  420.     }
  421.    
  422.     WriteRawRC(ComIEnReg,irqEn|0x80); // ComIEnReg:中斷請求的使能位。驗證密鑰:(10010010)位7:管腳IRQ與Status1Reg的IRq反相。位4:允許空閑中斷請求(IdleIRq位)傳遞到IRQ管腳上。位1:允許錯誤中斷請求(ErrIRq位)傳遞到IRQ管腳上。
  423.                                       //                             發送并接收數據:(11110111)除高位中斷請求外,其他都能傳到IRQ管腳上
  424.     ClearBitMask(ComIrqReg,0x80);     // ComIrqReg的屏蔽位清零
  425.     WriteRawRC(CommandReg,PCD_IDLE);  // CommandReg低4位寫0000B,處于空閑模式
  426.     SetBitMask(FIFOLevelReg,0x80);    // FIFOLevelReg中FlushBuffer位置1,表示緩沖區讀和寫指針清除,即緩沖區無數據,用來存放一下批數據,ErrReg的BufferOvfl清除
  427.    
  428.     for (i=0; i<InLenByte; i++)
  429.     {   
  430.             WriteRawRC(FIFODataReg, pInData[i]);  // 將pInData數組的數據寫進FIFO緩沖區
  431.     }
  432.     WriteRawRC(CommandReg, Command);    // 驗證密鑰 or 發送并接收數據
  433.    
  434.    
  435.     if (Command == PCD_TRANSCEIVE)
  436.     {    SetBitMask(BitFramingReg,0x80);  }  // 啟動數據的發送
  437.    
  438. //    i = 600;//根據時鐘頻率調整,操作M1卡最大等待時間25ms
  439. i = 2000;
  440.     do
  441.     {
  442.          n = ReadRawRC(ComIrqReg);
  443.          i--;
  444.     }
  445.     while ((i!=0) && !(n&0x01) && !(n&waitFor));  //如果i不為0,并且定時器沒減到0,并且沒有未知命令和自身終止命令和接收器沒有檢測到有效數據流,就繼續循環,退出循環則表示接收完成
  446.     ClearBitMask(BitFramingReg,0x80);    // StartSend位清零
  447.               
  448.     if (i!=0)
  449.     {   
  450.          if(!(ReadRawRC(ErrorReg)&0x1B))   // FIFO沒有溢出、接收器啟動并完成接收之后:(沒沖突)、(CRC沒出錯)、(沒有SOF錯誤)、(驗證時接受字節數沒錯)
  451.          {
  452.              status = MI_OK;
  453.              if (n & irqEn & 0x01)           // 發送并接收數據、定時器減到0
  454.              {   status = MI_NOTAGERR;   }   // 沒有找到目標錯誤
  455.              if (Command == PCD_TRANSCEIVE)
  456.              {
  457.                        n = ReadRawRC(FIFOLevelReg);  // 讀FIFO保存的字節數
  458.                       lastBits = ReadRawRC(ControlReg) & 0x07;  // 最后一個接收的字節的有效位數(0則表示8位都有效)
  459.                 if (lastBits)
  460.                 {   *pOutLenBit = (n-1)*8 + lastBits;   }
  461.                 else
  462.                 {   *pOutLenBit = n*8;   }
  463.                 if (n == 0)
  464.                 {   n = 1;    }
  465.                 if (n > MAXRLEN)
  466.                 {   n = MAXRLEN;   }
  467.                 for (i=0; i<n; i++)
  468.                 {   pOutData[i] = ReadRawRC(FIFODataReg);    } // 將緩沖區的數據讀出
  469.             }
  470.          }
  471.          else
  472.          {   status = MI_ERR;   }  // 驗證錯誤
  473.         
  474.    }
  475.    

  476.    SetBitMask(ControlReg,0x80);           // stop timer now
  477.    WriteRawRC(CommandReg,PCD_IDLE);       // 空閑
  478.    return status;
  479. }


  480. /********************************************************************
  481. * 開啟天線  
  482. * 每次啟動或關閉天險發射之間應至少有1ms的間隔
  483. ********************************************************************/
  484. void PcdAntennaOn()
  485. {
  486.     unsigned char i;
  487.     i = ReadRawRC(TxControlReg);
  488.     if (!(i & 0x03))
  489.     {
  490.         SetBitMask(TxControlReg, 0x03);  // Tx1和Tx2管腳的輸出信號調制到13.56MHz的載波上
  491.     }
  492. }


  493. /********************************************************************
  494. * 關閉天線
  495. ********************************************************************/
  496. void PcdAntennaOff()
  497. {
  498.     ClearBitMask(TxControlReg, 0x03);
  499. }


  500. /*********************************************************************
  501. * 功    能:扣款和充值
  502. * 參數說明: dd_mode[IN]:命令字
  503. *                0xC0 = 扣款
  504. *                0xC1 = 充值
  505. *           addr[IN]:錢包地址
  506. *           pValue[IN]:4字節增(減)值,低位在前
  507. * 返    回: 成功返回MI_OK
  508. *********************************************************************/                 
  509. char PcdValue(unsigned char dd_mode,unsigned char addr,unsigned char *pValue)
  510. {
  511.     char status;
  512.     unsigned int  unLen;
  513.     unsigned char ucComMF522Buf[MAXRLEN];
  514.    
  515.     ucComMF522Buf[0] = dd_mode;  // 充值還是扣款(加還是減)
  516.     ucComMF522Buf[1] = addr;     // 錢包地址(寫卡的地址)
  517.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); // 計算CRC

  518.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);  // 發送數據并接收數據

  519.     if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))  // 卡片返回1010
  520.     {   status = MI_ERR;   }
  521.         
  522.     if (status == MI_OK)
  523.     {
  524.         //(ucComMF522Buf, pValue, 4);
  525.         for (i=0; i<4; i++)  //16
  526.         {    ucComMF522Buf[i] = *(pValue+i);   }
  527.         CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]);
  528.         unLen = 0;
  529.         status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen);  // 發送充或者扣的數據
  530.         if (status != MI_ERR)
  531.         {    status = MI_OK;    }
  532.     }
  533.    
  534.     if (status == MI_OK)
  535.     {
  536.         ucComMF522Buf[0] = PICC_TRANSFER;  // 保存緩沖區中的數據
  537.         ucComMF522Buf[1] = addr;           // 地址
  538.         CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);   // 計算crc
  539.    
  540.         status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);  // 發送保存緩沖區數據的命令

  541.         if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))  // 卡片返回1010B
  542.         {   status = MI_ERR;   }
  543.     }
  544.     return status;
  545. }

  546. /**********************************************************************
  547. * 功    能:備份錢包
  548. * 參數說明: sourceaddr[IN]:源地址
  549. *           goaladdr[IN]:目標地址
  550. * 返    回: 成功返回MI_OK
  551. **********************************************************************/
  552. char PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr)
  553. {
  554.     char status;
  555.     unsigned int  unLen;
  556.     unsigned char ucComMF522Buf[MAXRLEN];

  557.     ucComMF522Buf[0] = PICC_RESTORE;  // 0xC2,調塊數據到緩沖區
  558.     ucComMF522Buf[1] = sourceaddr;    // 源地址
  559.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);  // 計算CRC

  560.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);  // 發送命令:將源地址的數據調到緩沖區

  561.     if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
  562.     {   status = MI_ERR;   }
  563.    
  564.     if (status == MI_OK)
  565.     {
  566.         ucComMF522Buf[0] = 0;
  567.         ucComMF522Buf[1] = 0;
  568.         ucComMF522Buf[2] = 0;
  569.         ucComMF522Buf[3] = 0;
  570.         CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]);

  571.         status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen);
  572.         if (status != MI_ERR)
  573.         {    status = MI_OK;    }
  574.     }
  575.    
  576.     if (status != MI_OK)
  577.     {    return MI_ERR;   }
  578.    
  579.     ucComMF522Buf[0] = PICC_TRANSFER;   // 保存緩沖區內容命令
  580.     ucComMF522Buf[1] = goaladdr;        // 目標地址

  581.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

  582.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);  // 發送命令:將緩沖區的內容發送到目標地址

  583.     if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
  584.     {   status = MI_ERR;   }

  585.     return status;
  586. }

  587. /*
  588. ///////////////////////////////////////////////////////////////////////
  589. // Delay 10ms
  590. ///////////////////////////////////////////////////////////////////////
  591. void delay_10ms(unsigned int _10ms)
  592. {
  593. #ifndef NO_TIMER2
  594.     RCAP2LH = RCAP2_10ms;
  595.     T2LH    = RCAP2_10ms;
  596.    
  597.     TR2 = TRUE;
  598.     while (_10ms--)
  599.     {
  600.             while (!TF2);
  601.             TF2 = FALSE;
  602.     }
  603.     TR2 = FALSE;
  604. #else
  605.     while (_10ms--)
  606.     {
  607.             delay_50us(19);
  608.             if (CmdValid)
  609.                 return;
  610.             delay_50us(20);
  611.             if (CmdValid)
  612.                 return;
  613.             delay_50us(20);
  614.             if (CmdValid)
  615.                 return;
  616.             delay_50us(20);
  617.             if (CmdValid)
  618.                 return;
  619.             delay_50us(20);
  620.             if (CmdValid )
  621.                 return;
  622.             delay_50us(20);
  623.             if (CmdValid)
  624.                 return;
  625.             delay_50us(20);
  626.             if (CmdValid)
  627.                 return;
  628.             delay_50us(20);
  629.             if (CmdValid)
  630.                 return;
  631.             delay_50us(20);
  632.             if (CmdValid)
  633.                 return;
  634.             delay_50us(19);
  635.             if (CmdValid)
  636.                 return;
  637.     }
  638. #endif
  639. }
  640. */
復制代碼

所有資料51hei提供下載:
mfrc522程序注釋.doc (23.44 KB, 下載次數: 57)
MFRC500中文資料.pdf (1.7 MB, 下載次數: 36)
51單片機RC522射頻卡驅動.docx (21.9 KB, 下載次數: 53)

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

無效樓層,該帖已經被刪除
無效樓層,該帖已經被刪除
無效樓層,該帖已經被刪除
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表