RC522模块学习

article/2025/8/23 1:16:38

目录

1.原理简介

2.SPI通信

3.获取卡号实验

3.驱动函数


参考:

https://www.cnblogs.com/ivantang/p/3904025.html

https://xiaolong.blog.csdn.net/article/details/117075834?spm=1001.2014.3001.5506

https://blog.csdn.net/weixin_47316662/article/details/124555292?spm=1001.2014.3001.5506

https://blog.csdn.net/qq_40574123/article/details/116722010?spm=1001.2014.3001.5506
https://yourcee.blog.csdn.net/article/details/107832198?spm=1001.2014.3001.5506


 

1.原理简介

       RC522 是一种非接触式读写卡芯片,底层采用SPI模拟时序,可以应用于校园一卡通、水卡充值消费、公交卡充值消费设计、门禁卡等。

       有两个部分,射频读写器和IC卡。射频读写器向IC卡发一组固定频率的电磁波,卡片内有一个LC串联谐振电路,其频率与读写器发射的频率相同,这样在电磁波激励下,LC谐振电路产生共振,从而使电容内有了电荷;在这个电荷的另一端,接有一个单向导通的电子泵,将电容内的电荷送到另一个电容内存储,当所积累的电荷达到2V时,此电容可作为电源为其它电路提供工作电压,将卡内数据发射出去或接受读写器的数据。

      非接触性IC卡与读卡器之间通过无线电波来完成读写操作。二者之间的通讯频率为13.56MHZ。非接触性IC卡本身是无源卡,当读写器对卡进行读写操作时,读写器发出的信号由两部分叠加组成:一部分是电源信号,该信号由卡接收后,与本身的L/C产生一个瞬间能量来供给芯片工作。另一部分则是指令和数据信号,指挥芯片完成数据的读取、修改、储存等,并返回信号给读写器,完成一次读写操作。

流程:

复位应答:M1射频卡的通讯协议和通讯波特率是定义好的,当有卡片进入读写器的操作范围时,读写器以特定的协议与它通讯,从而确定该卡是否为M1射频卡,即验证卡片的卡型。

防冲突机制:当有多张卡进入读写器操作范围时,防冲突机制会从其中选择一张进行操作,未选中的则处于空闲模式等待下一次选卡,该过程会返回被选卡的序列号。

选择卡片:选择被选中的卡的序列号,并同时返回卡的容量代码。

三次互相确认:选定要处理的卡片之后,读写器就确定要访问的扇区号,并对该扇区密码进行密码校验,在三次相互认证之后就可以通过加密流进行通讯。(在选择另一扇区时,则必须进行另一扇区密码校验。)

如果概括来说的话,主要也就四部分:开关连接、寻卡、验证密码、读取。

2.SPI通信

数据由MISO端口到RC52寄存器,RC522寄存器MOSI端口

软件SPI通过控制MISO引脚和MOSI端口引脚的高低电平来控制数据的进出,下面读取和写入寄存器的函数都是靠这两个函数来接收和发送数据与外界

 RC552采用模式3,上图为模式3的时序图,根据时序图写发送数据,共有8个时钟周期,所以循环8次, 按位查询需要发送的数据的高低电平,0MOSI引输出低电平,1MOSI输出高电平,然后调SCK时钟引脚,使时钟引脚输出低电平(默认状态高电平),延时一会,输出高电平。

void SPI_RC522_SendByte ( uint8_t byte )
{uint8_t counter;for(counter=0;counter<8;counter++){     if ( byte & 0x80 )RC522_MOSI_1 ();else RC522_MOSI_0 ();RC522_DELAY();RC522_SCK_0 ();RC522_DELAY();RC522_SCK_1();RC522_DELAY();byte <<= 1; } 	
}/*** @brief  从RC522发送1 Byte 数据* @param  无* @retval RC522返回的数据*/
uint8_t SPI_RC522_ReadByte ( void )
{uint8_t counter;uint8_t SPI_Data;for(counter=0;counter<8;counter++){SPI_Data <<= 1;RC522_SCK_0 ();RC522_DELAY();if ( RC522_MISO_GET() == 1)SPI_Data |= 0x01;RC522_DELAY();RC522_SCK_1 ();RC522_DELAY();}return SPI_Data;}

3.获取卡号实验

假设我们写522代码的目的是为了设计一个门禁系统,那有个问题是:我们需要从ic中读出什么数据?什么数据又是正确的数据?

卡片内部有块地址,它用于存放厂商代码,已经固化,不可更改。这样一个东西,叫做UID,这是一个存储在ic中的不可更改的数据,他是一个4字节16进制数,所以我们将他作为我们的判断依据。

开发板采用正点原子mini板,主控芯片为stm32F103RCT6

stm使用引脚

引脚名称使用功能定义
PB0普通的GPIO口,用于复位RC522
PA6SPI1的MISO
PA7SPI1的MOSI
PA5SPI1的SCK
PA4普通的GPIO口,用于RC522的片选端口

RC522使用引脚说明

引脚名称功能
3.3V电源正
RST复位引脚,高电平有效
GND地,电源负
IRQ中断引脚,悬空不使用
MISOSPI协议数据线
MOSISPI协议数据线
SCKSPI时钟线
SDASPI片选端口

接线说明

STM32F103RC522
3V33.3V
PB0RST
GNDGND
不接IRQ
PA6MISO
PA7MOSI
PA5SCK
PA4SDA

最后接好线烧录程序后,利用串口助手即可查看ic卡的uid,试了一下自己的校园卡也是可以刷出来的。主函数main.c

