首页 > 编程语言 >RC522刷卡电路设计及程序

RC522刷卡电路设计及程序

时间:2024-03-15 17:29:05浏览次数:25  
标签:刷卡 MI unsigned cStatus ucComMF522Buf char RC522 电路设计 uc

一、RC522刷卡电路组成

RC522 刷卡电路
基于RC522的刷卡电路如上图所示。该电路组成主要分为三部分:
Receiving Circuit:接收电路,接收卡发送的数据。
Filtering Impedence-Transtorm circuit:滤波和阻抗变换电路,抑制高次谐波并优化到读卡器天线的功率传输。
Matching Circuit:天线匹配电路。
在这里插入图片描述

二、RC522天线电路参数设计

1、天线电路参数

MF RC500 是一个单独的读卡器集成电路,它在没有外部放大器的情况下工作距离最大可达到 10cm,两侧最大5cm。为了得到最大的刷卡距离,需要合理设计天线电路和接收电路的元件参数。
在这里插入图片描述
如上图所示为MF RC522推荐的天线电路和接收电路的结构。
其中L0、C0组成了LC滤波电路,对应图一中的L1、L2、C5、C6;
Cs、Cp对应图一中的C8、C9、C11、C12;
R1、R2、C3、C4对应图一中的R3、R2、R7、R10;
滤波和接收电路的元件L0、C0、Cs、Cp、R1、R2、R3、R4的参数是固定的。在这里插入图片描述
Tx11和Tx12之间的整个天线线圈电感用Lant表示、天线所有电阻损耗可以用 Rant 来表示、天线的电容损耗可以用Cant来表示。建议用阻抗分析仪测量天线的等效电路,
在这里插入图片描述
如果没有阻抗分析仪 将计算的电感和电容值作为起始值。
天线线圈等效电阻的估算:RANT=5*RDC
式中,RDC为天线线圈的导线电阻,RANT为考虑集肤效应的天线线圈等效电阻。
天线线圈电感的估算:
在这里插入图片描述

2、天线品质因子计算

获取了天线电感 LANT 和电阻 RANT 的值之后,计算天线的品质因子。
在这里插入图片描述
在这里插入图片描述

2、天线外部电阻计算

由于元件的容差和对温度的依靠 我们建议 Q 因子的值取 35 要降低原始的 Q 因子 要求增加一个外部电阻 REXT 。图 3.10 显示了如何连接外部电阻 REXT。
在这里插入图片描述
REXT 的值用下面的公式算出:
在这里插入图片描述

3、天线匹配电路电容的计算

图 3.11 显示了推荐使用的将天线线圈匹配到 50Ω 的电路 匹配用一个串联和一个并联电容来实现输入电阻 Z 要等于 50Ω。
在这里插入图片描述
在这里插入图片描述
Cs 和 Cp 应当是 NP0 电介质的 SMD 类型 有很好的温度稳定性 我们建议将 Cp 分裂成一个固定的值和一个最大值是 10~20pF 的可变值 Cp’。
Cp 固定值对应图一中的C11、C12, Cp 可变值 Cp’对应图1中的C11 ~ C18。

4、环境对天线的影响

任何变化磁场都会在靠近读卡器天线的金属元件上感应出电压 这个感应电压会在金属平面上产生涡流,而涡流会导致天线去调并减弱磁场。结果是减少工作距离以及可能产生传输出错。
天线和大量金属元件的距离对于长距离 R/W 至少是 10cm 短距离 R/W 至少是 3cm 而且必须使
用密封的金属铁屏蔽。
5、电子屏蔽对天线的影响(天线PCB绘制)
电子屏蔽用于减少天线线圈本身产生的电场 要在 PCB 上获得屏蔽的天线 PCB 要有 4 层而且在顶
层和低层都有屏蔽环 shielding loop 这些环必须不能重合 闭合 它不仅提供电子屏蔽 还能改良EMC性能。
在这里插入图片描述

三、程序设计步骤

通讯协议代码
1、RC522初始化 :RST引脚拉低硬复位、SPI接口初始化、RC522寄存器配置和模式设置初始化
2、寻卡:发送寻卡命令给RC522模块、RC522模块开始搜索附件的卡片,并返回卡片信息。
3、防冲突:如果同时存在多张卡片,RC522模块执行防冲突算法,以保证选中的只是某一张卡
4、选择卡片:根据卡片的唯一序列号,选择要与之通信的特定卡片。
5、验证和通信:对选定的卡片进行身份验证,需要提供密钥和扇区号等参数,通信成功可对卡片进行读写操作。(只需要读唯一ID的话,不需要验证)
6、通信结束:将RC522置于空闲状体或关闭RC522模块。

