久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于stm32F103xxx與RFID-RC522的門禁程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:618513 發表于 2021-1-4 20:37 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
最近用到了RFID-RC522,找了很多資料,總結了一下 順便和大家分享分享。  再本人的項目中RFID只是用來起到刷卡開門的效果,順帶用串口打印顯示ID號。 需要的朋友自行下載。
RD
連線如下:
//SPI2_SCK                         PB13
//SPI2_MISO                        PB14
//SPI2_MOSI                         PB15
//RCC522_RST                   PC4
//RCC522_SDA                   PB0
//RCC522_IRQ                         懸空(不管)


直接移植久好  驅動是全的      
  1. #include "rc522.h"

  2. //SPI2_SCK                                 PB13
  3. //SPI2_MISO                                PB14
  4. //SPI2_MOSI                         PB15
  5. //RCC522_RST(CE)  PC4
  6. //RCC522_NSS(SDA)PB0
  7. //RCC522_IRQ                         懸空

  8. void SPI2_Init(void)
  9. {
  10.         GPIO_InitTypeDef GPIO_InitStructure;
  11.         SPI_InitTypeDef  SPI_InitStructure;

  12.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE );        //PORTB時鐘使能
  13.         RCC_APB1PeriphClockCmd(        RCC_APB1Periph_SPI2,  ENABLE );                                                                                                //SPI2時鐘使能         

  14.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  15.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                                                                                                                          //PB13/14/15復用推挽輸出
  16.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  17.         GPIO_Init(GPIOB, &GPIO_InitStructure);                                                                                                                                                                //初始化GPIOB
  18.         GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);                                                                                  //PB13/14/15上拉
  19.         
  20.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                                                                                                                                                        //PB0 RC522_CS
  21.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                                                                                                  //PB0推挽輸出
  22.         GPIO_Init(GPIOB, &GPIO_InitStructure);                                                                                                                                                                //初始化GPIOB
  23.         GPIO_SetBits(GPIOB,GPIO_Pin_0);                                                                                                                                                                                          //PB0上拉        

  24.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;                                                                                                                                                        //PC4 RC522_RST
  25.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                                                                                                  //推挽輸出
  26.         GPIO_Init(GPIOC, &GPIO_InitStructure);                                                                                                                                                                //初始化GPIOC
  27.         GPIO_SetBits(GPIOC,GPIO_Pin_4);                                                                                                                                                                                          //PC4

  28.         SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;                                          //設置SPI單向或者雙向的數據模式:SPI設置為雙線雙向全雙工
  29.         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                                                                                                                                        //設置SPI工作模式:設置為主SPI
  30.         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                                                                                                                        //設置SPI的數據大小:SPI發送接收8位幀結構
  31.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                                                                                                                                                //串行同步時鐘的空閑狀態為高電平
  32. //                 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;        
  33. //                SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                                                                                                                                        //串行同步時鐘的第一個跳變沿(下降)數據被采樣
  34.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                                                                                                                                                //串行同步時鐘的第二個跳變沿(上升)數據被采樣
  35.         SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                                                                                                                                                        //NSS信號由硬件(NSS管腳)還是軟件(使用SSI位)管理:內部NSS信號有SSI位控制
  36. //RC522 SPI通訊時鐘周期最小為100ns        即頻率最大為10MHZ
  37. //RC522 數據在下降沿變化
  38.         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                                        //定義波特率預分頻的值:波特率預分頻值為256、傳輸速率36M/256=140.625KHz
  39.         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                                                                                                                //指定數據傳輸從MSB位還是LSB位開始:數據傳輸從MSB位開始
  40.         SPI_InitStructure.SPI_CRCPolynomial = 7;                                                                                                                                                        //CRC值計算的多項式
  41.         SPI_Init(SPI2, &SPI_InitStructure);                                                                                                                                                                          //根據SPI_InitStruct中指定的參數初始化外設SPIx寄存器

  42.         SPI_Cmd(SPI2, ENABLE); //使能SPI外設
  43.         RC522_CS=0;
  44.         SPI2_ReadWriteByte(0xaa);//啟動傳輸        
  45.         RC522_CS=1;
  46.                
  47.   delay_ms(50);
  48.         PcdReset();//復位RC522讀卡器
  49.         delay_ms(10);
  50.         PcdReset();//復位RC522讀卡器
  51.         delay_ms(10);
  52.         PcdAntennaOff();//關閉天線發射                                                         
  53.         delay_ms(10);         
  54.   PcdAntennaOn();//開啟天線發射
  55.         printf("RFID-MFRC522 TEST\r\nFindCard Starting ...\r\n");  //測試引腳初始化完成
  56. }


  57. void delay_ns(u32 ns)
  58. {
  59.   u32 i;
  60.   for(i=0;i<ns;i++)
  61.   {
  62.     __nop();
  63.     __nop();
  64.     __nop();
  65.   }
  66. }

  67. /***************************************************************************
  68.     - 功能描述:STM32f103 SPI讀寫字節函數
  69.     - 隸屬模塊:STM32 SPI操作
  70.   - 函數屬性:外部,使用戶使用
  71.   - 參數說明:TxData:要寫入的字節
  72.   - 返回說明:讀取到的字節
  73. - 函數說明:由于主機SPI通信時,在發送和接受時是同時進行的,即發送完了一個字節的數據后,也應當接受到一個字節的數據
  74.    (1)stm32先等待已發送的數據是否發送完成,如果沒有發送完成,并且進入循環200次,則表示發送錯誤,返回收到的值為0;
  75.    (2)如果發送完成,stm32從SPI1總線發送TxData
  76.    (3)stm32再等待接收的數據是否接收完成,如果沒有接收完成,并且進入循環200次,則表示接收錯誤,則返回值0
  77.    (4)如果接收完成了,則返回STm32讀取的最新的數據  
  78.    
  79.    stm32
  80.    ------->等待已發送的數據是否完成
  81.    OK
  82.    ------->  
  83.    stm32發送數據
  84.    ------->等待待接收的數據是否完成
  85.    OK
  86.    ------->
  87.    stm32讀取數據

  88. //SPIx 讀寫一個字節
  89. //TxData:要寫入的字節
  90. //返回值:讀取到的字節
  91. ***************************************************************************/

  92. char SPI2_ReadWriteByte(u8 TxData)
  93. {                                                
  94.         while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //檢查指定的SPI標志位設置與否:發送緩存空標志位
  95.                 {
  96.                         ;
  97.                 }                          
  98.         SPI_I2S_SendData(SPI2, TxData);                                                                                                                                 //通過外設SPIx發送一個數據
  99.         while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //檢查指定的SPI標志位設置與否:接受緩存非空標志位
  100.                 {
  101. //                 retry++;
  102. //                 if(retry>200)return 0;
  103.                         ;
  104.                 }                                                              
  105.         return SPI_I2S_ReceiveData(SPI2);                                                                                                                         //返回通過SPIx最近接收的數據                                            
  106. }
  107. // u8 SPI2_ReadWriteByte(u8 Byte)
  108. // {
  109. //         while((SPI2->SR&0X02)==0);                //等待發送區空         
  110. //         SPI2->DR=Byte;                             //發送一個byte   
  111. //         while((SPI2->SR&0X01)==0);      //等待接收完一個byte  
  112. //         return SPI2->DR;                      //返回收到的數據                        
  113. // }


  114. //******************************************************************/
  115. //功    能:讀RC522寄存器
  116. //參數說明:Address[IN]:寄存器地址
  117. //返    回:讀出的值
  118. //******************************************************************/
  119. unsigned char ReadRawRC(unsigned char Address)
  120. {
  121.         u8 ucAddr;
  122.   u8 ucResult=0;
  123.         RC522_CS=0;
  124.         delay_us(10);
  125.    ucAddr = ((Address<<1)&0x7E)|0x80;
  126.         SPI2_ReadWriteByte(ucAddr);
  127.         delay_us(10);
  128.         ucResult=SPI2_ReadWriteByte(0);
  129.         delay_us(10);
  130.         RC522_CS=1;
  131.   return ucResult;
  132. }

  133. //******************************************************************/
  134. //功    能:寫RC522寄存器
  135. //參數說明:Address[IN]:寄存器地址
  136. //          value[IN]:寫入的值
  137. //******************************************************************/
  138. void WriteRawRC(unsigned char Address, unsigned char value)
  139. {
  140.         u8 ucAddr;
  141.         RC522_CS=0;
  142.         delay_us(10);
  143.         ucAddr = ((Address<<1)&0x7E) ;
  144.         SPI2_ReadWriteByte(ucAddr);
  145.         delay_us(10);
  146.         SPI2_ReadWriteByte(value);
  147.         delay_us(10);
  148.         RC522_CS=1;
  149. }

  150. //******************************************************************/
  151. //功    能:置RC522寄存器位
  152. //參數說明:reg[IN]:寄存器地址
  153. //          mask[IN]:置位值
  154. //******************************************************************/
  155. void SetBitMask(unsigned char reg,unsigned char mask)  
  156. {
  157.   char tmp = 0x0            ;
  158.   tmp = ReadRawRC(reg)| mask;
  159.   WriteRawRC(reg,tmp | mask);  // set bit mask
  160. }

  161. //******************************************************************/
  162. //功    能:清RC522寄存器位
  163. //參數說明:reg[IN]:寄存器地址
  164. //          mask[IN]:清位值
  165. //******************************************************************/
  166. void ClearBitMask(unsigned char reg,unsigned char mask)  
  167. {
  168.   char tmp = 0x0              ;
  169.   tmp = ReadRawRC(reg)&(~mask);
  170.   WriteRawRC(reg, tmp)        ;  // clear bit mask
  171. }

  172. //******************************************************************/
  173. //功    能:復位RC522
  174. //返    回: 成功返回MI_OK
  175. //******************************************************************/
  176. char PcdReset()
  177. {
  178.   RC522_RST=1;                             ;
  179.   delay_ns(10)                             ;
  180.   RC522_RST=0;                             ;
  181.   delay_ns(100)                             ;
  182.   RC522_RST=1;                             ;
  183.   delay_ns(10)                           ;
  184.   WriteRawRC(CommandReg,PCD_RESETPHASE);
  185.   delay_ns(100)                             ;
  186.   WriteRawRC(ModeReg,0x3D)             ;//定義發送和接收常用模式 和Mifare卡通訊,CRC初始值0x6363
  187.   WriteRawRC(TReloadRegL,30)           ;//16位定時器低位 30
  188.   WriteRawRC(TReloadRegH,0)            ;//16位定時器高位
  189.   WriteRawRC(TModeReg,0x8D)            ;//定義內部定時器的設置
  190.   WriteRawRC(TPrescalerReg,0x3E)       ;//設置定時器分頻系數  
  191.   WriteRawRC(TxASKReg,0x40)            ;//調制發送信號為100%ASK
  192.   return MI_OK                         ;
  193. }
  194. //////////////////////////////////////////////////////////////////////
  195. //設置RC522的工作方式   
  196. //////////////////////////////////////////////////////////////////////
  197. char MF522PcdConfigISOType(unsigned char  type)
  198. {
  199.         if (type == 'A')        //ISO14443_A
  200.                 {
  201.                         ClearBitMask(Status2Reg,0x08);        //狀態2寄存器         
  202.                         WriteRawRC(ModeReg,0x3D);        //3F  //和Mifare卡通訊,CRC初始值0x6363         
  203.                         WriteRawRC(RxSelReg,0x86);        //84   選擇內部接收器設置,內部模擬部分調制信號,發送數據后,延遲6個位時鐘,接收         
  204.                         WriteRawRC(RFCfgReg,0x7F);        //4F  配置接收器  48dB最大增益         
  205.                         WriteRawRC(TReloadRegL,30);        //tmoLength);TReloadVal = 'h6a =tmoLength(dec)      
  206.                         WriteRawRC(TReloadRegH,0);        //實際值是OXD3E 這部分主要是設置定時器寄存器      
  207.                         WriteRawRC(TModeReg,0x8D);
  208.                         WriteRawRC(TPrescalerReg,0x3E);
  209.                         delay_ns(1000);
  210.                         PcdAntennaOn();
  211.                 }     
  212.         else {return 0xFE;}  
  213.         return MI_OK;
  214. }  

  215. //******************************************************************/
  216. //開啟天線發射  
  217. //每次啟動或關閉天險發射之間應至少有1ms的間隔
  218. //******************************************************************/
  219. void PcdAntennaOn()
  220. {
  221.   unsigned char i;
  222.   WriteRawRC(TxASKReg,0x40)       ;
  223.   delay_us(10)                       ;
  224.   i = ReadRawRC(TxControlReg)     ;
  225.   if(!(i&0x03))
  226.     SetBitMask(TxControlReg, 0x03);
  227.   i=ReadRawRC(TxASKReg)       ;
  228. }


  229. //******************************************************************/
  230. //關閉天線發射
  231. //******************************************************************/
  232. void PcdAntennaOff()
  233. {
  234.   ClearBitMask(TxControlReg, 0x03);
  235. }

  236. //******************************************************************/
  237. //功    能:通過RC522和ISO14443卡通訊
  238. //參數說明:Command[IN]:RC522命令字
  239. //          pInData[IN]:通過RC522發送到卡片的數據
  240. //          InLenByte[IN]:發送數據的字節長度
  241. //          pOutData[OUT]:接收到的卡片返回數據
  242. //          *pOutLenBit[OUT]:返回數據的位長度
  243. //******************************************************************/
  244. char PcdComMF522(unsigned char Command  ,unsigned char *pInData ,
  245.                  unsigned char InLenByte,unsigned char *pOutData,
  246.                  unsigned int  *pOutLenBit                       )
  247. {
  248.   char status = MI_ERR                          ;
  249.   unsigned char irqEn   = 0x00                  ;
  250.   unsigned char waitFor = 0x00                  ;
  251.   unsigned char lastBits                        ;
  252.   unsigned char n                               ;
  253.   unsigned int  i                               ;
  254.   switch (Command)
  255.   {
  256.     case PCD_AUTHENT:
  257.       irqEn   = 0x12                            ;
  258.       waitFor = 0x10                            ;
  259.       break                                     ;
  260.     case PCD_TRANSCEIVE:
  261.       irqEn   = 0x77                            ;
  262.       waitFor = 0x30                            ;
  263.       break                                     ;
  264.     default:
  265.       break                                     ;
  266.   }
  267.   WriteRawRC(ComIEnReg,irqEn|0x80)              ; //
  268.   ClearBitMask(ComIrqReg,0x80)                  ;
  269.   WriteRawRC(CommandReg,PCD_IDLE)               ;
  270.   SetBitMask(FIFOLevelReg,0x80)                 ; // 清空FIFO
  271.   for(i=0; i<InLenByte; i++)
  272.     WriteRawRC(FIFODataReg,pInData[i])          ; // 數據寫入FIFO
  273.   WriteRawRC(CommandReg, Command)               ; // 命令寫入命令寄存器
  274.   if(Command == PCD_TRANSCEIVE)
  275.     SetBitMask(BitFramingReg,0x80)              ; // 開始發送     
  276.   i = 6000                                      ; //根據時鐘頻率調整,操作M1卡最大等待時間25ms
  277.   do
  278.   {
  279.     n = ReadRawRC(ComIrqReg)                    ;
  280.     i--                                         ;
  281.   }
  282.   while((i!=0)&&!(n&0x01)&&!(n&waitFor))        ;
  283.   ClearBitMask(BitFramingReg,0x80)              ;
  284.   if(i!=0)
  285.   {
  286.     if(!(ReadRawRC(ErrorReg)&0x1B))
  287.     {
  288.       status = MI_OK                            ;
  289.       if (n&irqEn&0x01)
  290.         status = MI_NOTAGERR                    ;
  291.       if(Command==PCD_TRANSCEIVE)
  292.       {
  293.         n = ReadRawRC(FIFOLevelReg)             ;
  294.         lastBits = ReadRawRC(ControlReg)&0x07   ;
  295.         if(lastBits)
  296.           *pOutLenBit = (n-1)*8 + lastBits      ;
  297.         else
  298.           *pOutLenBit = n*8                     ;
  299.         if(n==0)
  300.           n = 1                                 ;
  301.         if(n>MAXRLEN)
  302.           n = MAXRLEN                           ;
  303.         for (i=0; i<n; i++)
  304.           pOutData[i] = ReadRawRC(FIFODataReg)  ;
  305.       }
  306.     }
  307.     else
  308.       status = MI_ERR                           ;        
  309.   }
  310.   SetBitMask(ControlReg,0x80)                   ;// stop timer now
  311.   WriteRawRC(CommandReg,PCD_IDLE)               ;
  312.   return status;
  313. }

  314. //******************************************************************/
  315. //功    能:尋卡                                                    /
  316. //參數說明: req_code[IN]:尋卡方式                                   /
  317. //                0x52 = 尋感應區內所有符合14443A標準的卡           /
  318. //                0x26 = 尋未進入休眠狀態的卡                       /
  319. //                pTagType[OUT]:卡片類型代碼                       /
  320. //                0x4400 = Mifare_UltraLight                        /
  321. //                0x0400 = Mifare_One(S50)                          /
  322. //                0x0200 = Mifare_One(S70)                          /
  323. //                0x0800 = Mifare_Pro(X)                            /
  324. //                0x4403 = Mifare_DESFire                           /
  325. //返    回: 成功返回MI_OK                                           /
  326. //******************************************************************/
  327. char PcdRequest(unsigned char req_code,unsigned char *pTagType)
  328. {
  329.   char status                                        ;  
  330.   unsigned int  unLen                                ;
  331.   unsigned char ucComMF522Buf[MAXRLEN]               ;

  332.   ClearBitMask(Status2Reg,0x08)                      ;//清除MRCrypto1on,要用軟件清零
  333.   WriteRawRC(BitFramingReg,0x07)                     ;//startsend=0,rxalign=0,在FIFO中存放的位置,TXlastbit=7
  334.   SetBitMask(TxControlReg,0x03)                      ;//TX2rfen=1,TX1RFen=1,傳遞調制的13.56MHZ的載波信號

  335.   ucComMF522Buf[0] = req_code                        ;

  336.   status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen       );
  337.   if ((status == MI_OK) && (unLen == 0x10))
  338.   {   
  339.     *pTagType     = ucComMF522Buf[0]                 ;
  340.     *(pTagType+1) = ucComMF522Buf[1]                 ;
  341.   }
  342.   else
  343.     status = MI_ERR                                  ;
  344.   return status                                      ;
  345. }

  346. //******************************************************************/
  347. //功    能:防沖撞                                                  /
  348. //參數說明: pSnr[OUT]:卡片序列號,4字節                             /
  349. //返    回: 成功返回MI_OK                                           /
  350. //******************************************************************/
  351. char PcdAnticoll(unsigned char *pSnr)
  352. {
  353.     char status;
  354.     unsigned char i,snr_check=0;
  355.     unsigned int  unLen;
  356.     unsigned char ucComMF522Buf[MAXRLEN];
  357.    
  358.     ClearBitMask(Status2Reg,0x08);//清除MRCrypto1on,要用軟件清零
  359.     WriteRawRC(BitFramingReg,0x00);//表示最后一個字節所有位都發送
  360.     ClearBitMask(CollReg,0x80);//CollRegCollReg0沖突結束后沖突位被置零

  361.     ucComMF522Buf[0] = PICC_ANTICOLL1;
  362.     ucComMF522Buf[1] = 0x20;

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

  364.     if (status == MI_OK)
  365.     {
  366.              for (i=0; i<4; i++)
  367.          {   
  368.              *(pSnr+i)  = ucComMF522Buf[i];
  369.              snr_check ^= ucComMF522Buf[i];
  370.          }
  371.          if (snr_check != ucComMF522Buf[i])
  372.          {   status = MI_ERR;    }
  373.     }
  374.    
  375.     SetBitMask(CollReg,0x80);//CollRegCollReg 在106kbps良好的防沖突情況下該位置1
  376.     return status;
  377. }

  378. /////////////////////////////////////////////////////////////////////
  379. //功    能:選定卡片
  380. //參數說明: pSnr[IN]:卡片序列號,4字節
  381. //返    回: 成功返回MI_OK
  382. /////////////////////////////////////////////////////////////////////
  383. char PcdSelect(unsigned char *pSnr)
  384. {
  385.     char status;
  386.     unsigned char i;
  387.     unsigned int  unLen;
  388.     unsigned char ucComMF522Buf[MAXRLEN];
  389.    
  390.     ucComMF522Buf[0] = PICC_ANTICOLL1;
  391.     ucComMF522Buf[1] = 0x70;
  392.     ucComMF522Buf[6] = 0;
  393.     for (i=0; i<4; i++)
  394.     {
  395.             ucComMF522Buf[i+2] = *(pSnr+i);
  396.             ucComMF522Buf[6]  ^= *(pSnr+i);
  397.     }
  398.     CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);
  399.   
  400.     ClearBitMask(Status2Reg,0x08);//清零MFcryon

  401.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);
  402.    
  403.     if ((status == MI_OK) && (unLen == 0x18))
  404.     {   status = MI_OK;  }
  405.     else
  406.     {   status = MI_ERR;    }

  407.     return status;
  408. }

  409. //******************************************************************/
  410. //功    能:驗證卡片密碼
  411. //參數說明: auth_mode[IN]: 密碼驗證模式
  412. //                 0x60 = 驗證A密鑰
  413. //                 0x61 = 驗證B密鑰
  414. //          addr[IN]:塊地址
  415. //          pKey[IN]:密碼
  416. //          pSnr[IN]:卡片序列號,4字節
  417. //返    回: 成功返回MI_OK
  418. //******************************************************************/
  419. char PcdAuthState(unsigned char auth_mode,unsigned char addr,
  420.                   unsigned char *pKey,unsigned char *pSnr    )
  421. {
  422.     char status;
  423.     unsigned int  unLen;
  424.     unsigned char i,ucComMF522Buf[MAXRLEN];

  425.     ucComMF522Buf[0] = auth_mode;//驗證A密鑰
  426.     ucComMF522Buf[1] = addr;//addr[IN]:塊地址
  427.     for (i=0; i<6; i++)
  428.     {    ucComMF522Buf[i+2] = *(pKey+i);   }
  429.     for (i=0; i<6; i++)
  430.     {    ucComMF522Buf[i+8] = *(pSnr+i);   }
  431.    
  432.     status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);
  433.     if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
  434.     {   status = MI_ERR;   }
  435.    
  436.     return status;
  437. }

  438. //******************************************************************/
  439. //功    能:讀取M1卡一塊數據
  440. //參數說明: addr[IN]:塊地址
  441. //          pData[OUT]:讀出的數據,16字節
  442. //返    回: 成功返回MI_OK
  443. //******************************************************************/
  444. char PcdRead(unsigned char addr,unsigned char *pData)
  445. {
  446.     char status                                          ;
  447.     unsigned int  unLen                                  ;
  448.     unsigned char i,ucComMF522Buf[MAXRLEN]               ;

  449.     ucComMF522Buf[0] = PICC_READ                         ;
  450.     ucComMF522Buf[1] = addr                              ;
  451.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2])       ;   
  452.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,
  453.                          ucComMF522Buf,&unLen           );
  454.     if ((status == MI_OK) && (unLen == 0x90))
  455.     {
  456.         for (i=0; i<16; i++)
  457.             *(pData+i) = ucComMF522Buf[i];   
  458.     }
  459.     else
  460.       status = MI_ERR;      
  461.     return status;
  462. }

  463. //******************************************************************/
  464. //功    能:讀取M1卡一塊數據
  465. //參數說明: addr[IN]:塊地址
  466. //          pData[OUT]:讀出的數據,16字節
  467. //返    回: 成功返回MI_OK
  468. //******************************************************************/
  469. char Read_Block(unsigned char Block,unsigned char *Buf)
  470. {
  471.   char result                                             ;
  472.   result = PcdAuthState(0x60,Block,Password_Buffer,UID)   ;
  473.   if(result!=MI_OK)
  474.     return result                                         ;
  475.   result = PcdRead(Block,Buf)                             ;
  476. //  return result; // 2011.01.03
  477.   
  478.   if(result!=MI_OK)     return   result                   ;
  479.   if(Block!=0x00&&des_on)
  480.   {
  481. //     Des_Decrypt((char *)Buf    ,KK,(char *)Buf    )       ;
  482. //     Des_Decrypt((char *)&Buf[8],KK,(char *)&Buf[8])       ;  
  483.   }
  484.   return SUCCESS                                          ;
  485. }

  486. //******************************************************************/
  487. //功    能:寫數據到M1卡一塊
  488. //參數說明: addr[IN]:塊地址
  489. //          pData[IN]:寫入的數據,16字節
  490. //返    回: 成功返回MI_OK
  491. //******************************************************************/
  492. char PcdWrite(unsigned char addr,unsigned char *pData)
  493. {
  494.   char status                                             ;
  495.   unsigned int  unLen                                     ;
  496.   unsigned char i,ucComMF522Buf[MAXRLEN]                  ;
  497.    
  498.   ucComMF522Buf[0] = PICC_WRITE                           ;
  499.   ucComMF522Buf[1] = addr                                 ;
  500.   CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2])          ;
  501.   status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,
  502.                        ucComMF522Buf,&unLen          )    ;
  503.   if(  ( status != MI_OK)||(unLen != 4)
  504.      ||((ucComMF522Buf[0]&0x0F)!= 0x0A))
  505.     status = MI_ERR                                       ;           
  506.   if (status == MI_OK)
  507.   {
  508.     for (i=0; i<16; i++)
  509.       ucComMF522Buf[i] = *(pData+i)                       ;  
  510.     CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16])      ;
  511.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,
  512.                          18,ucComMF522Buf,&unLen     )    ;
  513.     if(  (status != MI_OK)||(unLen != 4 )
  514.        ||((ucComMF522Buf[0]&0x0F)!= 0x0A))
  515.       status = MI_ERR                                     ;   
  516.   }   
  517.   return status                                           ;
  518. }
  519. //******************************************************************/
  520. //功    能:寫數據到M1卡一塊
  521. //參數說明: addr[IN]:塊地址
  522. //          pData[IN]:寫入的數據,16字節
  523. //返    回: 成功返回MI_OK
  524. //******************************************************************/

  525. //******************************************************************/
  526. //用MF522計算CRC16函數
  527. //******************************************************************/
  528. void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData)
  529. {
  530.     unsigned char i,n;
  531.     ClearBitMask(DivIrqReg,0x04);
  532.     WriteRawRC(CommandReg,PCD_IDLE);//取消當前命令
  533.     SetBitMask(FIFOLevelReg,0x80);//FlushBuffer 清除ErrReg 的標志位
  534.     for (i=0; i<len; i++)
  535.     {   WriteRawRC(FIFODataReg, *(pIndata+i));   }
  536.     WriteRawRC(CommandReg, PCD_CALCCRC);
  537.     i = 0xFF;
  538.     do
  539.     {
  540.         n = ReadRawRC(DivIrqReg);
  541.         i--;
  542.     }
  543.     while ((i!=0) && !(n&0x04));//當CRCIRq所有數據被處理完畢該位置位
  544.     pOutData[0] = ReadRawRC(CRCResultRegL);//顯示計算出來的CRC值
  545.     pOutData[1] = ReadRawRC(CRCResultRegM);
  546. }


  547. //==============================================================================
  548. //讀取卡的類型
  549. //讀取卡的ID號
  550. // 卡片:12AAD52D
  551. // 卡環:EC838322
  552. //==============================================================================
  553. void ReaderCard(void)
  554. {
  555.         char temp_value;
  556.         if(PcdRequest(PICC_REQALL,Temp)==MI_OK)        //選卡
  557.         {
  558.                 if(Temp[0]==0x04&&Temp[1]==0x00)  
  559.                                 printf("MFOne-S50");
  560.                 else if(Temp[0]==0x02&&Temp[1]==0x00)
  561.                         printf("MFOne-S70");
  562.                 else if(Temp[0]==0x44&&Temp[1]==0x00)
  563.                         printf("MF-UltraLight");
  564.                 else if(Temp[0]==0x08&&Temp[1]==0x00)
  565.                         printf("MF-Pro");
  566.                 else if(Temp[0]==0x44&&Temp[1]==0x03)
  567.                         printf("MF Desire");
  568.                 else
  569.                         printf("Unknown");
  570.                 if(PcdAnticoll(UID)==MI_OK)                        //防沖撞
  571.                 {
  572.                         printf("Card Id is:");
  573.                         /* 獲取卡值  */
  574.                         Uart1_SendHexDisplay(UID[0]);
  575.                         Uart1_SendHexDisplay(UID[1]);
  576.                         Uart1_SendHexDisplay(UID[2]);
  577.                         Uart1_SendHexDisplay(UID[3]);
  578.                         printf("\r\n");                //發送換行指令
  579.                         temp_value = ((UID[0]>>4)*10+(UID[0]&0x0f));
  580.                         printf("管理員:%d\r\n",temp_value);
  581. //                        switch(temp_value)
  582. //                        {
  583. //                                case 12 : printf("管理員:%d\r\n",temp_value);    break;
  584. //                                case 152: printf("學生  :%d\r\n",temp_value);    break;
  585. //                                default : printf("無效卡:%d\r\n",temp_value);    break;
  586. //                        }                                    
  587.                 }
  588.   }
  589. }
