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

📄 read_card.h

📁 ID卡读卡器源程序 用Mega32通过U2270B读取H4001RFID卡号的范例
💻 H
字号:
/******************************************************************************************************************
程序名:      射频卡门禁系统_读卡头
功能概述:
			 读射频卡头文件  适用于AVR 7.3728MHZ
			 
射频卡类型: 4001、EM4100和含E2PROM的RF卡。如E5550。
MCU类型:     ATmega16
晶振频率:    7.3728MHZ
版本:	     V0.1
修改:        于军峰
原作者:     章其波先生
编译日期:    2007-05-01
******************************************************************************************************************/
#ifndef _read_card_H
#define _read_card_H
#define DELAY_VALUE 425								//在7.3728MHZ下425----384us
#define TIME_OF     380								//超时退出
#define Manchester_IN  (PIND&(1<<PD2))   			//曼彻斯特码输入端
uchar rev_dat[5]={0,0,0,0,0};						//接收的5个字节数据
ulong lcd_dis_num=0;
//*****************************************************************************************************************
void delay_384us(void);								//适用机型    :用于AVR系列单片机延时处理,7.3728MHZ晶振下
void send_initial(void);
uchar read_card_number(void);						//尝试读十次卡,无卡则返回0,有卡则返回卡号
void delay_384us(void)								//适用机型    :用于AVR系列单片机延时处理,7.3728MHZ晶振下
{
	uint n=DELAY_VALUE;
	for(;n>0;n--)			
	{
		asm("nop");
		asm("nop");
	}											
}
uchar read_card_number(void)
{
	uchar i=0;										//起始为的计数值
	uchar error_flag=0; 							//时间溢出标志
	uchar row=0,col=0;	  							//行列寄存器
	uchar row_parity=0;  							//行校验寄存器
	uchar col_parity[5]; 							//列校验寄存器
	uchar card_data=0;								//数据寄存器
	uchar temp=0;									//卡号寄存器
	uchar seek_num=0;	 							//搜索次数寄存器
	uint error=0;  									//时间溢出的计数值
	uchar pp=0;
	uchar ii=0;
	while(1)
	{		
		if(seek_num>=10)							//尝试10次搜索,如没有则返回0
		{
			return 0;
		}
		else 
		{
			seek_num++;
			WDR();							//喂狗
		}
		error=0;
		ii=pp=0;
		while(Manchester_IN);						//等待高电平结束,主要是判断曼码结束位0
		while(Manchester_IN==0)						//等低电平,判断如果后面有连续9个1,表示可以接收数据
		{
			if(error==TIME_OF)
			{
				error=0;
				break;								//超时退出
			}
			else 
			{
				error++;
			}
		} 	
		delay_384us();					   			//延时384us  
		if(Manchester_IN)							//寻找真正的1起始位,利用01的波形确定1起始位,即最后一位加第一位
		{	 
			for(i=0;i<8;i++)						//判断是否是真的起始位
			{	  
				error=0;	   						//限定等待时间
				while(Manchester_IN)
				{	
					if(error>=TIME_OF)
					{	  
						error_flag=1;				//时间溢出
						break;						//退出
					}
					else 
					{
						error++;
					}
				}	 
				delay_384us();				  				 //延时384us
				if(Manchester_IN&&error_flag==0)			 //判断下一位是否为1 和是否没有时间溢出
				{
					;
				}
				else 
				{
					break;			 						//不是1退出,溢出退出		
				}	   
			}
			if(error_flag)									//因时间溢出造成的本次主循环退出
			{	  
				error_flag=0;
				ii=pp=0;
				continue;									//退出本次循环
			}
			if(i==8)  										//起始位接受完并且正确后开始接受数据
			{	
				error_flag=0;
				error=0;	 								//限定等待时间
				while(Manchester_IN)
				{  
					if(error>=TIME_OF)
					{	
						error_flag=0;
						break;								//时间溢出造成的出错
					}
					else error++;
				}	  
				if(error_flag)	   
				{
					error_flag=0;
					ii=pp=0;
					continue;	   							//因等待待第一个正式数据错误引起的本次主循环退出
				}
				col_parity[0]=col_parity[1]=col_parity[2]=col_parity[3]=col_parity[4]=0;		//所有列校验清零
				WDR();													//喂狗
				for(row=0;row<11;row++)															//共11行数据
				{
					for(col=0,row_parity=0;col<5;col++)											//共5列数据
					{
						delay_384us();  														//延时384us
						if(Manchester_IN)
						{
							card_data=1;  					//数据为1
						}
						else 
						{
							card_data=0;			   		//数据为0
						}
						if(col<4&&row<10)		   			//数据区的接受,后四个字节
						{
							temp<<=1;			 			//左移一位
							temp+=card_data;				//数据相加
							lcd_dis_num<<=1;
							lcd_dis_num+=card_data;
							ii++;
							if(ii>=8)
							{
								ii=0;
								rev_dat[pp++]=temp;
								temp=0;
							}
						}
						row_parity+=card_data;		 		//行校验加入数据
						col_parity[col]+=card_data;	 		//相应列校验加入数据  虽最后一列没有校验但为了方便也加上
						error=0;				 			//限定等待时间清零
						while(Manchester_IN==card_data)
						{
							if(error==TIME_OF)		  		//由于时间溢出造成的数据出错
							{	
								error_flag=1;
								break;			  			//退出本while循环
							}
							else error++;
						}
						if(error_flag)
						{
							break;	 						//出错退出内层for循环
						}
					}
					if(row<10)								//最后一行没有校验所以要加限制
					{
						if((row_parity&0x01)||error_flag) 	//出错退出外for循环
						{
							temp=0;
							error_flag=1; 
							break;			 				//退出
						}
					}
				}
				//对最后接收的列校验进行判断,及对来自上面数据错误error_flag处理以结束本次主循环
				if(error_flag||((col_parity[0]&0x01)&&(col_parity[1]&0x01)&&(col_parity[2]&0x01)&&(col_parity[3]&0x01)))   
				{											 //最后一列没有校验											 
					error_flag=0;
					temp=0;
					ii=pp=0;
					continue; 								//退出本次循环
				} 
				else 
				{
					ii=pp=0;
					return 0xaa;								//将正确的数据返回
				}
			}
			ii=pp=0;
			continue;
		}
		ii=pp=0;
		continue;
	}
	return 0;		
}
#endif
//**************************************************Program End****************************************************

⌨️ 快捷键说明

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