/*
 * 函数名:SetBitMask
 * 描述  :对RC522寄存器置位
 * 输入  :ucReg,寄存器地址
 *         ucMask,置位值
 * 返回  : 无
 * 调用  :内部调用
 */
void SetBitMask ( unsigned char ucReg, unsigned char ucMask )  
{
    unsigned char ucTemp;
    ucTemp = ReadRawRC ( ucReg );
    WriteRawRC ( ucReg, ucTemp | ucMask );         // set bit mask
}
 
 
/*
 * 函数名:ClearBitMask
 * 描述  :对RC522寄存器清位
 * 输入  :ucReg,寄存器地址
 *         ucMask,清位值
 * 返回  : 无
 * 调用  :内部调用
 */
void ClearBitMask ( unsigned char ucReg, unsigned char ucMask )  
{
    unsigned char ucTemp;
    ucTemp = ReadRawRC ( ucReg );
    WriteRawRC ( ucReg, ucTemp & ( ~ ucMask) );  // clear bit mask
}
/*
 * 函数名:PcdAntennaOn
 * 描述  :开启天线 
 * 输入  :无
 * 返回  : 无
 * 调用  :内部调用
 */
void PcdAntennaOn ( void )
{
    unsigned char uc;
    uc = ReadRawRC ( TxControlReg );
    if ( ! ( uc & 0x03 ) )
			SetBitMask(TxControlReg, 0x03);
}
 
 
/*
 * 函数名:PcdAntennaOff
 * 描述  :开启天线 
 * 输入  :无
 * 返回  : 无
 * 调用  :内部调用
 */
void PcdAntennaOff ( void )
{
    ClearBitMask ( TxControlReg, 0x03 );
}
 
 
/*
 * 函数名:M500PcdConfigISOType
 * 描述  :设置RC522的工作方式
 * 输入  :ucType,工作方式
 * 返回  : 无
 * 调用  :外部调用
 */
void M500PcdConfigISOType ( unsigned char ucType )
{
	if ( ucType == 'A')                     //ISO14443_A
  {
		ClearBitMask ( Status2Reg, 0x08 );
        WriteRawRC ( ModeReg, 0x3d );//3F 3d
		WriteRawRC ( RxSelReg, 0x84 );//84 86
		WriteRawRC( RFCfgReg, 0x4F );   //4F
		WriteRawRC( TReloadRegL, 30 );//tmoLength);// TReloadVal = 'h6a =tmoLength(dec) 
		WriteRawRC ( TReloadRegH, 0 );
		WriteRawRC ( TModeReg, 0x8D );
		WriteRawRC ( TPrescalerReg, 0x3E );
		_delay_us ( 2 );
		PcdAntennaOn ();//开天线
   }
 
}
 
/*
 * 函数名:PcdRese
 * 描述  :复位RC522 
 * 输入  :无
 * 返回  : 无
 * 调用  :外部调用
 */
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 ( ReadRawRC ( CommandReg ) & 0x10 )
    {
		;
    }
    _delay_us ( 1 );
    WriteRawRC ( ModeReg, 0x3D );   //定义发送和接收常用模式 和Mifare卡通讯,CRC初始值0x6363
    WriteRawRC ( TReloadRegL, 30 );          //16位定时器低位    
    WriteRawRC ( TReloadRegH, 0 );			     //16位定时器高位
    WriteRawRC ( TModeReg, 0x8D );				   //定义内部定时器的设置
    WriteRawRC ( TPrescalerReg, 0x3E );			 //设置定时器分频系数
    WriteRawRC ( TxAutoReg, 0x40 );				   //调制发送信号为100%ASK	
}
 
/*
 * 函数名:PcdComMF522
 * 描述  :通过RC522和ISO14443卡通讯
 * 输入  :ucCommand,RC522命令字
 *         pInData,通过RC522发送到卡片的数据
 *         ucInLenByte,发送数据的字节长度
 *         pOutData,接收到的卡片返回数据
 *         pOutLenBit,返回数据的位长度
 * 返回  : 状态值
 *         = MI_OK,成功
 * 调用  :内部调用
 */
