By 曙光单片机科技 RC522程序读书笔记 详细注释
// pSnr[IN]:卡片序列号,4字节 //返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdAuthState(unsigned char data auth_mode,unsigned char data addr,unsigned char *pKey,unsigned char *pSnr) {
char data status;
unsigned int data unLen;
unsigned char data i,ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = auth_mode; //验证A密钥 ucComMF522Buf[1] = addr; //addr[IN]:块地址 for (i=0; i<6; i++)
{ ucComMF522Buf[i+2] = *(pKey+i); } for (i=0; i<6; i++)
{ ucComMF522Buf[i+8] = *(pSnr+i); } // memcpy(&ucComMF522Buf[2], pKey, 6); // memcpy(&ucComMF522Buf[8], pSnr, 4);
status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen); if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08))) { status = MI_ERR; }
return status; }
///////////////////////////////////////////////////////////////////// //功 能:读取M1卡一块数据 //参数说明: addr[IN]:块地址
// pData[OUT]:读出的数据,16字节 //返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdRead(unsigned char data addr,unsigned char *pData) {
char data status;
unsigned int data unLen;
unsigned char data i,ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_READ; ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
status =
By 曙光单片机科技 RC522程序读书笔记 详细注释
PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen); if ((status == MI_OK) && (unLen == 0x90))
// { memcpy(pData, ucComMF522Buf, 16); } {
for (i=0; i<16; i++)
{ *(pData+i) = ucComMF522Buf[i]; } } else
{ status = MI_ERR; }
return status; }
///////////////////////////////////////////////////////////////////// //功 能:写数据到M1卡一块 //参数说明: addr[IN]:块地址
// pData[IN]:写入的数据,16字节 //返 回: 成功返回MI_OK
///////////////////////////////////////////////////////////////////// char PcdWrite(unsigned char data addr,unsigned char *pData) {
char data status;
unsigned int data unLen;
unsigned char data i,ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_WRITE; ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
status
PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) { status = MI_ERR; }
if (status == MI_OK) {
//memcpy(ucComMF522Buf, pData, 16); for (i=0; i<16; i++) { ucComMF522Buf[i] = *(pData+i); }
CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);
=
By 曙光单片机科技 RC522程序读书笔记 详细注释
status
PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen); if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) { status = MI_ERR; } }
return status; }
///////////////////////////////////////////////////////////////////// //功 能:命令卡片进入休眠状态 //返 回: 成功返回MI_OK
///////////////////////////////////////////////////////////////////// char PcdHalt(void) {
char data status;
unsigned int data unLen;
unsigned char data ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_HALT; ucComMF522Buf[1] = 0;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
status
PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
return MI_OK; }
///////////////////////////////////////////////////////////////////// //用MF522计算CRC16函数
/////////////////////////////////////////////////////////////////////
void CalulateCRC(unsigned char *pIndata,unsigned char data len,unsigned char *pOutData) {
unsigned char data i,n;
ClearBitMask(DivIrqReg,0x04);
WriteRawRC(CommandReg,PCD_IDLE); //取消当前命令 SetBitMask(FIFOLevelReg,0x80); //FlushBuffer 清除ErrReg 的标志位 for (i=0; i { WriteRawRC(FIFODataReg, *(pIndata+i)); } WriteRawRC(CommandReg, PCD_CALCCRC); i = 0xFF; do { = = By 曙光单片机科技 RC522程序读书笔记 详细注释 n = ReadRawRC(DivIrqReg); i--; } while ((i!=0) && !(n&0x04)); //当CRCIRq 所有数据被处理完毕该位置位 pOutData[0] = ReadRawRC(CRCResultRegL); //显示计算出来的CRC值 pOutData[1] = ReadRawRC(CRCResultRegM); } ///////////////////////////////////////////////////////////////////// //功 能:复位RC522 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// char PcdReset(void) { //PORTD|=(1< WriteRawRC(CommandReg,PCD_RESETPHASE);//#define PCD_RESETPHASE 0x0F //复位 delay_ns(10); WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363 WriteRawRC(TReloadRegL,30); //定时器的低8位数据, WriteRawRC(TReloadRegH,0); //定时器的高8位数据, WriteRawRC(TModeReg,0x8D); //定时器模式寄存器,定时器减值计数 WriteRawRC(TPrescalerReg,0x3E); //实际值是OXD3E 这部分主要是设置定时器寄存器,############## WriteRawRC(TxAutoReg,0x40);//必须要 ,设置逻辑1,强制100%ASK调制 return MI_OK; } ////////////////////////////////////////////////////////////////////// //设置RC522的工作方式 ////////////////////////////////////////////////////////////////////// char M500PcdConfigISOType(unsigned char data type) { if (type == 'A') //ISO14443_A By 曙光单片机科技 RC522程序读书笔记 详细注释 { ClearBitMask(Status2Reg,0x08); //状态2寄存器 WriteRawRC(ModeReg,0x3D);//3F //和Mifare卡通讯,CRC初始值0x6363 WriteRawRC(RxSelReg,0x86);//84 选择内部接收器设置,内部模拟部分调制信号,发送数据后,延迟6个位时钟,接收 WriteRawRC(RFCfgReg,0x7F); //4F 配置接收器 48dB最大增益 WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec) WriteRawRC(TReloadRegH,0); //实际值是OXD3E 这部分主要是设置定时器寄存器,############## WriteRawRC(TModeReg,0x8D); WriteRawRC(TPrescalerReg,0x3E); delay_ns(1000); PcdAntennaOn(); } else{ return -1; } return MI_OK; } ///////////////////////////////////////////////////////////////////// //功 能:读RC522寄存器 //参数说明:Address[IN]:寄存器地址 //返 回:读出的值 ///////////////////////////////////////////////////////////////////// unsigned char ReadRawRC(unsigned char data Address) { unsigned char data ucAddr; unsigned char data ucResult=0; CLR_SPI_CS; ucAddr = ((Address<<1)&0x7E)|0x80;//变化成有效的地址形式,最低位为0,最高位为1时候是,从MFRC522读出数据,参考39页 SPIWriteByte(ucAddr); ucResult=SPIReadByte(); SET_SPI_CS; return ucResult; } ///////////////////////////////////////////////////////////////////// //功 能:写RC632寄存器 //参数说明:Address[IN]:寄存器地址 // value[IN]:写入的值 ///////////////////////////////////////////////////////////////////// void WriteRawRC(unsigned char data Address, unsigned char data value) {