手把手从0到1教你做STM32+FreeRTOS智能家居--第9篇之RC522读卡器

一、硬件设计

硬件接线:

SPI_NSS(CS)  -- PA4

SPI_SCK-- PA5

SPI_MISO -- PA6

SPI_MOSI -- PA7

SPI_RST -- PD2

二、软件设计

本项目用到的是IO口模拟SPI,STM32Cubemx直接将PA4、PA5、PA7、PD2配置为推挽输出,PA6配置为输入即可。

RC522.c

#include "rc522.h"


#define   RC522_DELAY()  delay_us ( 2 )
#define fac_us 72   //时钟频率,单位MHZ

uint32_t RC522_ID1 = 0xED0B562D; //小圆球ID

void Get_RC522(void)
{
	uint32_t writeValue = 100;
	uint32_t readValue;
	char cStr [ 30 ];
  uint8_t ucArray_ID [ 4 ];    /*先后存放IC卡的类型和UID(IC卡序列号)*/                                                                                         
	uint8_t ucStatusReturn;      /*返回状态*/        	
	static uint8_t Rc_Timeout;
	uint8_t status;
	uint8_t Card_ID[4];
	
	HAL_Delay(100);
	/*寻卡*/
	while( (ucStatusReturn = PcdRequest ( PICC_REQIDL, ucArray_ID )) != MI_OK )
	{
		/*若失败再次寻卡*/
		Rc_Timeout++;
		HAL_Delay(100);
		//printf ( "寻卡失败\n" );
		ucStatusReturn = PcdRequest ( PICC_REQIDL, ucArray_ID ); //PICC_REQALL   PICC_REQIDL
		if(Rc_Timeout >= 10)
		{
			Rc_Timeout = 0;
			break;
		}
	}
	if ( ucStatusReturn == MI_OK  )
	{
		printf ( "寻卡成功\n" );
		status = PcdAnticoll(Card_ID);
		//判断读取的ID是否为的小圆球ID,是的话再做操作。
		if(status)
		{
			if(Card_ID[0] == ((RC522_ID1 & 0xFF000000) >> 24) )
				if(Card_ID[1] == ((RC522_ID1 & 0x00FF0000) >> 16))
					if(Card_ID[2] == ((RC522_ID1 & 0x0000FF00) >> 8))
						if(Card_ID[3] == ((RC522_ID1 & 0x000000FF) >>0 ))
							printf("小圆球\n");
		}
	}
}

void delay_us(uint32_t nus)
{
	uint32_t ticks;
	uint32_t told,tnow,tcnt=0;
	uint32_t reload=SysTick->LOAD;			//LOAD的值
	ticks=nus*fac_us; 						//需要的节拍数
	told=SysTick->VAL;        				//刚进入时的计数器值
	while(1)
	{
		tnow=SysTick->VAL;
		if(tnow!=told)
		{
			if(tnow<told)tcnt+=told-tnow;	//这里注意一下SYSTICK是一个递减的计数器就可以了.
			else tcnt+=reload-tnow+told;
			told=tnow;
			if(tcnt>=ticks)break;			//时间超过/等于要延迟的时间,则退出.
		}
	}
}



/**
  * @brief  RC522_Init
  * @param  无
  * @retval 无
  */
void RC522_Init ( void )
{
//	RC522_Reset_Disable();	
//	RC522_CS_Disable();
	PcdReset ();/*RC522相关*/
	HAL_Delay(50);
	PcdReset();//复位RC522读卡器
	HAL_Delay(10);
	PcdReset();//复位RC522读卡器
	HAL_Delay(10);
	PcdAntennaOff();//关闭天线发射
	HAL_Delay(10);
  PcdAntennaOn();//开启天线发射
	
//	M500PcdConfigISOType ( 'A' );/*RC52射频模 设置工作方式*/
	printf("RFID-MFRC522 初始化完成\r\nFindCard Starting ...\r\n");
}


/**
  * @brief  IC测试函数
  * @param  无
  * @retval 无
  */
extern uint8_t KeyValue[];   // 卡A密钥
void IC_test ( void )
{
	uint32_t writeValue = 100;
	uint32_t readValue;
	char cStr [ 30 ];
  uint8_t ucArray_ID [ 4 ];    /*先后存放IC卡的类型和UID(IC卡序列号)*/                                                                                         
	uint8_t ucStatusReturn;      /*返回状态*/                   
	static uint8_t Rc_Timeout;
  while ( 1 )
  {    
    /*寻卡*/
		if ( ( ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ) ) != MI_OK )
    {
      /*若失败再次寻卡*/
			Rc_Timeout++;
			HAL_Delay(1000);
      printf ( "寻卡失败\n" );
			ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ); //PICC_REQALL   PICC_REQIDL
			if(Rc_Timeout >= 10)
			{
				Rc_Timeout = 0;
				break;
			}
    }
		if ( ucStatusReturn == MI_OK  )
		{
      printf ( "寻卡成功\n" );
			//Voice_Send("RC522 OK");
			//delay_ms(2000);
			HAL_Delay(2000);
			break;
//      /*防冲撞(当有多张卡进入读写器操作范围时,防冲突机制会从其中选择一张进行操作)*/
//			if ( PcdAnticoll ( ucArray_ID ) == MI_OK )                                                                   
//			{
//				PcdSelect(ucArray_ID);			
//		
//				PcdAuthState( PICC_AUTHENT1A, 0x11, KeyValue, ucArray_ID );//校验密码 
//        WriteAmount(0x11,writeValue); //写入金额
//        if(ReadAmount(0x11,&readValue) == MI_OK)	//读取金额
//				{		
//					writeValue +=100;
//				  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 );  //打印卡片ID
//					
//					printf ("余额为:%d\r\n",readValue);
//					sprintf ( cStr, "TThe residual amount: %d", readValue);				 										 	         
//          PcdHalt();
//				}
//			}				
		}		
  }	
}

/**
  * @brief  向RC522发送1 Byte 数据
  * @param  byte,要发送的数据
  * @retval RC522返回的数据
  */
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;
	
}



/**
  * @brief  读RC522寄存器
  * @param  ucAddress,寄存器地址
  * @retval 寄存器的当前值
  */
uint8_t ReadRawRC ( uint8_t ucAddress )
{
	uint8_t ucAddr, ucReturn;
	
	ucAddr = ( ( ucAddress << 1 ) & 0x7E ) | 0x80;	
	RC522_CS_Enable();
  
	SPI_RC522_SendByte ( ucAddr );
	ucReturn = SPI_RC522_ReadByte ();
  
	RC522_CS_Disable();
	
	return ucReturn;	
}

/**
  * @brief  写RC522寄存器
  * @param  ucAddress,寄存器地址
  * @param  ucValue,写入寄存器的值
  * @retval 无
  */
void WriteRawRC ( uint8_t ucAddress, uint8_t ucValue )
{  
	uint8_t ucAddr;
	
	ucAddr = ( ucAddress << 1 ) & 0x7E;	
	RC522_CS_Enable();
	
	SPI_RC522_SendByte ( ucAddr );	
	SPI_RC522_SendByte ( ucValue );
  
	RC522_CS_Disable();		
}


/**
  * @brief  对RC522寄存器置位
  * @param  ucReg,寄存器地址
  * @param   ucMask,置位值
  * @retval 无
  */
void SetBitMask ( uint8_t ucReg, uint8_t ucMask )  
{
  uint8_t ucTemp;

  ucTemp = ReadRawRC ( ucReg );
  WriteRawRC ( ucReg, ucTemp | ucMask ); // set bit mask
}


/**
  * @brief  对RC522寄存器清位
  * @param  ucReg,寄存器地址
  * @param  ucMask,清位值
  * @retval 无
  */
void ClearBitMask ( uint8_t ucReg, uint8_t ucMask )  
{
  uint8_t ucTemp;

  ucTemp = ReadRawRC ( ucReg );
  WriteRawRC ( ucReg, ucTemp & ( ~ ucMask) ); // clear bit mask
}


/**
  * @brief  开启天线 
  * @param  无
  * @retval 无
  */
void PcdAntennaOn ( void )
{
  uint8_t uc;

  uc = ReadRawRC ( TxControlReg );
  if ( ! ( uc & 0x03 ) )
   SetBitMask(TxControlReg, 0x03);		
}


/**
  * @brief  关闭天线
  * @param  无
  * @retval 无
  */
void PcdAntennaOff ( void )
{
  ClearBitMask ( TxControlReg, 0x03 );	
}


/**
  * @brief  复位RC522 
  * @param  无
  * @retval 无
  */
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 );
  
	//定义发送和接收常用模式 和Mifare卡通讯,CRC初始值0x6363
  WriteRawRC ( ModeReg, 0x3D );        
	
  WriteRawRC ( TReloadRegL, 30 );      //16位定时器低位    
	WriteRawRC ( TReloadRegH, 0 );			 //16位定时器高位
	
  WriteRawRC ( TModeReg, 0x8D );			 //
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值