char PcdComMF522 ( unsigned char ucCommand, unsigned char * pInData, unsigned char ucInLenByte, unsigned char * pOutData, unsigned int * pOutLenBit )		
{
    char cStatus = MI_ERR;
    unsigned char ucIrqEn   = 0x00;
    unsigned char ucWaitFor = 0x00;
    unsigned char ucLastBits;
    unsigned char ucN;
    unsigned int ul;
 
    switch ( ucCommand )
    {
       case PCD_AUTHENT:		//Mifare认证
          ucIrqEn   = 0x12;		//允许错误中断请求ErrIEn  允许空闲中断IdleIEn
          ucWaitFor = 0x10;		//认证寻卡等待时候 查询空闲中断标志位
          break;
			 
       case PCD_TRANSCEIVE:		//接收发送 发送接收
          ucIrqEn   = 0x77;		//允许TxIEn RxIEn IdleIEn LoAlertIEn ErrIEn TimerIEn
          ucWaitFor = 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 ] );    		//写数据进FIFOdata	
    WriteRawRC ( CommandReg, ucCommand );					//写命令
    if ( ucCommand == PCD_TRANSCEIVE )
			SetBitMask(BitFramingReg,0x80); //StartSend置位启动数据发送 该位与收发命令使用时才有效
    ul = 1000;//根据时钟频率调整,操作M1卡最大等待时间25ms
    do 														//认证 与寻卡等待时间	
    {
         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 );   
			}		
        }
			else
				cStatus = MI_ERR;   
    }
   
   SetBitMask ( ControlReg, 0x80 );           // stop timer now
   WriteRawRC ( 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 ( unsigned char ucReq_code, unsigned char * pTagType )
{
    char cStatus;  
    unsigned char ucComMF522Buf [ MAXRLEN ]; 
    unsigned int 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 ];
    }
    else
     cStatus = MI_ERR;
 
    return cStatus;
 
}
 
 
/*
 * 函数名:PcdAnticoll
 * 描述  :防冲撞
 * 输入  :pSnr,卡片序列号,4字节
 * 返回  : 状态值
 *         = MI_OK,成功
 * 调用  :外部调用
 */
char PcdAnticoll ( unsigned char * pSnr )
{
    char cStatus;
    unsigned char uc, ucSnr_check = 0;
    unsigned char ucComMF522Buf [ MAXRLEN ]; 
	unsigned int 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 ];			//读出UID
            ucSnr_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 ( unsigned char * pIndata, unsigned char ucLen, unsigned char * pOutData )
{
    unsigned char 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 );
	
}
 
 
/*
 * 函数名:PcdWrite
 * 描述  :写数据到M1卡一块
 * 输入  :unsigned char ucAddr,块地址
 *         pData,写入的数据,16字节
 * 返回  : 状态值
 *         = MI_OK,成功
 * 调用  :外部调用
 */
char PcdWrite ( unsigned char ucAddr, unsigned char * pData )
{
    char cStatus;
	unsigned char uc, ucComMF522Buf [ MAXRLEN ];
    unsigned int 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;
}
 

/*
 * 函数名:PcdSelect
 * 描述  :选定卡片
 * 输入  :pSnr,卡片序列号,4字节
 * 返回  : 状态值
 *         = MI_OK,成功
 * 调用  :外部调用
 */
char PcdSelect ( unsigned char * pSnr )
{
    char ucN;
    unsigned char uc;
	unsigned char ucComMF522Buf [ MAXRLEN ]; 
    unsigned int  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;  
    else
      ucN = MI_ERR;    
 
    return ucN;
}
 
 
/*
 * 函数名:PcdAuthState
 * 描述  :验证卡片密码
 * 输入  :ucAuth_mode,密码验证模式
 *                     = 0x60,验证A密钥
 *                     = 0x61,验证B密钥
 *         unsigned char ucAddr,块地址
 *         pKey,密码
 *         pSnr,卡片序列号,4字节
 * 返回  : 状态值
 *         = MI_OK,成功
 * 调用  :外部调用
 */
char PcdAuthState ( unsigned char ucAuth_mode, unsigned char ucAddr, unsigned char * pKey, unsigned char * pSnr )
{
    char cStatus;
	  unsigned char uc, ucComMF522Buf [ MAXRLEN ];
    unsigned int 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;
		
}
 
/*
 * 函数名:PcdIncrement
 * 描述  :增加数据到M1卡一块
 * 输入  :unsigned char ucAddr,块地址
 *         pData,写入的数据,16字节
 * 返回  : 状态值
 *         = MI_OK,成功
 * 调用  :外部调用
 */
