|
RFID MFRC522資料
單片機(jī)源程序如下:
- #include "rc522.h"
- #include "SPI.h"
- #include "stm32f10x.h"
- #include "delay.h"
- #include <string.h>
- #include <stdio.h> //sprintf頭文件
- #include "hw_config.h"
- /*************************************
- * 使用SPI與RC522通信
- *
- *
- **************************************/
- /********************************************************************************
- *函數(shù)功能:SPI發(fā)送數(shù)據(jù)
- *參數(shù):待發(fā)送的數(shù)據(jù)
- *返回值:無(wú)
- *
- **********************************************************************************/
- void RC522_Send(u8 byte)
- {
- u8 counter;
- for(counter=0;counter<8;counter++)
- {
- if ( byte & 0x80 )
- RC522_MOSI_H();
- else
- RC522_MOSI_L();
- Delay_us(200);
- RC522_SCK_L();
- Delay_us(200);
- RC522_SCK_H();
- Delay_us(200);
- byte <<= 1;
- }
- }
- /*******************************************************************************************
- *函數(shù)功能:SPI讀函數(shù)
- *參數(shù):無(wú)
- *返回值:讀到的數(shù)據(jù)
- *
- ********************************************************************************************/
- u8 RC522_Read( void )
- {
- u8 counter;
- u8 Data;
- for(counter=0;counter<8;counter++)
- {
- Data <<= 1;
- RC522_SCK_L();
- Delay_us(200);
- if (RC522_MISO_int() == 1)
- Data |= 0x01;
- Delay_us(200);
- RC522_SCK_H();
- Delay_us(200);
- }
- return Data;
-
- }
- /******************************************************************************************
- *函數(shù)功能:讀RC522寄存器
- *參數(shù):address 寄存器的地址
- *返回值:寄存器的當(dāng)前值
- *
- ******************************************************************************************/
- //用SPI讀RC522的數(shù)據(jù)格式是 0x msb(控制位 1位) 地址(6位) 日志(1位),
- //舉個(gè)例子 讀地址 0x0000 0110 的數(shù)據(jù)就要把他轉(zhuǎn)換成 0x1000 1100,首位1代表讀,0是寫,最后一位0是日志是規(guī)定。
- //隨意左移一位是確定地址,& 0x0111 1110(7e)的作用是保證此操作只有地址沒(méi)有變成奇奇怪怪的東西。然后 | 0x1000 0000 (80)就是確定第一位是1,也就是讀數(shù)據(jù)。
- //具體內(nèi)容看官方的 《MFCR522數(shù)據(jù)手冊(cè)》 10.2 章節(jié),中文文檔可能不太一樣
- u8 ReadRC(u8 address )
- {
- u8 Addr, Return;
- Addr=((address<<1)&0x7E)|0x80;//變化成有效的地址形式,最低位為0,最高位為1時(shí)候是,從MFRC522讀出數(shù)據(jù)。
- RC522_CS_Enable();
- RC522_Send(Addr);
- Return=RC522_Read();
- RC522_CS_Disable();
- return Return;
- }
- /*******************************************************************************************
- *函數(shù)功能:寫RC522寄存器
- *參數(shù):Addresss 寄存器的地址
- Value 寫入寄存器的值
- *返回值:無(wú)
- *******************************************************************************************/
- void WriteRawRC(u8 Address,u8 Value)
- {
- u8 Addr;
-
- Addr =(Address<<1)&0x7E;//變化成有效的地址形式,最低位為0,最高位為0時(shí)候是,從MFRC522寫入數(shù)據(jù)。
-
- RC522_CS_Enable();
-
- RC522_Send(Addr);
-
- RC522_Send(Value);
-
- RC522_CS_Disable();
- }
- /*******************************************************************************************
- *函數(shù)功能:對(duì)RC522寄存器置位
- *參數(shù):Reg 寄存器的紙質(zhì)
- mask 置位的值
- *返回值:無(wú)
- *******************************************************************************************/
- void SetBitMask(u8 Reg,u8 Mask )
- {
- u8 Temp;
- Temp=ReadRC(Reg);
- WriteRawRC(Reg,Temp|Mask); // set bit mask
- }
- /*******************************************************************************************
- *函數(shù)功能:對(duì)RC522寄存器清零
- *參數(shù):Reg RC522的地址
- Mask 清零的數(shù)據(jù)
- *返回值:無(wú)
- *******************************************************************************************/
- //讀取寄存器reg,保存在temp中;
- //將mask取反后與temp的內(nèi)容作與運(yùn)算,運(yùn)算結(jié)果寫回寄存器reg中;
- //mask取反后原先為1的位變0,為0的位變1,所以、與運(yùn)算后temp中對(duì)應(yīng)mask中最初為1的位就被清零。
- void ClearBitMask(u8 Reg,u8 Mask )
- {
- u8 Temp;
- Temp=ReadRC(Reg);
- WriteRawRC(Reg,Temp&(~Mask)); // clear bit mask
-
- }
- /*******************************************************************************************
- *函數(shù)功能:開天線
- *參數(shù):無(wú)
- *返回值:無(wú)
- *
- ********************************************************************************************/
- void PcdAntennaOn(void)
- {
- u8 temp;
-
- temp=ReadRC(TxControlReg);
-
- if (!(temp&0x03))
- SetBitMask(TxControlReg,0x03);
- }
- /*******************************************************************************************
- *函數(shù)功能:關(guān)閉天線
- *參數(shù):無(wú)
- *返回值:
- *
- *******************************************************************************************/
- void PcdAntennaOff ( void )
- {
- ClearBitMask(TxControlReg,0x03 );
- }
- /*******************************************************************************************
- *函數(shù)功能:復(fù)位RC522
- *參數(shù):無(wú)
- *返回值:無(wú)
- *
- *******************************************************************************************/
- void PcdReset(void)
- {
- RC522_Reset_Disable();
-
- Delay_us(1);
-
- RC522_Reset_Enable();
-
- Delay_us(1);
-
- RC522_Reset_Disable();
-
- Delay_us(1);
-
- WriteRawRC(CommandReg,0x0f);
-
- while(ReadRC(CommandReg)&0x10);
-
- Delay_us(1);
-
- WriteRawRC(ModeReg, 0x3D ); //定義發(fā)送和接收常用模式 和Mifare卡通訊,CRC初始值0x6363
-
- WriteRawRC(TReloadRegL,30); //16位定時(shí)器低位
- WriteRawRC(TReloadRegH,0); //16位定時(shí)器高位
-
- WriteRawRC(TModeReg,0x8D); //定義內(nèi)部定時(shí)器的設(shè)置
-
- WriteRawRC(TPrescalerReg,0x3E); //設(shè)置定時(shí)器分頻系數(shù)
-
- WriteRawRC(TxAutoReg,0x40); //調(diào)制發(fā)送信號(hào)為100%ASK
-
- }
- /*******************************************************************************************
- *函數(shù)功能:設(shè)置RC522的工作方式
- *參數(shù):CardType:工作方式
- *返回值:無(wú)
- *
- *******************************************************************************************/
- void M500PcdConfigISOType(u8 CardType)
- {
- if (CardType== 'A') //ISO14443_A
- {
- ClearBitMask(Status2Reg,0x08);
-
- WriteRawRC(ModeReg,0x3D);//3F
-
- WriteRawRC(RxSelReg,0x86);//84
-
- WriteRawRC(RFCfgReg,0x7F); //4F
-
- WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec)
-
- WriteRawRC(TReloadRegH,0);
-
- WriteRawRC(TModeReg,0x8D);
-
- WriteRawRC(TPrescalerReg,0x3E);
-
- Delay_us(2);
- PcdAntennaOn();//開天線
-
- }
-
- }
- /*******************************************************************************************
- *函數(shù)功能:通過(guò)RC522和ISO14443卡通訊
- *參數(shù): Command,RC522的命令
- * intData,RC522發(fā)送到卡片的數(shù)據(jù)
- * intLen,發(fā)送數(shù)據(jù)的字節(jié)長(zhǎng)度
- * outData,接收到的卡片返回?cái)?shù)據(jù)
- * outLen,返回?cái)?shù)據(jù)的長(zhǎng)度
- *返回值:
- ********************************************************************************************/
- char PcdComMF522(u8 Command,u8 *intData,u8 intLen,u8 * Data,u32 * outLen )
- {
- char Status =Fault;
- u8 IrqEn = 0x00;
- u8 WaitFor = 0x00;
- u8 LastBits;
- u8 N;
- u32 L;
- switch (Command)
- {
- case PCD_AUTHENT: //Mifare認(rèn)證
- IrqEn=0x12; //允許錯(cuò)誤中斷請(qǐng)求ErrIEn 允許空閑中斷IdleIEn
- WaitFor=0x10; //認(rèn)證尋卡等待時(shí)候 查詢空閑中斷標(biāo)志位
- break;
-
- case PCD_TRANSCEIVE: //接收發(fā)送 發(fā)送接收
- IrqEn = 0x77; //允許TxIEn RxIEn IdleIEn LoAlertIEn ErrIEn TimerIEn
- WaitFor = 0x30; //尋卡等待時(shí)候 查詢接收中斷標(biāo)志位與 空閑中斷標(biāo)志位
- break;
-
- default:
- break;
-
- }
-
- WriteRawRC( ComIEnReg,IrqEn|0x80); //IRqInv置位管腳IRQ與Status1Reg的IRq位的值相反
- ClearBitMask( ComIrqReg,0x80 ); //Set1該位清零時(shí),CommIRqReg的屏蔽位清零
- WriteRawRC( CommandReg,PCD_IDLE ); //寫空閑命令
- SetBitMask( FIFOLevelReg,0x80); //置位FlushBuffer清除內(nèi)部FIFO的讀和寫指針以及ErrReg的BufferOvfl標(biāo)志位被清除
-
- for (L= 0; L<intLen;L++ )
- WriteRawRC(FIFODataReg,Data [L]); //寫數(shù)據(jù)進(jìn)FIFOdata
-
- WriteRawRC(CommandReg,Command); //寫命令
-
-
- if (Command==PCD_TRANSCEIVE )
- SetBitMask(BitFramingReg,0x80); //StartSend置位啟動(dòng)數(shù)據(jù)發(fā)送 該位與收發(fā)命令使用時(shí)才有效
-
- L= 1000;//根據(jù)時(shí)鐘頻率調(diào)整,操作M1卡最大等待時(shí)間25ms
-
- do //認(rèn)證 與尋卡等待時(shí)間
- {
- N = ReadRC ( ComIrqReg ); //查詢事件中斷
- L--;
- } while ((L!=0)&&(!(N&0x01))&&(!(N&WaitFor ) ) ); //退出條件i=0,定時(shí)器中斷,與寫空閑命令
-
- ClearBitMask ( BitFramingReg, 0x80 ); //清理允許StartSend位
-
- if (L!= 0 )
- {
- if ( ! ( ReadRC ( ErrorReg ) & 0x1B ) ) //讀錯(cuò)誤標(biāo)志寄存器BufferOfI CollErr ParityErr ProtocolErr
- {
- Status =True ;
-
- if ( N & IrqEn & 0x01 ) //是否發(fā)生定時(shí)器中斷
- Status =Irq_falg ;
-
- if (Command ==PCD_TRANSCEIVE )
- {
- N = ReadRC ( FIFOLevelReg ); //讀FIFO中保存的字節(jié)數(shù)
-
- LastBits = ReadRC(ControlReg ) & 0x07; //最后接收到得字節(jié)的有效位數(shù)
-
- if(LastBits )
- * outLen=(N - 1 )*8+LastBits; //N個(gè)字節(jié)數(shù)減去1(最后一個(gè)字節(jié))+最后一位的位數(shù) 讀取到的數(shù)據(jù)總位數(shù)
- else
- *outLen=N * 8; //最后接收到的字節(jié)整個(gè)字節(jié)有效
-
- if (N ==0)
- N = 1;
-
- if (N >max)
- N =max;
-
- for (L=0;L<N;L ++ )
- Data[L] =ReadRC(FIFODataReg );
-
- }
-
- }
-
- else
- Status =Fault;
-
- }
-
- SetBitMask ( ControlReg, 0x80 ); // stop timer now
- WriteRawRC ( CommandReg, PCD_IDLE );
-
-
- return Status;
-
-
- }
- /*******************************************************************************************
- *函數(shù)功能:尋卡
- *參數(shù):Card_code,尋卡方式
- * = 0x52,尋感應(yīng)區(qū)內(nèi)所有符合14443A標(biāo)準(zhǔn)的卡
- * = 0x26,尋未進(jìn)入休眠狀態(tài)的卡
- * CardType,卡片類型代碼
- * = 0x4400,Mifare_UltraLight
- * = 0x0400,Mifare_One(S50)
- * = 0x0200,Mifare_One(S70)
- * = 0x0800,Mifare_Pro(X))
- * = 0x4403,Mifare_DESFire
- * 返回值:1 ,成功 0,失敗
- *******************************************************************************************/
- char PcdRequest ( u8 Req_code, u8 * CardType )
- {
- char Status;
- u8 buffer[max];
- u32 Len;
-
- ClearBitMask ( Status2Reg, 0x08 ); //清理指示MIFARECyptol單元接通以及所有卡的數(shù)據(jù)通信被加密的情況
- WriteRawRC ( BitFramingReg, 0x07 ); // 發(fā)送的最后一個(gè)字節(jié)的 七位
- SetBitMask ( TxControlReg, 0x03 ); //TX1,TX2管腳的輸出信號(hào)傳遞經(jīng)發(fā)送調(diào)制的13.56的能量載波信號(hào)
- buffer[0] =Req_code; //存入 卡片命令字
- Status = PcdComMF522(PCD_TRANSCEIVE,buffer,1,buffer,&Len ); //尋卡
-
- if ((Status ==True)&&(Len == 0x10 ) ) //尋卡成功返回卡類型
- {
- * CardType=buffer[0];
- * (CardType+1)=buffer[1];
- }
-
- else
- Status =Fault;
- return Status;
-
- }
- /*******************************************************************************************
- *函數(shù)功能:防沖撞
- *參數(shù):接收ID號(hào)緩沖區(qū)
- *返回值:1,成功,0,失敗
- *
- ********************************************************************************************/
- char PcdAnticoll ( u8 * Snr )
- {
- char Status;
- u8 uc, Snr_check = 0;
- u8 buffer[max];
- u32 Len;
-
- ClearBitMask ( Status2Reg, 0x08 ); //清MFCryptol On位 只有成功執(zhí)行MFAuthent命令后,該位才能置位
- WriteRawRC ( BitFramingReg, 0x00); //清理寄存器 停止收發(fā)
- ClearBitMask ( CollReg, 0x80 ); //清ValuesAfterColl所有接收的位在沖突后被清除
-
- buffer[ 0 ] = 0x93; //卡片防沖突命令
- buffer[ 1 ] = 0x20;
-
- Status =PcdComMF522(PCD_TRANSCEIVE,buffer, 2,buffer,&Len);//與卡片通信
-
- if (Status==True ) //通信成功
- {
- for ( uc = 0; uc < 4; uc ++ )
- {
- * ( Snr + uc ) = buffer[ uc ]; //讀出UID
- Snr_check ^= buffer[ uc ];
- }
-
- if ( Snr_check !=buffer[ uc ] )
- Status =Fault;
-
- }
-
- SetBitMask ( CollReg, 0x80 );
-
-
- return Status;
-
-
- }
- /*******************************************************************************************
- 函數(shù)功能:用RC522計(jì)算CRC16
- 參數(shù):intdata,計(jì)算CRC16的數(shù)組
- Len,計(jì)算CRC16的數(shù)組字節(jié)長(zhǎng)度
- 0utData,存放計(jì)算結(jié)果存放的首地址
- *返回值:無(wú)
- *******************************************************************************************/
- void CalulateCRC ( u8 * intData, u8 Len, u8 * outData )
- {
- u8 k,j;
-
-
- ClearBitMask(DivIrqReg,0x04);
-
- WriteRawRC(CommandReg,PCD_IDLE);
-
- SetBitMask(FIFOLevelReg,0x80);
-
- for (k= 0;k<Len;k++)
- WriteRawRC ( FIFODataReg, * (intData +k) );
- WriteRawRC ( CommandReg, PCD_CALCCRC );
-
- k= 0xFF;
-
- do
- {
- j= ReadRC(DivIrqReg );
- k--;
- } while ( (k!= 0) && ! (j& 0x04 ) );
-
- outData[0] = ReadRC(CRCResultRegL);
- outData[1] = ReadRC(CRCResultRegM);
-
-
- }
- /*******************************************************************************************
- 函數(shù)功能:選定卡片
- 參數(shù):pSnr,卡片序列號(hào),4字節(jié)
- *返回值: 1,成功,0,失敗
- *
- ********************************************************************************************/
- char PcdSelect ( u8 * pSnr )
- {
- char ucN;
- u8 uc;
- u8 buffer[max];
- u32 ulLen;
-
-
- buffer[0] = PICC_ANTICOLL1;
- buffer[1] = 0x70;
- buffer[6] = 0;
-
- for ( uc = 0; uc < 4; uc ++ )
- {
- buffer[ uc + 2 ] = * ( pSnr + uc );
- buffer[ 6 ] ^= * ( pSnr + uc );
- }
-
- CalulateCRC (buffer, 7, &buffer[ 7 ] );
-
- ClearBitMask ( Status2Reg, 0x08 );
- ucN = PcdComMF522 ( PCD_TRANSCEIVE,buffer, 9,buffer, & ulLen );
-
- if ( ( ucN ==True ) && ( ulLen == 0x18 ) )
- ucN =True ;
- else
- ucN =Fault;
-
- return ucN;
-
-
- }
- /*******************************************************************************************
- *函數(shù)功能:驗(yàn)證卡片密碼
- *參數(shù):mode,密碼驗(yàn)證模式
- * 0x60,驗(yàn)證A密鑰
- * 0x61,驗(yàn)證B密鑰
- * u8 Addr,塊地址
- * Key,密碼
- * Str,卡片序列號(hào),4字節(jié)
- *返回值: 1,成功,0,失敗
- *******************************************************************************************/
- char PcdAuthState ( u8 mode, u8 Addr, u8 * Key, u8 * str )
- {
- char Status;
- u8 uc, buffer[max];
- u32 Len;
-
-
- buffer[ 0 ] =mode;
- buffer[ 1 ] = Addr;
-
- for ( uc = 0; uc < 6; uc ++ )
- buffer[uc + 2 ] = * ( Key + uc );
-
- for ( uc = 0; uc < 6; uc ++ )
- buffer[ uc + 8 ] = * (str + uc );
- Status = PcdComMF522 ( PCD_AUTHENT,buffer, 12,buffer, &Len );
-
- if ( ( Status !=True ) || ( ! ( ReadRC ( Status2Reg ) & 0x08 ) ) )
- Status =Fault;
-
-
- return Status;
-
-
- }
- /*******************************************************************************************
- *函數(shù)功能:寫數(shù)據(jù)到M1卡一塊
- *參數(shù):u8 addr,塊地址
- * Data,寫入的數(shù)據(jù),16字節(jié)
- *返回值:1,成功,0,失敗
- *******************************************************************************************/
- char PcdWrite ( u8 addr, u8 * Data )
- {
- char Status;
- u8 uc,buffer[max];
- u32 Len;
-
-
- buffer[ 0 ] = PICC_WRITE;
- buffer [ 1 ] =addr;
-
- CalulateCRC (buffer, 2, &buffer[ 2 ] );
-
- Status = PcdComMF522 ( PCD_TRANSCEIVE,buffer, 4,buffer, & Len );
- if ((Status != True )||(Len!=4)||((buffer[ 0 ] & 0x0F ) != 0x0A ) )
- Status =Fault;
-
- if (Status==True )
- {
- //memcpy(ucComMF522Buf, pData, 16);
- for ( uc = 0; uc < 16; uc ++ )
- buffer[uc] = * ( Data + uc );
-
- CalulateCRC ( buffer, 16, &buffer[ 16 ] );
- Status = PcdComMF522 ( PCD_TRANSCEIVE,buffer, 18,buffer,&Len );
-
- if ( ( Status != True )||(Len !=4)||((buffer[0]&0x0F)!=0x0A))
- Status =Fault;
-
- }
-
-
- return Status;
-
-
- }
- /*******************************************************************************************
- *函數(shù)功能:讀取M1卡一塊數(shù)據(jù)
- *參數(shù):u8 Aaddr,塊地址
- * Data,讀出的數(shù)據(jù),16字節(jié)
- *返回值:1,成功,0,失敗
- *
- ********************************************************************************************/
- char PcdRead (u8 addr,u8 *Data )
- {
- char Status;
- u8 L, buffer[max];
- u32 Len;
-
- buffer[0]=PICC_READ;
- buffer[1]=addr;
-
- CalulateCRC (buffer, 2, &buffer[ 2 ] );
-
- Status = PcdComMF522 ( PCD_TRANSCEIVE,buffer, 4,buffer,&Len );
-
- if ((Status==True ) && (Len == 0x90 ) )
- {
- for (L= 0; L< 16;L++ )
- * (Data+L) = buffer[L];
- }
-
- else
- Status =Fault;
-
-
- return Status;
-
- }
- /*******************************************************************************************
- *函數(shù)功能:命令卡片進(jìn)入休眠狀態(tài)
- *參數(shù):無(wú)
- *返回值:1,成功,0,失敗
- *
- ********************************************************************************************/
- char PcdHalt(void)
- {
- u8 buffer[max];
- u32 Len;
-
- buffer[0]=PICC_HALT;
- buffer[1]=0;
-
- CalulateCRC (buffer, 2, &buffer[ 2 ] );
- PcdComMF522(PCD_TRANSCEIVE,buffer, 4,buffer, &Len);
- return True ;
-
- }
- /****************************************************************************************************************
- *函數(shù)功能:RC522測(cè)試
- *參數(shù):無(wú)
- *返回值:無(wú)
- ******************************************************************************************************************/
- void RC522_test(void)
- {
- char Str[30];
- u8 Card_ID[4];
-
- while (1)
- {
-
- PcdRequest (PICC_REQALL, Card_ID); //尋卡 //若失敗再次尋卡
- if (PcdAnticoll(Card_ID)==True ) //防沖撞(當(dāng)有多張卡進(jìn)入讀寫器操作范圍時(shí),防沖突機(jī)制會(huì)從其中選擇一張進(jìn)行操作)
- {
- sprintf(Str,"\r\n門禁卡的ID號(hào): %02X%02X%02X%02X",Card_ID[0],Card_ID[1],Card_ID[2],Card_ID[3]);
-
- printf ("%s\r\n",Str);
-
- }
-
-
- }
-
- }
復(fù)制代碼
所有資料51hei提供下載:
金龍107RFID例程(20160721).7z
(349.26 KB, 下載次數(shù): 27)
2019-1-25 15:28 上傳
點(diǎn)擊文件名下載附件
RFID MFRC522 下載積分: 黑幣 -5
|
|