void IC_test ( void )
{char cStr [ 30 ];u8 ucArray_ID [ 4 ];        u8 ucStatusReturn;           static u8 ucLineCount = 0; while ( 1 ){ if ( ( ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ) ) != MI_OK )   {ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID );		}if ( ucStatusReturn == MI_OK  ){if ( PcdAnticoll ( ucArray_ID ) == MI_OK ) {sprintf ( cStr, "The Card ID is: %02X%02X%02X%02X", ucArray_ID [ 0 ], ucArray_ID [ 1 ], ucArray_ID [ 2 ], ucArray_ID [ 3 ] );printf ( "%s\r\n",cStr ); if ( ucLineCount == 0 )ucLineCount ++;if ( ucLineCount == 17 ) ucLineCount = 0;}	}	}
}

3.驱动函数rcc.c


/** 函数名:SPI_RC522_SendByte* 描述  :向RC522发送1 Byte 数据* 输入  :byte,要发送的数据* 返回  : RC522返回的数据* 调用  :内部调用*/
void SPI_RC522_SendByte ( u8 byte )
{u8 counter;for(counter=0;counter<8;counter++){     if ( byte & 0x80 )macRC522_MOSI_1 ();else macRC522_MOSI_0 ();//			Delay_us ( 3 );macRC522_DELAY();macRC522_SCK_0 ();//			Delay_us ( 1 );
//			Delay_us ( 3 );macRC522_DELAY();macRC522_SCK_1();//			Delay_us ( 3 );macRC522_DELAY();byte <<= 1; } }/** 函数名:SPI_RC522_ReadByte* 描述  :从RC522发送1 Byte 数据* 输入  :无* 返回  : RC522返回的数据* 调用  :内部调用*/
u8 SPI_RC522_ReadByte ( void )
{u8 counter;u8 SPI_Data;for(counter=0;counter<8;counter++){SPI_Data <<= 1;macRC522_SCK_0 ();//			Delay_us ( 3 );macRC522_DELAY();if ( macRC522_MISO_GET() == 1)SPI_Data |= 0x01;//			Delay_us ( 2 );
//			Delay_us ( 3 );macRC522_DELAY();macRC522_SCK_1 ();//			Delay_us ( 3 );macRC522_DELAY();}return SPI_Data;}/** 函数名:ReadRawRC* 描述  :读RC522寄存器* 输入  :ucAddress,寄存器地址* 返回  : 寄存器的当前值* 调用  :内部调用*/
u8 ReadRawRC ( u8 ucAddress )
{u8 ucAddr, ucReturn;ucAddr = ( ( ucAddress << 1 ) & 0x7E ) | 0x80;macRC522_CS_Enable();SPI_RC522_SendByte ( ucAddr );ucReturn = SPI_RC522_ReadByte ();macRC522_CS_Disable();return ucReturn;}/** 函数名:WriteRawRC* 描述  :写RC522寄存器* 输入  :ucAddress,寄存器地址*         ucValue,写入寄存器的值* 返回  : 无* 调用  :内部调用*/
void WriteRawRC ( u8 ucAddress, u8 ucValue )
{  u8 ucAddr;ucAddr = ( ucAddress << 1 ) & 0x7E;macRC522_CS_Enable();SPI_RC522_SendByte ( ucAddr );SPI_RC522_SendByte ( ucValue );macRC522_CS_Disable();	}/** 函数名:SetBitMask* 描述  :对RC522寄存器置位* 输入  :ucReg,寄存器地址*         ucMask,置位值* 返回  : 无* 调用  :内部调用*/
void SetBitMask ( u8 ucReg, u8 ucMask )  
{u8 ucTemp;ucTemp = ReadRawRC ( ucReg );WriteRawRC ( ucReg, ucTemp | ucMask );         // set bit mask}/** 函数名:ClearBitMask* 描述  :对RC522寄存器清位* 输入  :ucReg,寄存器地址*         ucMask,清位值* 返回  : 无* 调用  :内部调用*/
void ClearBitMask ( u8 ucReg, u8 ucMask )  
{u8 ucTemp;ucTemp = ReadRawRC ( ucReg );WriteRawRC ( ucReg, ucTemp & ( ~ ucMask) );  // clear bit mask}/** 函数名:PcdAntennaOn* 描述  :开启天线 * 输入  :无* 返回  : 无* 调用  :内部调用*/
void PcdAntennaOn ( void )
{u8 uc;uc = ReadRawRC ( TxControlReg );if ( ! ( uc & 0x03 ) )SetBitMask(TxControlReg, 0x03);}/** 函数名:PcdAntennaOff* 描述  :开启天线 * 输入  :无* 返回  : 无* 调用  :内部调用*/
void PcdAntennaOff ( void )
{ClearBitMask ( TxControlReg, 0x03 );}/** 函数名:PcdRese* 描述  :复位RC522 * 输入  :无* 返回  : 无* 调用  :外部调用*/
void PcdReset ( void )
{macRC522_Reset_Disable();Delay_us ( 1 );macRC522_Reset_Enable();Delay_us ( 1 );macRC522_Reset_Disable();Delay_us ( 1 );WriteRawRC ( CommandReg, 0x0f );while ( ReadRawRC ( CommandReg ) & 0x10 );Delay_us ( 1 );WriteRawRC ( ModeReg, 0x3D );            //定义发送和接收常用模式 和Mifare卡通讯,CRC初始值0x6363WriteRawRC ( TReloadRegL, 30 );          //16位定时器低位    WriteRawRC ( TReloadRegH, 0 );			     //16位定时器高位WriteRawRC ( TModeReg, 0x8D );				   //定义内部定时器的设置WriteRawRC ( TPrescalerReg, 0x3E );			 //设置定时器分频系数WriteRawRC ( TxAutoReg, 0x40 );				   //调制发送信号为100%ASK	}/** 函数名:M500PcdConfigISOType* 描述  :设置RC522的工作方式* 输入  :ucType,工作方式* 返回  : 无* 调用  :外部调用*/
void M500PcdConfigISOType ( u8 ucType )
{if ( ucType == 'A')                     //ISO14443_A{ClearBitMask ( Status2Reg, 0x08 );WriteRawRC ( ModeReg, 0x3D );//3FWriteRawRC ( RxSelReg, 0x86 );//84WriteRawRC( RFCfgReg, 0x7F );   //4FWriteRawRC( TReloadRegL, 30 );//tmoLength);// TReloadVal = 'h6a =tmoLength(dec) WriteRawRC ( TReloadRegH, 0 );WriteRawRC ( TModeReg, 0x8D );WriteRawRC ( TPrescalerReg, 0x3E );Delay_us ( 2 );PcdAntennaOn ();//开天线}}/** 函数名:PcdComMF522* 描述  :通过RC522和ISO14443卡通讯* 输入  :ucCommand,RC522命令字*         pInData,通过RC522发送到卡片的数据*         ucInLenByte,发送数据的字节长度*         pOutData,接收到的卡片返回数据*         pOutLenBit,返回数据的位长度* 返回  : 状态值*         = MI_OK,成功* 调用  :内部调用*/
char PcdComMF522 ( u8 ucCommand, u8 * pInData, u8 ucInLenByte, u8 * pOutData, u32 * pOutLenBit )		
{char cStatus = MI_ERR;u8 ucIrqEn   = 0x00;u8 ucWaitFor = 0x00;u8 ucLastBits;u8 ucN;u32 ul;switch ( ucCommand ){case PCD_AUTHENT:		//Mifare认证ucIrqEn   = 0x12;		//允许错误中断请求ErrIEn  允许空闲中断IdleIEnucWaitFor = 0x10;		//认证寻卡等待时候 查询空闲中断标志位break;case PCD_TRANSCEIVE:		//接收发送 发送接收ucIrqEn   = 0x77;		//允许TxIEn RxIEn IdleIEn LoAlertIEn ErrIEn TimerIEnucWaitFor = 0x30;		//寻卡等待时候 查询接收中断标志位与 空闲中断标志位break;default:break;}WriteRawRC ( ComIEnReg, ucIrqEn | 0x80 );		//IRqInv置位管脚IRQ与Status1Reg的IRq位的值相反 ClearBitMask ( ComIrqReg, 0x80 );			//Set1该位清零时,CommIRqReg的屏蔽位清零WriteRawRC ( CommandReg, PCD_IDLE );		//写空闲命令SetBitMask ( FIFOLevelReg, 0x80 );			//置位FlushBuffer清除内部FIFO的读和写指针以及ErrReg的BufferOvfl标志位被清除for ( ul = 0; ul < ucInLenByte; ul ++ )WriteRawRC ( FIFODataReg, pInData [ ul ] );    		//写数据进FIFOdataWriteRawRC ( CommandReg, ucCommand );					//写命令if ( ucCommand == PCD_TRANSCEIVE )SetBitMask(BitFramingReg,0x80);  				//StartSend置位启动数据发送 该位与收发命令使用时才有效ul = 1000;//根据时钟频率调整,操作M1卡最大等待时间25msdo 														//认证 与寻卡等待时间	{ucN = ReadRawRC ( ComIrqReg );							//查询事件中断ul --;} while ( ( ul != 0 ) && ( ! ( ucN & 0x01 ) ) && ( ! ( ucN & ucWaitFor ) ) );		//退出条件i=0,定时器中断,与写空闲命令ClearBitMask ( BitFramingReg, 0x80 );					//清理允许StartSend位if ( ul != 0 ){if ( ! ( ReadRawRC ( ErrorReg ) & 0x1B ) )			//读错误标志寄存器BufferOfI CollErr ParityErr ProtocolErr{cStatus = MI_OK;if ( ucN & ucIrqEn & 0x01 )					//是否发生定时器中断cStatus = MI_NOTAGERR;   if ( ucCommand == PCD_TRANSCEIVE ){ucN = ReadRawRC ( FIFOLevelReg );			//读FIFO中保存的字节数ucLastBits = ReadRawRC ( ControlReg ) & 0x07;	//最后接收到得字节的有效位数if ( ucLastBits )* pOutLenBit = ( ucN - 1 ) * 8 + ucLastBits;   	//N个字节数减去1(最后一个字节)+最后一位的位数 读取到的数据总位数else* pOutLenBit = ucN * 8;   					//最后接收到的字节整个字节有效if ( ucN == 0 )		ucN = 1;    if ( ucN > MAXRLEN )ucN = MAXRLEN;   for ( ul = 0; ul < ucN; ul ++ )pOutData [ ul ] = ReadRawRC ( FIFODataReg );   }}elsecStatus = MI_ERR;   }SetBitMask ( ControlReg, 0x80 );           // stop timer nowWriteRawRC ( CommandReg, PCD_IDLE ); return cStatus;}/** 函数名:PcdRequest* 描述  :寻卡* 输入  :ucReq_code,寻卡方式*                     = 0x52,寻感应区内所有符合14443A标准的卡*                     = 0x26,寻未进入休眠状态的卡*         pTagType,卡片类型代码*                   = 0x4400,Mifare_UltraLight*                   = 0x0400,Mifare_One(S50)*                   = 0x0200,Mifare_One(S70)*                   = 0x0800,Mifare_Pro(X))*                   = 0x4403,Mifare_DESFire* 返回  : 状态值*         = MI_OK,成功* 调用  :外部调用*/
char PcdRequest ( u8 ucReq_code, u8 * pTagType )
{char cStatus;  u8 ucComMF522Buf [ MAXRLEN ]; u32 ulLen;ClearBitMask ( Status2Reg, 0x08 );	//清理指示MIFARECyptol单元接通以及所有卡的数据通信被加密的情况WriteRawRC ( BitFramingReg, 0x07 );	//	发送的最后一个字节的 七位SetBitMask ( TxControlReg, 0x03 );	//TX1,TX2管脚的输出信号传递经发送调制的13.56的能量载波信号ucComMF522Buf [ 0 ] = ucReq_code;		//存入 卡片命令字cStatus = PcdComMF522 ( PCD_TRANSCEIVE,	ucComMF522Buf, 1, ucComMF522Buf, & ulLen );	//寻卡  if ( ( cStatus == MI_OK ) && ( ulLen == 0x10 ) )	//寻卡成功返回卡类型 {    * pTagType = ucComMF522Buf [ 0 ];* ( pTagType + 1 ) = ucComMF522Buf [ 1 ];}elsecStatus = MI_ERR;return cStatus;}/** 函数名:PcdAnticoll* 描述  :防冲撞* 输入  :pSnr,卡片序列号,4字节* 返回  : 状态值*         = MI_OK,成功* 调用  :外部调用*/
char PcdAnticoll ( u8 * pSnr )
{char cStatus;u8 uc, ucSnr_check = 0;u8 ucComMF522Buf [ MAXRLEN ]; u32 ulLen;ClearBitMask ( Status2Reg, 0x08 );		//清MFCryptol On位 只有成功执行MFAuthent命令后,该位才能置位WriteRawRC ( BitFramingReg, 0x00);		//清理寄存器 停止收发ClearBitMask ( CollReg, 0x80 );			//清ValuesAfterColl所有接收的位在冲突后被清除ucComMF522Buf [ 0 ] = 0x93;	//卡片防冲突命令ucComMF522Buf [ 1 ] = 0x20;cStatus = PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 2, ucComMF522Buf, & ulLen);//与卡片通信if ( cStatus == MI_OK)		//通信成功{for ( uc = 0; uc < 4; uc ++ ){* ( pSnr + uc )  = ucComMF522Buf [ uc ];			//读出UIDucSnr_check ^= ucComMF522Buf [ uc ];}if ( ucSnr_check != ucComMF522Buf [ uc ] )cStatus = MI_ERR;    }SetBitMask ( CollReg, 0x80 );return cStatus;}/** 函数名:CalulateCRC* 描述  :用RC522计算CRC16* 输入  :pIndata,计算CRC16的数组*         ucLen,计算CRC16的数组字节长度*         pOutData,存放计算结果存放的首地址* 返回  : 无* 调用  :内部调用*/
void CalulateCRC ( u8 * pIndata, u8 ucLen, u8 * pOutData )
{u8 uc, ucN;ClearBitMask(DivIrqReg,0x04);WriteRawRC(CommandReg,PCD_IDLE);SetBitMask(FIFOLevelReg,0x80);for ( uc = 0; uc < ucLen; uc ++)WriteRawRC ( FIFODataReg, * ( pIndata + uc ) );   WriteRawRC ( CommandReg, PCD_CALCCRC );uc = 0xFF;do {ucN = ReadRawRC ( DivIrqReg );uc --;} while ( ( uc != 0 ) && ! ( ucN & 0x04 ) );pOutData [ 0 ] = ReadRawRC ( CRCResultRegL );pOutData [ 1 ] = ReadRawRC ( CRCResultRegM );}/** 函数名:PcdSelect* 描述  :选定卡片* 输入  :pSnr,卡片序列号,4字节* 返回  : 状态值*         = MI_OK,成功* 调用  :外部调用*/
char PcdSelect ( u8 * pSnr )
{char ucN;u8 uc;u8 ucComMF522Buf [ MAXRLEN ]; u32  ulLen;ucComMF522Buf [ 0 ] = PICC_ANTICOLL1;ucComMF522Buf [ 1 ] = 0x70;ucComMF522Buf [ 6 ] = 0;for ( uc = 0; uc < 4; uc ++ ){ucComMF522Buf [ uc + 2 ] = * ( pSnr + uc );ucComMF522Buf [ 6 ] ^= * ( pSnr + uc );}CalulateCRC ( ucComMF522Buf, 7, & ucComMF522Buf [ 7 ] );ClearBitMask ( Status2Reg, 0x08 );ucN = PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 9, ucComMF522Buf, & ulLen );if ( ( ucN == MI_OK ) && ( ulLen == 0x18 ) )ucN = MI_OK;  elseucN = MI_ERR;    return ucN;}/** 函数名:PcdAuthState* 描述  :验证卡片密码* 输入  :ucAuth_mode,密码验证模式*                     = 0x60,验证A密钥*                     = 0x61,验证B密钥*         u8 ucAddr,块地址*         pKey,密码*         pSnr,卡片序列号,4字节* 返回  : 状态值*         = MI_OK,成功* 调用  :外部调用*/
char PcdAuthState ( u8 ucAuth_mode, u8 ucAddr, u8 * pKey, u8 * pSnr )
{char cStatus;u8 uc, ucComMF522Buf [ MAXRLEN ];u32 ulLen;ucComMF522Buf [ 0 ] = ucAuth_mode;ucComMF522Buf [ 1 ] = ucAddr;for ( uc = 0; uc < 6; uc ++ )ucComMF522Buf [ uc + 2 ] = * ( pKey + uc );   for ( uc = 0; uc < 6; uc ++ )ucComMF522Buf [ uc + 8 ] = * ( pSnr + uc );   cStatus = PcdComMF522 ( PCD_AUTHENT, ucComMF522Buf, 12, ucComMF522Buf, & ulLen );if ( ( cStatus != MI_OK ) || ( ! ( ReadRawRC ( Status2Reg ) & 0x08 ) ) )cStatus = MI_ERR;   return cStatus;}/** 函数名:PcdWrite* 描述  :写数据到M1卡一块* 输入  :u8 ucAddr,块地址*         pData,写入的数据,16字节* 返回  : 状态值*         = MI_OK,成功* 调用  :外部调用*/
char PcdWrite ( u8 ucAddr, u8 * pData )
{char cStatus;u8 uc, ucComMF522Buf [ MAXRLEN ];u32 ulLen;ucComMF522Buf [ 0 ] = PICC_WRITE;ucComMF522Buf [ 1 ] = ucAddr;CalulateCRC ( ucComMF522Buf, 2, & ucComMF522Buf [ 2 ] );cStatus = PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, & ulLen );if ( ( cStatus != MI_OK ) || ( ulLen != 4 ) || ( ( ucComMF522Buf [ 0 ] & 0x0F ) != 0x0A ) )cStatus = MI_ERR;   if ( cStatus == MI_OK ){//memcpy(ucComMF522Buf, pData, 16);for ( uc = 0; uc < 16; uc ++ )ucComMF522Buf [ uc ] = * ( pData + uc );  CalulateCRC ( ucComMF522Buf, 16, & ucComMF522Buf [ 16 ] );cStatus = PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 18, ucComMF522Buf, & ulLen );if ( ( cStatus != MI_OK ) || ( ulLen != 4 ) || ( ( ucComMF522Buf [ 0 ] & 0x0F ) != 0x0A ) )cStatus = MI_ERR;   } return cStatus;}/** 函数名:PcdRead* 描述  :读取M1卡一块数据* 输入  :u8 ucAddr,块地址*         pData,读出的数据,16字节* 返回  : 状态值*         = MI_OK,成功* 调用  :外部调用*/
char PcdRead ( u8 ucAddr, u8 * pData )
{char cStatus;u8 uc, ucComMF522Buf [ MAXRLEN ]; u32 ulLen;ucComMF522Buf [ 0 ] = PICC_READ;ucComMF522Buf [ 1 ] = ucAddr;CalulateCRC ( ucComMF522Buf, 2, & ucComMF522Buf [ 2 ] );cStatus = PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, & ulLen );if ( ( cStatus == MI_OK ) && ( ulLen == 0x90 ) ){for ( uc = 0; uc < 16; uc ++ )* ( pData + uc ) = ucComMF522Buf [ uc ];   }elsecStatus = MI_ERR;   return cStatus;}/** 函数名:PcdHalt* 描述  :命令卡片进入休眠状态* 输入  :无* 返回  : 状态值*         = MI_OK,成功* 调用  :外部调用*/
char PcdHalt( void )
{u8 ucComMF522Buf [ MAXRLEN ]; u32  ulLen;ucComMF522Buf [ 0 ] = PICC_HALT;ucComMF522Buf [ 1 ] = 0;CalulateCRC ( ucComMF522Buf, 2, & ucComMF522Buf [ 2 ] );PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, & ulLen );return MI_OK;}void IC_CMT ( u8 * UID, u8 * KEY, u8 RW, u8 * Dat )
{u8 ucArray_ID [ 4 ] = { 0 };//先后存放IC卡的类型和UID(IC卡序列号)PcdRequest ( 0x52, ucArray_ID );//寻卡PcdAnticoll ( ucArray_ID );//防冲撞PcdSelect ( UID );//选定卡PcdAuthState ( 0x60, 0x10, KEY, UID );//校验if ( RW )//读写选择,1是读,0是写PcdRead ( 0x10, Dat );else PcdWrite ( 0x10, Dat );PcdHalt ();}

rcc.h文件

#ifndef __RC52_H
#define __RC52_H
#include "sys.h"
#include "stm32f10x.h"/*********************************** RC522 引脚定义 *********************************************/
#define               macRC522_GPIO_CS_CLK_FUN                  RCC_APB2PeriphClockCmd
#define               macRC522_GPIO_CS_CLK                      RCC_APB2Periph_GPIOA
#define               macRC522_GPIO_CS_PORT    	                GPIOA			   
#define               macRC522_GPIO_CS_PIN		                  GPIO_Pin_4
#define               macRC522_GPIO_CS_Mode		                  GPIO_Mode_Out_PP#define               macRC522_GPIO_SCK_CLK_FUN                 RCC_APB2PeriphClockCmd
#define               macRC522_GPIO_SCK_CLK                     RCC_APB2Periph_GPIOA
#define               macRC522_GPIO_SCK_PORT    	              GPIOA			   
#define               macRC522_GPIO_SCK_PIN		                  GPIO_Pin_5
#define               macRC522_GPIO_SCK_Mode		                GPIO_Mode_Out_PP#define               macRC522_GPIO_MOSI_CLK_FUN                RCC_APB2PeriphClockCmd
#define               macRC522_GPIO_MOSI_CLK                    RCC_APB2Periph_GPIOA
#define               macRC522_GPIO_MOSI_PORT    	              GPIOA			   
#define               macRC522_GPIO_MOSI_PIN		                GPIO_Pin_7
#define               macRC522_GPIO_MOSI_Mode		                GPIO_Mode_Out_PP#define               macRC522_GPIO_MISO_CLK_FUN                RCC_APB2PeriphClockCmd
#define               macRC522_GPIO_MISO_CLK                    RCC_APB2Periph_GPIOA
#define               macRC522_GPIO_MISO_PORT    	              GPIOA			   
#define               macRC522_GPIO_MISO_PIN		                GPIO_Pin_6
#define               macRC522_GPIO_MISO_Mode		                GPIO_Mode_IN_FLOATING#define               macRC522_GPIO_RST_CLK_FUN                 RCC_APB2PeriphClockCmd
#define               macRC522_GPIO_RST_CLK                     RCC_APB2Periph_GPIOB
#define               macRC522_GPIO_RST_PORT    	              GPIOB		   
#define               macRC522_GPIO_RST_PIN		                  GPIO_Pin_0
#define               macRC522_GPIO_RST_Mode		                GPIO_Mode_Out_PP/
//MF522命令字
/
#define PCD_IDLE              0x00               //取消当前命令
#define PCD_AUTHENT           0x0E               //验证密钥
#define PCD_RECEIVE           0x08               //接收数据
#define PCD_TRANSMIT          0x04               //发送数据
#define PCD_TRANSCEIVE        0x0C               //发送并接收数据
#define PCD_RESETPHASE        0x0F               //复位
#define PCD_CALCCRC           0x03               //CRC计算/
//Mifare_One卡片命令字
/
#define PICC_REQIDL           0x26               //寻天线区内未进入休眠状态
#define PICC_REQALL           0x52               //寻天线区内全部卡
#define PICC_ANTICOLL1        0x93               //防冲撞
#define PICC_ANTICOLL2        0x95               //防冲撞
#define PICC_AUTHENT1A        0x60               //验证A密钥
#define PICC_AUTHENT1B        0x61               //验证B密钥
#define PICC_READ             0x30               //读块
#define PICC_WRITE            0xA0               //写块
#define PICC_DECREMENT        0xC0               //扣款
#define PICC_INCREMENT        0xC1               //充值
#define PICC_RESTORE          0xC2               //调块数据到缓冲区
#define PICC_TRANSFER         0xB0               //保存缓冲区中数据
#define PICC_HALT             0x50               //休眠/
//MF522 FIFO长度定义
/
#define DEF_FIFO_LENGTH       64                 //FIFO size=64byte
#define MAXRLEN  18/
//MF522寄存器定义
/
// PAGE 0
#define     RFU00                 0x00
#define     CommandReg            0x01
#define     ComIEnReg             0x02
#define     DivlEnReg             0x03
#define     ComIrqReg             0x04
#define     DivIrqReg             0x05
#define     ErrorReg              0x06
#define     Status1Reg            0x07
#define     Status2Reg            0x08
#define     FIFODataReg           0x09
#define     FIFOLevelReg          0x0A
#define     WaterLevelReg         0x0B
#define     ControlReg            0x0C
#define     BitFramingReg         0x0D
#define     CollReg               0x0E
#define     RFU0F                 0x0F
// PAGE 1
#define     RFU10                 0x10
#define     ModeReg               0x11
#define     TxModeReg             0x12
#define     RxModeReg             0x13
#define     TxControlReg          0x14
#define     TxAutoReg             0x15
#define     TxSelReg              0x16
#define     RxSelReg              0x17
#define     RxThresholdReg        0x18
#define     DemodReg              0x19
#define     RFU1A                 0x1A
#define     RFU1B                 0x1B
#define     MifareReg             0x1C
#define     RFU1D                 0x1D
#define     RFU1E                 0x1E
#define     SerialSpeedReg        0x1F
// PAGE 2
#define     RFU20                 0x20
#define     CRCResultRegM         0x21
#define     CRCResultRegL         0x22
#define     RFU23                 0x23
#define     ModWidthReg           0x24
#define     RFU25                 0x25
#define     RFCfgReg              0x26
#define     GsNReg                0x27
#define     CWGsCfgReg            0x28
#define     ModGsCfgReg           0x29
#define     TModeReg              0x2A
#define     TPrescalerReg         0x2B
#define     TReloadRegH           0x2C
#define     TReloadRegL           0x2D
#define     TCounterValueRegH     0x2E
#define     TCounterValueRegL     0x2F
// PAGE 3
#define     RFU30                 0x30
#define     TestSel1Reg           0x31
#define     TestSel2Reg           0x32
#define     TestPinEnReg          0x33
#define     TestPinValueReg       0x34
#define     TestBusReg            0x35
#define     AutoTestReg           0x36
#define     VersionReg            0x37
#define     AnalogTestReg         0x38
#define     TestDAC1Reg           0x39
#define     TestDAC2Reg           0x3A
#define     TestADCReg            0x3B
#define     RFU3C                 0x3C
#define     RFU3D                 0x3D
#define     RFU3E                 0x3E
#define     RFU3F		  		        0x3F/
//和MF522通讯时返回的错误代码
/
#define 	MI_OK                 0
#define 	MI_NOTAGERR           (1)
#define 	MI_ERR                (2)#define	SHAQU1	0X01
#define	KUAI4	0X04
#define	KUAI7	0X07
#define	REGCARD	0xa1
#define	CONSUME	0xa2
#define READCARD	0xa3
#define ADDMONEY	0xa4//
//#define  spi_cs 1;
//sbit  spi_ck=P0^6;
//sbit  spi_mosi=P0^7;
//sbit  spi_miso=P4^1;
//sbit  spi_rst=P2^7;
#define SPIReadByte()	SPIWriteByte(0)
u8 SPIWriteByte(u8 byte);
void SPI1_Init(void);
//void SPI2_Init(void);#define SET_SPI_CS  (GPIOA->BSRR=0X01)
#define CLR_SPI_CS  (GPIOA->BRR=0X01)#define SET_RC522RST  GPIOA->BSRR=0X02
#define CLR_RC522RST  GPIOA->BRR=0X02/***********************RC522 函数宏定义**********************/
#define          RC522_CS_Enable()         GPIO_ResetBits ( GPIOA, GPIO_Pin_4 )
#define          RC522_CS_Disable()        GPIO_SetBits ( GPIOA, GPIO_Pin_4 )#define          RC522_Reset_Enable()      GPIO_ResetBits( GPIOB, GPIO_Pin_0 )
#define          RC522_Reset_Disable()     GPIO_SetBits ( GPIOB, GPIO_Pin_0)#define          RC522_SCK_0()             GPIO_ResetBits( GPIOA, GPIO_Pin_5 )
#define          RC522_SCK_1()             GPIO_SetBits ( GPIOA, GPIO_Pin_5)#define          RC522_MOSI_0()            GPIO_ResetBits( GPIOA, GPIO_Pin_7 )
#define          RC522_MOSI_1()            GPIO_SetBits ( GPIOA, GPIO_Pin_7 )#define          RC522_MISO_GET()          GPIO_ReadInputDataBit ( GPIOA, GPIO_Pin_6 )void             RC522_Handel               (void);
void             RC522_Init                 ( void );                       //初始化
void             PcdReset                   ( void );                       //复位
void             M500PcdConfigISOType       ( u8 type );                    //工作方式
char             PcdRequest                 ( u8 req_code, u8 * pTagType ); //寻卡
char             PcdAnticoll                ( u8 * pSnr);                   //读卡号char             PcdSelect                  ( u8 * pSnr );
char             PcdAuthState               ( u8 ucAuth_mode, u8 ucAddr, u8 * pKey, u8 * pSnr );
char             PcdWrite                   ( u8 ucAddr, u8 * pData );
char             PcdRead                    ( u8 ucAddr, u8 * pData );
void ShowID(u8 *p);	 //显示卡的卡号,以十六进制显示extern char* POINT_LNG;
extern char* POINT_LAT;
extern char* POINT_LNG_ON;
extern char* POINT_LAT_ON;
extern char* POINT_LNG_OFF;
extern char* POINT_LAT_OFF;u8 shibieka(void);#endif


http://chatgpt.dhexx.cn/article/Syx7PQNj.shtml

相关文章

Jmeter下载安装配置---测试小白

一&#xff0c;进入官网&#xff1a;http://jmeter.apache.org/ 1.第一步进入官网如下图 2.选择进行下载&#xff0c;下载下来为一个压缩包&#xff0c;解压即可。 3.我下载的是jmeter4.0版本&#xff0c;对应jdk1.8。然后就进行解压。个人认为要注意3点&#xff1a;1.解压之后…

Windows版JMeter下载安装

进入apache官网https://www.apache.org/dist/jmeter/binaries下载Windows版本JMeter&#xff1b;配置环境变量&#xff08;JMETER_HOMED:\JMeter\apache-jmeter-5.1.1&#xff09;配置环境变量&#xff08;classpath%JMETER_HOME%\lib\ext\ApacheJMeter_core.jar;%JMETER_HOME%…

JMeter下载安装

一、环境准备 1.Jmeter是纯Java开发的&#xff0c; 能够运行Java程序的系统一般都可以运行Jmeter&#xff0c; 如&#xff1a;Windows、 Linux、 mac等。由于是由Java开发&#xff0c;所以自然需要jdk环境。 2.去官方下载JMeter安装包&#xff1a;Apache JMeter - Download Apa…

Mac版本Jmeter下载安装教程

Mac版本Jmeter下载安装教程 1. 下载&安装&启动Jmeter1.1 下载安装包&#xff1a;1.2 解压安装包1.3 启动Jmeter1.4 Jmeter页面 2. Jmeter进一步优化配置2.1 打开&编辑&保存配置文件~/.bash_profile步骤一&#xff1a;打开配置文件~/.bash_profile步骤二&#x…

JMeter-文件下载教程

一、单个下载配置方法 1、先添加线程组 选中测试计划右键添加线程组&#xff1a;测试计划->添加->线程(用户)->线程组 2、添加HTTP请求 ①. 选中线程组右键添加HTTP请求&#xff1a;线程组->添加->取样器->HTTP请求 ②.配置HPPT请求 3、添加BeanShell 取…

jmeter下载与安装教程

jmeter下载与安装教程 下载步骤&#xff1a; 自行百度jmeter下载&#xff0c;找到apache官网&#xff1b;进入网站后&#xff0c;选择左侧Download下的Download Releases&#xff1b;如图所示 2.页面进入新的页面后&#xff0c;点击此页面Binaries标签下的“apache-jmeter-5…

Jmeter下载及安装教程

下载及环境配置 下载 前置条件&#xff0c;电脑得配置Java环境&#xff0c;也就是安装jdk&#xff0c;可百度jdk安装教程。 1、下载地址&#xff1a;Apache JMeter - Download Apache JMeter&#xff0c;&#xff08;Windows版本下载.zip&#xff0c;Linux版本下载.tgz&…

Jmeter下载安装详细步骤(2021)

Jmeter下载安装详细步骤&#xff08;2021&#xff09; 由于项目方有压测需求&#xff0c;因此需要学习Jmeter压测工具的使用&#xff0c;避免遗忘&#xff0c;记录一下Jmeter下载安装的步骤 这里面有个坑就是Jmeter需要依赖JAVA环境&#xff0c;在安装Jmeter之前需要配置好JA…

测试工具:jmeter的下载以及使用

测试不仅要了解项目整体流程&#xff0c;还需要会使用各种测试工具&#xff0c;比如&#xff1a;jmeter压力测试工具。 1.下载地址 https://jmeter.apache.org/download_jmeter.cgi2.下载完直接解压&#xff0c;配置环境 &#xff08;1&#xff09;此电脑-右键属性-高级系统设…

Jmeter安装配置详细教程

目录 1、Jmeter下载1.1、下载地址1.2、选择对应版本 2、JDK安装2.1、java环境检查2.2、JDK安装2.2.1、JDK下载2.2.2、JDK安装2.2.3、JDK环境变量配置2.2.4、验证java环境 3、Jmeter环境部署3.1、环境配置 4、验证jmeter5、修改语言5.1、临时性设置5.2、永久性生效 1、Jmeter下载…

Jmeter常用插件下载

一、jmeter Manager jmeter插件下载地址&#xff1a;https://jmeter-plugins.org/wiki/Start/ 二、PerfMon Metrics Collector&#xff1a;服务器性能监控数据采集器 在性能测试过程中&#xff0c;除了监控TPS和TRT&#xff0c;还需要监控服务器的资源使用情况&#xff0c;比…

【Jmeter】Win10 下载安装Jmeter 5.5

1、Jmeter下载 地址&#xff1a; https://jmeter.apache.org/前提&#xff1a;使用jmeter工具之前需要安装java.并配置好java的环境变量。 注意&#xff1a;jdk版本和jmeter版本匹配问题 2、JAVA8 下载 进入官网&#xff0c;https://www.oracle.com/&#xff0c;点击Resour…

jmeter常用插件下载及安装

jmeter常用插件 一、下载及安装 下载地址&#xff1a;https://jmeter-plugins.org/install/Install/ 下载后文件为一个jar包&#xff0c;将其放入jmeter安装目录下的lib/ext目录&#xff0c;然后重启jmeter&#xff0c;即可。 启动jemter&#xff0c;点击选项&#xff0c;最下面…

jmeter的配置与下载详细教程

目录 1、Jmeter下载 1.1、下载地址 1.2、选择对应版本 2、JDK安装 2.1、java环境检查 2.2、JDK安装 2.2.1、JDK下载 2.2.2、JDK安装 2.2.3、JDK环境变量配置 2.2.4、验证java环境 3、Jmeter环境部署 …

Jmeter的下载与安装

Jmeter的下载与安装 Jmeter工具可以用来做接口和性能测试&#xff0c;在使用之前让我们先来学习一下Jmeter是怎样下载和安装的吧&#xff01; 安装Jmter之前的准备工作&#xff1a; 1:下载jdk&#xff1a;https://www.oracle.com/technetwork/java/javase/downloads/index.h…

Jmeter下载安装及基本使用

本文将讲述Jmeter的下载安装&#xff0c;并以一个实例来讲解如何使用Jmeter。 一、Jmeter下载及安装部署 下载解压JMeter压缩包下载地址&#xff1a; http://jmeter.apache.org/download_jmeter.cgi JMeter解压之后&#xff0c;…\apache-jmeter-4.0\bin\jmeter.bat&#xff…

JMeter - 下载安装教程(Windows/macOS/Linux)

目录 1. JMeter介绍2. JMeter下载3. JMeter目录解析4. Windows和macOS下安装启动5. JMeter切换语言为中文6. Linux下安装启动 1. JMeter介绍 JMeter是目前行业内用的比较多的一个开源性能测试工具&#xff0c;由Java语言编写&#xff0c;要依赖Java环境来运行&#xff08;需要…

【jmeter安装】jmeter下载安装超详细简单步骤

本文介绍jmeter下载安装的详细步骤 1.下载jmeter安装包&#xff0c;我下的就是最新的版本&#xff08;在此之前需要安装Java环境jdk&#xff0c;已有环境可忽略&#xff09; 2.下载后解压 3.右键单击桌面的“此电脑”图标&#xff0c;再单击弹框中的“属性”按钮 4.在页面左侧…

【Jmeter】win 10 / win 11:Jmeter 下载、安装、汉化、新机迁移、版本更新(Jmeter 4 以上版本均适用)

目录 一、安装 JDK 二、下载 Jmeter &#xff08;1&#xff09;Jmeter 应用程序下载&#xff08;最新版本&#xff09; &#xff08;2&#xff09;Jmeter 源代码包下载&#xff08;最新版本&#xff09; &#xff08;3&#xff09;Jmeter 应用程序下载&#xff08;历史版本…

JMeter 下载安装教程

JMeter 下载安装教程 安装 Java下载 JMeter关闭 SSLJMeter 汉化设置 JMeter 主题设置 Cookie运行 JMeter 笔者的环境&#xff1a; JMeter 5.4.3 Java 17.0.1 Windows 10 教育版 64位 安装 Java 在继续阅读本教程之前&#xff0c;需要先完成 JDK 的安装。关于 JDK 的安装&…