RFID的检测电路设计和stm32驱动程序

目录

电路

代码


        提示:此代码不是复制粘贴后就可以使用,肯定是有一些小细节要注意,要搭配RFID的通讯协议一起使用效果更加。

电路

       

        对这个电路做一个简单的分析最前面使用一个单片机的普通io做一个推挽输出,增强后面天线的信号发射能力,后面到运放的电路大多都是滤波和限压使用(D2和D3这两个二极管是对电压形成一种钳制的效果,我经常叫限压,如果说的不对请大佬纠正),到第一个358是一个同向放大,使得信号更容易识别,到后面那个358就是一个比较器的作用,将模拟信号转换成数字信号给予单片机进行识别

代码

        代码实现方面,先使用一个引脚输出125kmhz的方波,在使用引脚中断和定时器编写逻辑最后获得RFID的基本数据

        定时器2是用来输出125khz的方波

        

        定时器3配合引脚的中断一起使用,实现获得RFID的数据。

大家一定要记得开启定时器和pwm输出


	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);

	HAL_TIM_Base_Start(&htim3);

中断服务函数

void EXTI3_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI3_IRQn 0 */
	static uint8_t BitsCnt = 0;	//½ÓÊÕbit¼ÆÊý£¬½ÓÊÕµÀ128¸öÔò½øÈëУÑé
	static uint8_t flag = 0;  //¿ÕÌø±êÖ¾
	uint8_t Value = 0;			//
	uint16_t temp = 0;  //ʱ¼ä¼ÆÊý ¶¨Ê±Æ÷Ϊ8Mhz ÐèÒª512us Ò»ÖÜÆÚ¼ÆÊý4096 °ë¸öΪ2048
//	GPIO_PinState pinState = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3);
	
//	 if (HAL_TIM_IC_GetCapture(&htim1, TIM_CHANNEL_4) != HAL_OK)
//    {
//        Error_Handler();
//    }
	
    if (!CodeBitsRecComplete)
    {
			temp = TIM3->CNT;//    temp = HAL_TIM_ReadCapturedValue(&htim1, TIM_CHANNEL_4);   //»ñµÃ¼ÆÊýÆ÷µ±Ç°Öµ       
			if (temp > 3000 && temp < 5000) 
			{		
//				  printf("L");
				
				 HAL_TIM_Base_Stop(&htim3);
			   TIM3->CNT=0;// __HAL_TIM_SET_COUNTER(&htim1, 0); //¶¨Ê±Æ÷Çå0
         HAL_TIM_Base_Start(&htim3);
				
				if (flag)             //ÊÇ·ñ¼ì²âµ½¿ÕÌø
				{
					Value = ((ManchesterCodeBits[(BitsCnt - 1) / 8] >> (7 - (BitsCnt - 1) % 8)) & 0x01) ? 1 : 0;    //ÉÏÒ»¸öbitΪ1ÔòΪ1£¬·ñÔòΪ0
//					HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2)) ;
				}else  {Value = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) ? 0 : 1;} //HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3)) ;
				flag = 0;
				ManchesterCodeBits[BitsCnt / 8] |= (Value << (7 - BitsCnt % 8));
        BitsCnt++;
				if (BitsCnt > 127)
        {
            CodeBitsRecComplete = 1;
            BitsCnt = 0;
        }
			}
			else if (temp > 1000 && temp < 3000) // Ò»°ëÖÜÆÚ£¬¼ÆÊýֵԼΪ2048
			{
        flag = 1;  // ¼ì²âµ½Ò»¸ö¿ÕÌø
			}
		}
		
  /* USER CODE END EXTI3_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
  /* USER CODE BEGIN EXTI3_IRQn 1 */

  /* USER CODE END EXTI3_IRQn 1 */
}

RFID.c文件

#include "RFID.h"


struct Card_Uid{
	uint8_t Num;   //¿¨´úºÅ
	uint8_t Id[4];  	//¿¨ºÅ
}UID[MAX];


volatile	uint8_t card_num=1; // ¿¨IDµÄ±äÁ¿ ÔÝʱ
uint8_t Count_UID=0;   //¿¨ºÅÐòºÅ
uint8_t card_count=0;	//at´æ´¢µØÖ·
uint8_t readUid[5];		//¼ì²â¿¨ºÅÔÝ´æ´¦

uint8_t ff=0xff;

uint8_t GetBitValue(uint8_t bitsCnt)
{
	return (ManchesterCodeBits[bitsCnt / 8] >> (7 - bitsCnt % 8)) & 0x01;
}