char PcdIncrement ( unsigned char ucAddr, unsigned char * pData )
{
    char cStatus;
    unsigned char uc, ucComMF522Buf [ MAXRLEN ];
    unsigned int ulLen;
 
    ucComMF522Buf [ 0 ] = PICC_INCREMENT;
    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 )
    {
      for ( uc = 0; uc < 4; uc ++ )
			  ucComMF522Buf [ uc ] = * ( pData + uc );  
      CalulateCRC ( ucComMF522Buf, 4, & ucComMF522Buf [ 4 ] );
      cStatus = PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 6, ucComMF522Buf, & ulLen );
    if( cStatus != MI_ERR )
    {
    	cStatus = MI_OK;
    }
    }
    if( cStatus == MI_OK )
    {
    ucComMF522Buf [ 0 ] = PICC_TRANSFER;
    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;   
    } 
    return cStatus;
	
}



/*
 * 函数名:PcdRead
 * 描述  :读取M1卡一块数据
 * 输入  :unsigned char ucAddr,块地址
 *         pData,读出的数据,16字节
 * 返回  : 状态值
 *         = MI_OK,成功
 * 调用  :外部调用
 */
char PcdRead ( unsigned char ucAddr, unsigned char * pData )
{
    char cStatus;
	  unsigned char uc, ucComMF522Buf [ MAXRLEN ]; 
    unsigned int 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 ];   
    }
    else
      cStatus = MI_ERR;   
    return cStatus;
 
}
 
 
/*
 * 函数名:PcdHalt
 * 描述  :命令卡片进入休眠状态
 * 输入  :无
 * 返回  : 状态值
 *         = MI_OK,成功
 * 调用  :外部调用
 */
char PcdHalt( void )
{
    unsigned char ucComMF522Buf [ MAXRLEN ]; 
    unsigned int  ulLen;
 
    ucComMF522Buf [ 0 ] = PICC_HALT;
    ucComMF522Buf [ 1 ] = 0;
    CalulateCRC ( ucComMF522Buf, 2, & ucComMF522Buf [ 2 ] );
    	PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, & ulLen );
    return MI_OK;
	
}
 
 
char IC_CMT ( unsigned char * UID, unsigned char * KEY, unsigned char RW, unsigned char addr, unsigned char * Dat )
{
    unsigned char ucArray_ID [ 4 ] = { 0 };//先后存放IC卡的类型和UID(IC卡序列号)
    unsigned char ICstate=MI_ERR;
 
    ICstate=PcdRequest ( 0x52, ucArray_ID );//寻卡
    if(ICstate==MI_OK)
    {
	    UID[1]=ucArray_ID[0];
	    UID[2]=ucArray_ID[1];
	    UID[3]=ucArray_ID[2];
	    UID[4]=ucArray_ID[3];
    }
    if(ICstate==MI_OK)
    {
      ICstate=MI_ERR;
      ICstate=PcdAnticoll ( UID+1 );//防冲撞
    }
    if(ICstate==MI_OK)
    {
      ICstate=MI_ERR;
      ICstate=PcdSelect ( UID+1 );//选定卡
    }
	/*
    if(ICstate==MI_OK)
    {
      ICstate=MI_ERR;
      ICstate=PcdAuthState ( 0x60, addr, KEY, UID );//校验
    }
    if(ICstate==MI_OK)
    {
        ICstate=MI_ERR;
        if ( RW==1 )//读写选择,1是读,0是写,2是增,3是减
            ICstate=PcdRead( addr, Dat );
        else if(RW==2)
            ICstate=PcdIncrement( addr, Dat );
        else 
            ICstate=PcdWrite( addr, Dat );
    }*/
    if(ICstate==MI_OK)
    {
      ICstate=MI_ERR;
      ICstate=PcdHalt ();
    }
    return ICstate;
	 
}
 
/*
 * 函数名:RC522_Init
 * 描述  :初始化RC522 
 * 输入  :无
 * 返回  : 无
 * 调用  :外部调用
 */
void RC522_Init ( void )
{
	RC522_Reset_Disable();
	RC522_CS_Disable();
	PcdReset ();
	M500PcdConfigISOType ( 'A' );//设置工作方式
	
}
 

标签:刷卡,MI,unsigned,cStatus,ucComMF522Buf,char,RC522,电路设计,uc
From: https://blog.csdn.net/STM89C56/article/details/136668531

