⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfid.c

📁 利用射频卡读写基站U2270B实现对EM4100卡的读取控制。系统会自动对曼彻斯特编码进行解调
💻 C
字号:
/*H4001只读卡读码程序*/
/******************头文件********************/
#include <AT89X52.h>
#include <absacc.h>
#include <intrins.h>

#define uchar unsigned char
#define uint  unsigned int

sbit RF_DATA_IN=P1^2;         //接收来至U2270B的数据"Output"

/****************全局变量***********************/
uchar data Read_RF_Data[11];   //暂存从U2270B上接收的数据
extern uchar data ID_Data[6];                  //暂存经效验后的正确数据
uint  data TIMER_1=0;
bit Check_Data_bit;              //效验请求标志位
bit flag_card;//卡存在标志,1代表存在,0代表不存在
uint count;//数据读取最大次数
extern bit READ_SUCESS; //读取数据检验正确标志,1代表正确,0代表错误

/****************函数列表***********************/
void Recive_RF_Data(void);     
void Check_Data(void);
void Clern_Number(void);
void delay1ms(uint count);

void print_data_hex(uchar,uchar);
void print(uchar,uchar *);
void inital();
void pcf8563();
void test_ID();
void wcmd(uchar);
void wdat(uchar);
void pcf8563_read();

display_RFID()
{
	print(0x80,"EM4001卡号                      ");		 //空格表示显示空格
	print_data_hex(0x90,ID_Data[0]);
	print_data_hex(0x91,ID_Data[1]);
	print_data_hex(0x92,ID_Data[2]);
	print_data_hex(0x93,ID_Data[3]);
	print_data_hex(0x94,ID_Data[4]);
	print(0x95,"                      ");
}
void Data_start(void)
{
	TMOD=0x11;                                                    //T0方式1,T1工作于方式2
	TH1=0x00;                                                        //初始化T1计时器
	TL1=0x00;
	TR1=0;
	TH0=0x00;                                                        //初始化T0计时器
	TL0=0x00;
	TR0=0;
	EA=1;                                                             //开放总中断
	ET0=0;ET1=0;
}


/**********************************************/
/*主函数*/
/**********************************************/
/*void main(void)
{
	delay1ms(100);
	P1_1=1;
	P1_0=1;
	P3_1=1;
	inital();
	Data_start();
	flag_card=0;
	while(1)
	{
		test_ID();
		if(flag_card==1)
		{
			Recive_RF_Data();         //调用接收RF数据函数
			if(flag_card==1)
			{
				if(Check_Data_bit==1 )     //如果此位为1,有一组数据申请效验
				{
					Check_Data_bit=0;
					Check_Data();         //调用数据效验函数
					display_RFID();
					Clern_Number();
				}
				else
				{
					Clern_Number();
				//	print(0x88,"fail");
				//	pcf8563();
				}
			}
			else pcf8563();
			flag_card=0;
		}
		else   pcf8563();
	}
} */


void RFID_2(void)
{
	test_ID();
	if(flag_card==1)
	{
		Recive_RF_Data();         //调用接收RF数据函数
		if(flag_card==1)
		{
			if(Check_Data_bit==1 )     //如果此位为1,有一组数据申请效验
			{
				Check_Data_bit=0;
				Check_Data();         //调用数据效验函数
				display_RFID();
			}
			else
				pcf8563_read();
		}
		else pcf8563_read();
	}
	else   pcf8563_read();
} 

void RFID()
{
	count=0;
	READ_SUCESS=0;
	flag_card=0;
	Check_Data_bit=0;

	Recive_RF_Data();         //调用接收RF数据函数
	if(flag_card==1)
	{
		if(Check_Data_bit==1 )     //如果此位为1,有一组数据申请效验
		{
			print(0x88,"校验····");
			Check_Data_bit=0;
			Check_Data();         //调用数据效验函数
			if(READ_SUCESS==1)	
			{
				display_RFID();
			}
			else
			{
				inital();
				print (0x80,"检验错误");
				print(0x90,"请重新读取");
			}
		}
		else
		{
			READ_SUCESS=0;
			inital();
			print(0x80,"读取失败");
			print(0x88,"请将卡片放在图示");
			print(0x98,"读卡区域内");
		}
	}
	else 
	{
		READ_SUCESS=0;
		inital();
		print(0x80,"未检测到卡");
		print(0x88,"请将卡片放在图示");
		print(0x98,"读卡区域内");
	}

}