/**
  * @brief  Êý¾ÝУÑé
  * @note   Ó¦·ÅÔÚÖ÷Ñ­»·ÖнøÐУ¬»ò·ÅÔÚ¹ýÂ˺¯Êý£¨Ó¦Îª¶à´Î¶Áµ½µÄÊý¾Ý¾ùÎÞ´í²ÅÈÏΪ¶Áµ½£©
  * @param  pBuff ´æ´¢¿¨ºÅµÄÊý×é
  * @retval None
  */
int8_t GetCardNO(uint8_t * pBuff)
{
	uint8_t bitsCnt = 0;
	uint8_t i = 0;
	uint8_t j = 0;
	uint16_t Value = 0;
	int8_t status = CARDFALSE;   //УÑéʧ°Ü  -2
	if (!CodeBitsRecComplete) return CARDREADING;     //Ñ°¿¨ÖÐ   -1
	//
	status = CARDFALSE;//  УÑéʧ°Ü
	
	/* ÕÒµ½ 0 1 1111 1111 (1ֹͣλ+9Òýµ¼Î») Èç¹ûbit63-bit72ÈԾɲ»ÊÇ£¬Ôò²»ÐèÒªÔÙÑ°ÕÒ */
	while (bitsCnt <= 63) 
	{
		Value = 0;
		for (j = 0; j <= 9; j++)
		{
			Value <<= 1;
			Value |= GetBitValue(bitsCnt + j);
		}
		if ( Value == 0x01ff ) //ÕÒµ½ 0 1 1111 1111
		{
		
			bitsCnt += 10;	//Ìø¹ýֹͣλºÍÒýµ¼Î»
			break;
		}
		else				//ûÓÐÕÒµ½ 0 1 1111 1111
		{
			bitsCnt++;
		}
	}
		if (bitsCnt != 64)
		{	
				status = CARDTRUE;
				/* 10×éÐÐÊý¾Ý½øÐÐУÑé*/
				for (i = bitsCnt; i <= (bitsCnt + 45); i += 5)
				{
						Value = 0;
						for (j = 0; j <= 3; j++)
						{
								Value +=  GetBitValue(i + j);   //ÿÐÐ4bitÊý¾ÝÀÛ¼Ó
						}
						if ( Value % 2 != GetBitValue(i + 4) )
						{
								status = CARDFALSE;
								break;
						}
				}
				if (status == CARDTRUE)
				{
						/* ¶Ô4×éÁÐÊý¾Ý½øÐÐУÑé */
						for (i = bitsCnt; i <= (bitsCnt + 3); i++)
						{
								Value = 0;
								for (j = 0; j <= 45; j += 5)
								{
										Value +=  GetBitValue(i + j);   //ÿÁÐ10bitÊý¾ÝÀÛ¼Ó
								}
								if ( Value % 2 != GetBitValue(i + 50) )
								{
										status = CARDFALSE;
										break;
								}
						}
				}
				if (status == CARDTRUE)
				{
						/* ֹͣλ */
						if (GetBitValue(bitsCnt + 54) == 0)
						{
								status = CARDTRUE;
								/* 4×Ö½Ú¿¨ºÅ */
								for (i = 0; i < 4; i++)
								{
										pBuff[i] = 0;
										for (j = 0; j <= 8; j++)
										{
												if (j != 4)
												{
														pBuff[i] <<= 1;
														pBuff[i] |= GetBitValue(bitsCnt + (i + 1) * 10 + j);
												}
										}
								}
						}
						else{
							status = CARDFALSE;
						}
								
				}
		}
		for (i = 0; i < 16; i++)
		{
			ManchesterCodeBits[i] = 0;
		}
		CodeBitsRecComplete = 0;
		return status;
}

/**
  * @brief  ¿¨ºÅÊý¾Ý´æ´¢
  * @note   ¶Ô¶ÁÈ¡µÄµÄ¿¨ºÅ½øÐд洢
  * @param  None
  * @retval None
  */
void save_card(void)
{
	AT24C02_WriteByte(card_count,UID[Count_UID-1].Num);
	card_count+=1;
	HAL_Delay(20);
	for(uint8_t i=0;i<4;i++)
		{
			AT24C02_WriteByte(card_count,UID[Count_UID-1].Id[i]);
			card_count++;
			HAL_Delay(500);
		}	

}

/**
  * @brief  ´´½¨¿¨ºÅ
  * @note   ´´½¨¿¨ºÅ²¢¶Ô¶ÁÈ¡µÄµÄ¿¨ºÅ½øÐд洢
  * @param  None
  * @retval None
  */