相关文章

  • 14---DVI电路设计
    视频链接DVI硬件电路设计01_哔哩哔哩_bilibiliDVI电路设计1、DVI的简介DVI(DigitalVisualInterface),即数字视频接口。它是1998年9月,在Intel开发者论坛上成立的,由SiliconImage、Intel(英特尔)、Compaq(康柏)、IBM(国际商业机器公司)、HP(惠普)、NEC(日本电气股份有限公司......
  • 【触想智能】工业一体机刷卡应用知识分享
    工业一体机刷卡技术是一种高效、稳定、安全的身份认证方式,具有广泛的应用场景和优势。在工业自动化控制、生产过程监测等领域,它已成为必不可少的设备之一。一、工业一体机刷卡的原理:工业一体机刷卡的原理和普通的刷卡设备类似,都是通过读取磁条或芯片内嵌的信息,从而实现......
  • [经验] visa卡怎么刷卡消费不能用
    1、visa卡怎么刷作为一种常用的信用卡,Visa卡在全球各地广泛受到接受。Visa卡可以在众多商户店铺进行不同种类的交易,如购物、餐饮、旅游和娱乐等方面。那么,如何刷Visa卡呢?确保商家支持Visa卡,一般商家会明示在门口或收银台处。向收银员说明您的付款方式是使用Visa卡并需要刷卡。此时,......
  • 模拟集成电路设计系列博客——5.3.2 电容重置开关电容增益电路
    5.3.2电容重置开关电容增益电路为了消除需要放大器输出每个时钟周期都需要摆动到接近0V,并且仍然能够取消掉放大器的失调电压,可以使用一个电容重置正义电路。这个正义电路的基本思路是通过一个之前充电到输出电压电容,将放大器的输出在复位相耦合到一个反相的输入。因此,我们会看到......
  • 模拟集成电路设计系列博客——5.3.1 可重置开关电容增益电路
    5.3.1可重置开关电容增益电路最常见的非滤波器模拟功能是可能增益电路,即输出信号是输入信号的比例缩放。使用开关电容技术可以实现精确的正义电路。开关电容增益电路的一个重要应用是在流水线ADC中。具体的流水线ADC中的开关电容电路会在那个章节中进行讨论。在有源RC电路中,增......
  • 模拟集成电路设计系列博客——5.2.2 二阶开关电容滤波器
    5.2.2二阶开关电容滤波器类似于一阶的情况,二阶开关电容滤波器结构可以通过参考连续时间滤波器结构来实现。然而,和一阶滤波器一样,一旦确定滤波器结构,其精确的频率响应需要通过离散时间分析求得。使用精确的传输函数,或者是几个精确的近似,可以确定设计环节时所需要的电容比例。一......
  • DC电源模块如何简化电路设计
    BOSHIDADC电源模块如何简化电路设计DC电源模块是一种集成了直流电源电路的模块,可以提供稳定的直流电源输出。使用DC电源模块可以简化电路设计,具体步骤如下:1.选择合适的DC电源模块:根据电路所需的电压和电流要求,选择合适的DC电源模块。通常,DC电源模块有不同的输出电压和电流等级可......
  • 模拟集成电路设计系列博客——4.4.5 基于自适应滤波的修调
    4.4.5基于自适应滤波的修调自适应滤波一般用于数字信号处理应用中,例如模型观察,通道均衡,或者噪声消除。同时也可以使用自适应滤波技术来修调一个给定场景中的连续时间滤波器。一个实现的例子可以参考下图[Kozma,1991]:其中自适应修调电路被用于最小化误差信号。在进行修调时,输......
  • 模拟集成电路设计系列博客——4.4.4 Q因子修调
    4.4.4Q因子修调在一些需要高速或者高度选择的滤波器中,非理想的积分器效应和寄生参数使得电路需要对积分器的极点进行Q因子修调。尽管我们之前讨论过如何通过修调单独的时间常数使得集成滤波器的的因子达到百分之1以内的误差,当\(Q>1\)时,即使Q因子上有微小的误差也可能会在滤波器......
  • 模拟集成电路设计系列博客—— 4.4.3 频率修调
    4.4.3频率修调如果有精确的时钟的话,那么可以精确的修调\(G_m/C_A\)。例如,假设设计者有一个精确的时钟频率,称为\(f_{clk}\),那么一种使用开关电容电路进行修调的方式如下图所示[Viswanathan,1982]:这个修调电路与我们上一节介绍的固定跨导修调电路很像,除了外部电阻被更换为了一个......