void test_ID()//检测是否有卡存在
{
		TH0=(65526-2000)/256;   //在1毫秒时间内检测高电平
		TL0=(65526-2000)%256;
		TF0=0;
		TR0=1;
		while(RF_DATA_IN==0)
		{
			if(TF0==1)
	 		{
				flag_card=0;//1毫秒内没有电平信号,认为卡不存在,置标志位0
				TR0=0;
				TF0=0; 
				goto go1;
			}
		}
		flag_card=1;//检测到电平跳变,卡存在,置标志位
		TR0=0;
		go1:_nop_();
}

/*********************************************/
/*接收RF数据*/
/*********************************************/
void Recive_RF_Data()
{
	uchar  pc;
	uchar  temp1;
	uchar  ByteCounter;                                      //字节计数器
	uchar  *PData;
	uchar  BitCounter;                                        //位计数器
////////////////////初始化变量值
 	uint temp2;
	uchar header;
	uchar temp;
	PData=Read_RF_Data;
	count=0;

 	test_ID();//检测卡是否存在
	if(flag_card==0)
	goto str2;

str1:
	count++;
	if(count>=500)
	{	
		READ_SUCESS=0;//读取次数超过100次,读取失败
		goto str2;
	}

	header=0;
	temp=0;
	temp1=0;
	ByteCounter=0;
	BitCounter=5;    
	pc=4;
		TH0=0x00;
		TL0=0x00;
		TR0=0;
		TR0=1;
	if(RF_DATA_IN==1)     //首先检测9个1,曼彻斯特编码0对应下跳变,1对应上跳变,故在检测1时必须检测到一个持续一个周期的低电平,并且随后伴有高电平跳变
	{
		while(RF_DATA_IN==1 && TF0==0); 
		if(TF0==1)
		{
			flag_card=0;
			goto str2;   //如果卡片突然移走,自动退出
		}
		TH0=0x00;
		TL0=0x00;
		TF0=0;
		while(RF_DATA_IN==0 && TF0==0);       //当电平由高向低变跳时启动计时器     
		TR0=0;                 //电平变高时停止计数
		if(TF0==1)
		{
			flag_card=0;
			goto str2;   //如果卡片突然移走,自动退出
		}
		TIMER_1=TH0;
		TIMER_1=(TIMER_1<<8)+TL0;            
		TH0=0x00;
		TL0=0x00;
		temp2=1100;
		if(TIMER_1>temp2)       // >520us,确定数据为1
		{
		     goto str1;
		}
		temp2=800;
		if(TIMER_1<temp2)       // <490us
		{
		     goto str1;
		}

 		do
		{
			TIMER_1=0;
			TR0=1;
			while(RF_DATA_IN==1 && TF0==0);
			if(TF0==1)
			{
				flag_card=0;
				goto str2;   //如果卡片突然移走,自动退出
			}
			TH0=0x00;
			TL0=0x00;
			TF0=0;
			while(RF_DATA_IN==0 && TF0==0);
			TR0=0;
			if(TF0==1)
			{
				flag_card=0;
				goto str2;   //如果卡片突然移走,自动退出
			}
			TIMER_1=TH0;
			TIMER_1=(TIMER_1<<8)+TL0;
			TH0=0x00;
			TL0=0x00;
			temp2=600;
			if(TIMER_1>temp2)// >280us
			{
			    header=0;
			    goto str1;
			}
			temp2=300;
			if(TIMER_1<temp2)// <230us
			{
			    header=0;
			    goto str1;
			}
			header++;
	}while(header<8);

	TR0=0;
	TF0=0;
	TH0=0xfd;                                          //time:300us
	TL0=0x9E;
	TR0=1;
	do
	{
		do
		{
			while(TF0==0);
			TF0=0;
			if(RF_DATA_IN==1) temp=1;
			else temp=0;
			while(RF_DATA_IN==temp)                  //检测电平跳变否?
			{
				if(TF0==1)                            //如果300us计时到还未跳变,视为非法电平!!!
				{
					TR0=0;
					TF0=0;
					goto str1;
				}
			}
			temp=RF_DATA_IN;
			TH0=0xfd;                                          //time:300us
			TL0=0x9e;
			temp1=(temp1<<1)|temp;
			BitCounter--;     	
		}while(BitCounter);                               //一个字节完否
		*(PData+ByteCounter)=temp1;                 //将一字节数据存入缓存数组
		temp1=0;
		BitCounter=5;
		ByteCounter++;
	}while(ByteCounter<10);

			do
			{                     
//				WATCHDOG=~WATCHDOG;
				while(TF0==0);                                    //等待一个位周期
				TF0=0;
				if(RF_DATA_IN==1) temp=1;
				else temp=0;
				while(RF_DATA_IN==temp)                         //检测电平跳变否?
				{
					if(TF0==1)                     //如果300us计时到还未跳变,视为非法电平!!!
					{
						TR0=0;
						TF0=0;
						goto str1;
					}
				}
				TH0=0xfd;                                          //time:300us
				TL0=0x9e;
				temp=RF_DATA_IN;
				temp1=(temp1<<1)|temp;
				pc--;                     
			}while(pc);                                                        //一个字节完否
			Read_RF_Data[10]=temp1;


			while(TF0==0);
			TF0=0;
			if(RF_DATA_IN==1) temp=1;
			else temp=0;
			while(RF_DATA_IN==temp)                  //检测电平跳变否?
			{
				if(TF0==1)                            //如果300us计时到还未跳变,视为非法电平!!!
				{
					TR0=0;
					TF0=0;
					goto str1;
				}
			}
			temp=RF_DATA_IN;			
			if(temp==0)                                   //如果停止位正确
			{
			    Check_Data_bit=1;          //置效验请求标志
			}
			else                                     //如果停止位不正确
			{
			    Clern_Number();                    //清除
			}
	}
	str2: _nop_();
}  