復制代碼
全部程序51hei下載地址:
RFID_RC522.7z (195.99 KB, 下載次數: 395)

評分

參與人數 2黑幣 +65 收起 理由
殺死比亞 + 15 很給力!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:218113 發表于 2021-1-27 14:54 | 只看該作者
感謝老鐵,資料非常好。謝謝了
回復

使用道具 舉報

板凳
ID:210139 發表于 2021-2-7 10:59 | 只看該作者
很不錯,在網上很少有直接移植,就能成功程序,樓主的很不錯,燒錄好以后就能直接用
回復

使用道具 舉報

地板
ID:884825 發表于 2021-2-19 10:10 | 只看該作者
太感謝了,驅動移植很方便
回復

使用道具 舉報

5#
ID:890184 發表于 2021-4-27 01:22 | 只看該作者
樓主您好,我怎么找不到Uart1_SendHexDisplay這個函數的定義。您能告訴我嗎?
回復

使用道具 舉報

6#
ID:933937 發表于 2022-3-24 15:09 | 只看該作者
我想知道實物實現需要買什么硬件,或者說識別模塊
回復

使用道具 舉報

7#
ID:528966 發表于 2022-10-18 13:49 | 只看該作者
樓主的很不錯,燒錄好以后就能直接用
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产美女一区二区 | 91免费在线视频 | 国产99久久精品一区二区永久免费 | 日本高清视频在线播放 | 99精品欧美一区二区三区综合在线 | 久久亚洲一区二区三 | 亚洲一区中文字幕在线观看 | 日韩综合在线视频 | 国产精品99 | 色综合久久88色综合天天 | 久久精品成人热国产成 | 国产成人一区二区三区 | 日韩久久久久久久 | 久久综合国产精品 | 一级高清视频 | 欧美 视频 | 在线免费av观看 | 日日av| 在线免费观看成人 | 91美女视频 | 日韩免费视频一区二区 | 在线国产一区二区 | 波多野结衣一区二区三区在线观看 | 最新日韩欧美 | 三级av在线 | 亚洲a级 | 国产欧美日韩精品一区 | 久久久.com | 精品视频一区二区三区 | 国产成人精品综合 | 中文字幕一级 | 日韩一区二区在线视频 | 黄色精品| 超碰最新在线 | av中文字幕在线播放 | 毛片免费观看 | 国产精品视频一区二区三区不卡 | 亚洲一级在线 | 日韩免费一区二区 | 日韩伦理电影免费在线观看 | 国产在线精品一区二区三区 |