void Create_card(uint8_t *readUid)
{
	uint8_t i; 
	uint8_t Flag_Create=1;

	strcpy((char*)UID[Count_UID].Id,(char*)readUid);
	for(i=0;i<Count_UID;i++)
	{
//        if(strcmp((char *)UID[Count_UID].Id,(char *)UID[i].Id)==0)
		if(!strncmp((char *)UID[i].Id,(char *)UID[Count_UID].Id,4))
		{
  			printf("Óû§ÒÑ´æÔÚ£¡\n"); 
				Flag_Create=0;
        	break;
		}
	 }
	UID[Count_UID].Num=card_num;
	if(Flag_Create)
	{	
		card_num+=1;
		printf("ÐòºÅ£º%d ´´½¨¿¨ºÅ£º%x-%x-%x-%x\n",UID[Count_UID].Num,UID[Count_UID].Id[0],UID[Count_UID].Id[1],UID[Count_UID].Id[2],UID[Count_UID].Id[3]);
		Count_UID++;
		
//		AT24C02_WriteByte(0,UID[Count_UID].Id[0]);
		save_card();
	}
}
/**
  * @brief  ɾ³ý¿¨ºÅ
  * @note   ɾ³ýÑ¡ÔñµÄ¿¨ºÅ£¬²¢µÝ½ø´æ´¢¿Õ¼ä
  * @param  num Ñ¡ÔñµÄ¿¨ÐòÁкÅ
  * @retval None
  */
void Cancel_card(uint8_t num)
{
		volatile	uint8_t x=0;
    uint8_t a,b;
		for(a=0;a<Count_UID;a++)
		{
			if(!strncmp((char *)&num,(char *)&UID[a].Num,1))
			break;
		}
		if(a>=Count_UID)  printf("Óû§²»´æÔÚ!\r\n");
		else{
					for(b=a; b<Count_UID; b++) UID[b]=UID[b+1];		
					Count_UID--;
					for(uint8_t i=0;i<Count_UID;i++)
					{
						AT24C02_WriteByte(x,UID[i].Num);
						HAL_Delay(20);
						x++;
						for(uint8_t y=0;y<4;y++)
						{
							AT24C02_WriteByte(x,UID[i].Id[y]);
							HAL_Delay(20);
							x++;
						}		
					}
					for(x;x<255;x++)
					{
								AT24C02_WriteByte(x,0xff);
								HAL_Delay(20);
					}
					printf("ɾ³ý³É¹¦\r\n");
			}
}
/**
  * @brief  ÏÔʾËùÓп¨ºÅ
  * @note   ÏÔʾ´æ´¢ÆäÖÐËùÓп¨ºÅÓëÐòºÅ
  * @param  None
  * @retval None
  */

void show_card(void)
{
		volatile	uint8_t y=0;
		uint8_t AT_num;   //¶ÁÈ¡µÄÊä³öÔÝ´æ 
		card_count=0;
		Count_UID=0;
		for(uint8_t i=0;i<255;i++)
	{
			AT_num=AT24c02_read(i);
			
			if(strncmp((char *)&ff,(char *)&AT_num,1))	
			{
				if(i%5) 
				{ 
//						strcpy((char*)&UID[Count_UID-1].Id[y],(char*)&a); 
						UID[Count_UID-1].Id[y]=AT_num; 
						y++;
						if(y>3) y=0;
				}
				else{
				UID[Count_UID].Num=AT_num;
				card_num=UID[Count_UID].Num+1;
				Count_UID++;
				}
				card_count=i+1;
			}
	}
//	HAL_Delay(20);
	for(uint8_t i=0;i<Count_UID;i++)
		{
			printf("ÐòºÅ:%d ¿¨ºÅ£º%x-%x-%x-%x\n",UID[i].Num,UID[i].Id[0],UID[i].Id[1],UID[i].Id[2],UID[i].Id[3]);
		}
		printf("×ÜÊý£º%d\n",Count_UID);
}


uint8_t readCard(uint8_t *readUid)
{
	if (GetCardNO(readUid) == 0)   //»ñÈ¡¿¨ºÅ	
		{
			Create_card(readUid);
			return 0;
		}	
		return 1;

}

RFID.h文件

#ifndef __RFID_H
#define __RFID_H

//#include "stm32f1xx_hal.h"
#include "main.h"
#include "AT24C02.h"

#define MAX  100
#define CARDFALSE -2   //УÑéʧ°Ü  -2
#define CARDREADING -1 //Ñ°¿¨ÖÐ   -1
#define CARDTRUE   0   //УÑé³É¹¦   0

extern uint8_t ManchesterCodeBits[16];
extern uint8_t CodeBitsRecComplete;



int8_t GetCardNO(uint8_t * readUid); //¶Á³ö¿¨ºÅ
uint8_t readCard(uint8_t *readUid); // ¶ÁÈ¡²¢´´½¨¿¨ºÅ
void save_card(void);   //±£´æ¿¨ºÅ
void Create_card(uint8_t *readUid);	//´´½¨¿¨ºÅ
void Cancel_card(uint8_t num);//×¢Ïú¿¨ºÅ
void show_card(void);  //չʾ¿¨ºÅ

#endif

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值