/*********************************************/
                        /*效验数据*/
/*********************************************/
void Check_Data(void)
{
/////////////////////定义局部变量
	uchar  temp;
	uchar  temp1;
	uchar  ByteCounter;                                      //数组计数器
	uchar  ByteCounter1;
	uchar  *PData;
	uchar  *PData1;
////////////////////初如化变量值
	PData=Read_RF_Data;
	PData1=ID_Data;
	temp=0;
	temp1=0;
	ByteCounter=0;
	ByteCounter1=0;
/////////////////////循环效验       
//	WATCHDOG=~WATCHDOG;
/////////////////////行校验
	for(ByteCounter1=0;ByteCounter1<5;ByteCounter1++)//有5个字节数据
	{
		temp=(((*(PData+ByteCounter))&0x10)>>4)+(((*(PData+ByteCounter))&0x08)>>3)+(((*(PData+ByteCounter))&0x04)>>2)+(((*(PData+ByteCounter))&0x02)>>1);     
		if((temp&0x01)==((*(PData+ByteCounter))&0x01))//效验高4位
		{
			temp1=(*(PData+ByteCounter)&0xfe)<<3;
			ByteCounter++;
			temp=(((*(PData+ByteCounter))&0x10)>>4)+(((*(PData+ByteCounter))&0x08)>>3)+(((*(PData+ByteCounter))&0x04)>>2)+(((*(PData+ByteCounter))&0x02)>>1);     
			if((temp&0x01)==((*(PData+ByteCounter))&0x01))//效验高4位
			{
				*(PData1+ByteCounter1)=temp1|((*(PData+ByteCounter)&0xfe)>>1);//高低位生成一个字节存入数组
				ByteCounter++;
				READ_SUCESS=1;
			}
			else
			{
				READ_SUCESS=0;
			    ByteCounter1=5;//只要有一组不对则退出效验
			    Clern_Number();//并清所有数据
			}
		}
		else
		{
			READ_SUCESS=0;
			ByteCounter1=5;//只要有一组不对则退出效验
			Clern_Number();//并清所有数据
		}
//		WATCHDOG=~WATCHDOG;
	}
/////////////////////列校验
//......因没有必要所以先省略此处.........//
/////////////////////生成校验和,并发送出去
/*	if(ByteCounter==10)
	{
		ID_Data[5]=ID_Data[0]+ID_Data[1]+ID_Data[2]+ID_Data[3]+ID_Data[4];//生成校验和
		if(MSEL==0)    //此脚如果为低电位,为异步通信方式发送数据
		{
			CP=0;
			delay0_2ms(1);
			Send_RS232net(ID_Data,6);       //调用串口发送函数
			delay0_2ms(1);
			CP=1;
		} 
		Clern_Number();
//		dida(1);
		delay0_2ms(1000);//*****(正确读取一张卡号后要等待约一秒后再重新扫描)*****
	}*/
} 

//************************************************************
                               /*清暂存器*/
//************************************************************
void Clern_Number(void)
{
//	WATCHDOG=~WATCHDOG;
	Read_RF_Data[0]=0;
	Read_RF_Data[1]=0;             
	Read_RF_Data[2]=0;      
	Read_RF_Data[3]=0;             
	Read_RF_Data[4]=0;      
	Read_RF_Data[5]=0;             
	Read_RF_Data[6]=0;      
	Read_RF_Data[7]=0;             
	Read_RF_Data[8]=0;      
	Read_RF_Data[9]=0;             
	Read_RF_Data[10]=0;  
	ID_Data[0]=0;
	ID_Data[1]=0;
	ID_Data[2]=0;
	ID_Data[3]=0;
	ID_Data[4]=0;
	ID_Data[5]=0;
}





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -