www.pudn.com > HS4095.rar > main.c


//2006-4-27 13:10 
//更改为默认 manchester,RF/64,软件可读写EM4469,不能更改设置读卡器参数,可读参数2006-4-27 12:01 
//不能使用默认读命令 
//支持PCB端软件:1.EM4469 RFID Development Kit Application Software  2.EM4469 Read Only Application Software 
//支持卡片:EM4469,EM410X 
 
#include "main.h" 
 
 
////EM4095控制线定义 
sbit	MOD = P1^1; 
sbit	SHD = P1^2; 
sbit	DEMOD_OUT = P3^3; 
sbit    RDY_CLK = P3^4; 
sbit    speak = P1^3; 
 
union	myunion 
{ 
	uint	word; 
	struct 
	{ 
		uchar high2; 
		uchar low2; 
	}bytes; 
}; 
 
 
union myunion count_timer2; 
uchar fwd_1st_pulse = 256 - 20;            	//20个RF周期 
uchar field_stop;                          	//next field stop in RF clocks 
uchar fwd_01_zero   = 256 - 20;            	//complement to fwd_01_stop,20个RF周期 
uchar fwd_01_one    = 256 - 29;           	//notmod full period '1',29个RF周期 
uchar fwd_01_stop   = 256 - 9;            	//9个RF周期 
uchar edge=1;                         		//for manchester usage 
 
 
// 定时器0中断服务程序 
// 写操作,控制MOD 
void Timer0_int(void) interrupt 1 using 1 
{	           
	TF0=0;						//clear interrupt flag 
    if (fwd_bit_phase == 1)  
    {                      
      	MOD=1;   
		TR0=0;                      
      	TH0=0xFF; 
      	TL0 = field_stop; 
		TR0=1; 
      	field_stop = fwd_01_stop;              
      	fwd_bit_phase = 2; 
      	return; 
    } 
     
    MOD=0;                    
	TR0=0; 
    if (fwd_bit_phase == 2)                  
    { 
    	TH0=0xFF; 
    	TL0=fwd_01_zero; 
    } 
    else 
    { 
    	TH0=0xFF; 
    	TL0= fwd_01_one; 
    }                     
	TR0=1; 
 
    if(fwd_bit_sz-- > 0)  
    {                    
      	if(((*fwd_write_ptr++) & 1) == 1)  
        	fwd_bit_phase = 3; 
      	else 
        	fwd_bit_phase = 1; 
    } 
    else  
    { 
      	TR0= 0;                             
      	ET0=0;      		//disable T0 interrupt               
      	TF0=0;                      
    } 
} 
//串口中断标志位 
uchar Rxtemp; 
bit rx_start; 
bit rx_finish; 
bit rx_lenflag; 
uchar rx_i; 
uchar rx_len; 
bit MYTI; 
 
//串口中断服务程序 
void serial(void) interrupt 4 using 3  
{	 
    if(RI) 
    { 
        RI = 0; 
        Rxtemp = SBUF;    
        if(rx_start == 0) 
        { 
	        if(Rxtemp == STX) 
	        { 
//	        	clearrx_buff();   //清接收缓冲 
	        	rx_start = 1; 
	        	rx_finish = 0; 
	        	rx_lenflag = 0; 
	        	rx_i = 0;   //接收到的个数 
	        	rx_len = 0; 
	        	rx_buff[0] = Rxtemp; 
	        	rx_i++;     //长度+1 
	        } 
	        return; 
        } 
        if(rx_lenflag == 0) 
        { 
        	rx_lenflag = 1; 
        	rx_buff[1] = Rxtemp; 
	        rx_i++; 
	        rx_len = Rxtemp; 
	        if(rx_len > MAX_RXNUM) 
	        { 
	        	rx_start = 0; 
	        	rx_finish = 0; 
	        	rx_lenflag = 0; 
	        }	         
	        return; 
        } 
        rx_buff[rx_i] = Rxtemp; 
	    rx_i++; 
	    rx_len--; 
	    if(rx_len ==0) 
	    { 
	    	rx_start = 0; 
	        rx_finish = 1; 
	        rx_lenflag = 0; 
	        if(rx_buff[rx_i-1] != ETX) 
	        {	        	 
	        	rx_finish = 0;	        	 
	        }	         
	    }        
		return; 
	} 
	if(TI) 
	{ 
		TI = 0; 
		MYTI = 1;		 
 	} 
} 
 
// ================================================================== 
void Timer2_int(void) interrupt 5 using 2 
{ 
  	if (currentMaxTimeHi != 0xFF)  
  	{                  
    	currentMaxTimeHi = 0xFF; 
	}  
	else  
	{ 
    	flag_wait=0; 
    	ET2=0;   
  	} 
} 
 
void main(void) 
{ 
	uchar i; 
	uchar checksum; 
	//使能winbond W78E365内部1K SRAM 
	CHPENR = 0x87; 
    CHPENR = 0x59; 
    CHPCON = (CHPCON|0x10); 
 	CHPENR = 0x00; 
 
	//串口,定时器1,双倍速率,38400bps 
	SCON = 0x50;		 
	TMOD = 0x20; 
	//TH1 = 0xf3;TL1 = 0xf3; 
	TH1 = 0xfd;TL1 = 0xfd;		// 38400/22.1184M 
	PCON = PCON|0x80; 
	TR1 = 1; 
	ES = 1; 
	TI = 0;RI = 0;		 
	EA = 1; 
	C_T2 = 1;				//T2脚的负跳变计数,TH2,TL2自动重装 
	//EM4095 初始化 
	MOD = 0; 
	SHD = 0; 
	//串口接收初始化 
	rx_start = 0; 
    rx_finish = 0; 
	rx_lenflag = 0; 
    rx_len = 0;				//还要接收的数据个数 
	rx_i = 0;               //接收到个数 
	MYTI = 0; 
	 
	//配置读卡器默认值,RF/64,Manchester解码 
    config_delayed = 0; 
    config_lwr = 8;                       
    config_raw = 0;	 
 
	halfDataRate = 32;//default values, RF/64 
	MaxCaptureHalfDateRate = halfDataRate + (halfDataRate >> 1);		//=48  
	MaxCaptureDateRate = halfDataRate + halfDataRate + (halfDataRate >> 1);	//=80 
	lwr = config_lwr; 
	delayed = config_delayed; 
	raw = config_raw; 
	//forward_link_type = 0x01;  
	maxTLogin = 4 + (4 + 9) * 2 * (uint)halfDataRate;		//0x0344 
	maxTWrite = 1144 + (4 + 8) * 2 * (uint)halfDataRate; 
	maxTWriteRaw = 1144 + (4 + 5 + 54) * 2 * (uint)halfDataRate; 
	maxTRead = (100) + 4 + (5 + 54) * 2 * (uint)halfDataRate;		//3880 
	maxTDisable = maxTLogin; 
	maxTDefaultRead = 2*((lwr-4)*4*8)*2*((uint32)halfDataRate); 
	tpp_period = 4 + 2 * (uint)halfDataRate - 4;		//64 
	twr_period = (68 + 64 + 896 + 116) + 2 * (uint)halfDataRate - 4; 
	 
	while(1) 
	{ 
		if(rx_finish == 1)//串口完成合法的接收 
	    {	    	 
		  	rx_finish = 0; 
		    checksum = rx_buff[1]; 
			for(i=2;i<=(rx_buff[1]-1);i++) 
			{ 
				checksum ^= rx_buff[i]; 
			} 
			if (checksum != rx_buff[rx_buff[1]])	//检查校验和	 
				continue; 
	    } 
	    else continue; 
				 
		forward_ptr = forwardLink_data;	 
		 
		switch(rx_buff[2]) 			 
		{ 
			case 0x80 : 
				ReadWordToPC();		//读卡 
				break; 
			case 0x81 : 
				WriteWordtoCard();		//写卡 
				break; 
			case 0x82 : 
				Login();			// 
				break; 
			case 0x83 : 
				Disable(); 
				break; 
			case 0x84 :  
				PCLinkReader();		//PC要求与读卡器连接 
				break; 
			case 0x85 :  
				//DefaultRead();		// 
				break; 
			case 0x86 :  
				Readonly_autodetection();		//只读,自动检测,可读4100,配置4469,读4469 
				break;			 
			case 0xFB : 
				GetReaderConfiguration();		//读取读卡器的配置参数 
				break; 
			case 0xFC : 
				SetReaderConfiguration();		//设置读卡器的配置参数 
				break; 
			case 0xFD : 
				ReadStatusToPC();				//读卡 
				break; 
			case 0xFE :  
				FieldSwitch(); 
				break;		 
			case 0xF0: 
				FieldReset(); 
				break; 
			case 0x10: 
				Read4100ID(); 
				break;				  
			default :  
				break; 
		} 
	} 
} 
 
//读卡数据,区地址=rx_buff[3],发送到PC,本版本支持的PC演示软件可以看到相应的数据 
void ReadWordToPC(void) 
{ 
	uchar fwd_bit_count;	 
	fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); 
	fwd_bit_count += Prepare_Addr(rx_buff[3]); 
	SendForward(fwd_bit_count);		 
	Wait(tpp_period);		   
	maxCaptureTimeLow = maxTRead; 		//=3880 
	maxCaptureTimeHi = 0;		   
	ManchesterRead();			 
	tx_buff[0]=0x02;		//帧头 
	tx_buff[1]=0x09;		//帧信息长度,从tx_buff[2]开始计算,到tx_buff[10]=0x03结束 
	tx_buff[2]=0x80;		//命令字 
	tx_buff[3]=check_stat; 
	tx_buff[4]=rx_buff[3];		//地址 
	tx_buff[5]=capture_data[0];	//数据 
	tx_buff[6]=capture_data[1];	//数据 
	tx_buff[7]=capture_data[2];	//数据 
	tx_buff[8]=capture_data[3];	//数据 
	tx_buff[9]=(tx_buff[1]^tx_buff[2]^tx_buff[3]^tx_buff[4]^tx_buff[5]^tx_buff[6]^tx_buff[7]^tx_buff[8]); 
	//tx_buff[9]是校验和 
	tx_buff[10]=0x03;		//帧结束标志 
	trace(tx_buff,11);		//发送到PC 11个字节 
} 
 
//写PC传过来的数据到ID卡上 
void WriteWordtoCard(void) 
{ 
	uchar fwd_bit_count; 
 
	fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); 
  	fwd_bit_count += Prepare_Addr(rx_buff[3]); 
  	fwd_bit_count += Prepare_Data(( ((uint)rx_buff[5] << 8) + rx_buff[4]), ( ((uint)rx_buff[7] << 8) + rx_buff[6])); 
	if (rx_buff[3] == 0x04) 
	{			//32位配置字 
		 
		halfDataRate = 32;// datarate = RF/64 
		MaxCaptureHalfDateRate = halfDataRate + (halfDataRate >> 1);    //=48 
		MaxCaptureDateRate = halfDataRate + halfDataRate + (halfDataRate >> 1);		//=80 
		lwr = config_lwr; 
		delayed = config_delayed; 
		raw = config_raw; 
		//forward_link_type = 0x01;  
		maxTLogin = 4 + (4 + 9) * 2 * (uint)halfDataRate; 
		maxTWrite = 1144 + (4 + 8) * 2 * (uint)halfDataRate; 
		maxTWriteRaw = 1144 + (4 + 5 + 54) * 2 * (uint)halfDataRate; 
		maxTRead = (100) + 4 + (5 + 54) * 2 * (uint)halfDataRate; 
		maxTDisable = maxTLogin; 
		maxTDefaultRead = 2*((lwr-4)*4*8)*2*((uint32)halfDataRate); 
		tpp_period = 4 + 2 * (uint)halfDataRate - 4; 
		twr_period = (68 + 64 + 896 + 116) + 2 * (uint)halfDataRate - 4; 
	} 
 
	SendForward(fwd_bit_count);	 
	Wait(twr_period); 
	maxCaptureTimeHi = 0; 
	maxCaptureTimeLow = maxTWrite; 
	 
	ManchesterWrite(); 
 
	tx_buff[0]=0x02; 
	tx_buff[1]=0x04; 
	tx_buff[2]=0x81; 
	tx_buff[3]=check_stat; 
	tx_buff[4]=(tx_buff[1]^tx_buff[2]^tx_buff[3]); 
	tx_buff[5]=0x03; 
	trace(tx_buff,6); 
} 
 
//控制天线命令 
void FieldSwitch(void) 
{ 
	if (rx_buff[3] & 1 ) 
	{ 
		SHD=0;			//打开天线 
	} 
	else  
	{ 
		SHD=1;			// 关闭天线 
	} 
	tx_buff[0]=0x02;		//帧头 
	tx_buff[1]=0x04;		//长度 
	tx_buff[2]=0xfe;		//命令 
	tx_buff[3]=0; 
	tx_buff[4]=(tx_buff[1]^tx_buff[2]^tx_buff[3]);		//检验和 
	tx_buff[5]=0x03;		//帧结束 
	trace(tx_buff,6); 
} 
 
//不可用,匹配PC演示程序,直接返回 设置成功 
void SetReaderConfiguration(void) 
{ 
	tx_buff[0]=0x02; 
	tx_buff[1]=0x04; 
	tx_buff[2]=0xfc; 
	tx_buff[3]=0; 
	tx_buff[4]=(tx_buff[1]^tx_buff[2]^tx_buff[3]); 
	tx_buff[5]=0x03; 
	trace(tx_buff,6); 
} 
 
//读取DEMO读卡器的配置参数 
void GetReaderConfiguration(void) 
{ 
	uchar q;	 
	q = 1;  	                          
	get_settings_low = (q<<6) | (halfDataRate - 1); 
	q = (q >> 2) | (delayed << 4) | ((lwr & 3) << 6); 
	get_settings_low |= (uint)q << 8; 
	get_settings_hi = ((raw << 6) | (lwr >> 2));// | (forward_link_type >> 1); 
 
	tx_buff[0]=0x02; 
	tx_buff[1]=0x08; 
	tx_buff[2]=0xfb; 
	tx_buff[3]=0; 
	tx_buff[4]=(uchar)get_settings_low; 
	tx_buff[5]=get_settings_low>>8; 
	tx_buff[6]=(uchar)get_settings_hi; 
	tx_buff[7]=get_settings_hi>>8; 
	tx_buff[8]=(tx_buff[1]^tx_buff[2]^tx_buff[3]^tx_buff[4]^tx_buff[5]^tx_buff[6]^tx_buff[7]); 
	tx_buff[9]=0x03; 
	trace(tx_buff,10); 
} 
 
void Disable(void) 
{ 
	uchar fwd_bit_count; 
    fwd_bit_count = Prepare_Cmd( FWD_CMD_DISABLE ); 
    fwd_bit_count += Prepare_Data( 0xFFFF, 0xFFFF ); 
    SendForward(fwd_bit_count);	    
    Wait(tpp_period);	    
    maxCaptureTimeLow = maxTDisable;  
    maxCaptureTimeHi = 0; 
 
	ManchesterRead(); 
 
	tx_buff[0]=0x02; 
	tx_buff[1]=0x04; 
	tx_buff[2]=0x83; 
	tx_buff[3]=check_stat; 
	tx_buff[4]=(tx_buff[1]^tx_buff[2]^tx_buff[3]); 
	tx_buff[5]=0x03; 
	trace(tx_buff,6); 
} 
 
void Login(void) 
{ 
	uchar fwd_bit_count; 
	fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); 
	fwd_bit_count += Prepare_Data(( ((uint)rx_buff[4] << 8) + rx_buff[3]), ( ((uint)rx_buff[6] << 8) + rx_buff[5])); 
	SendForward(fwd_bit_count); 
	Wait(tpp_period); 
	maxCaptureTimeLow = maxTLogin;  
    maxCaptureTimeHi = 0; 
	ManchesterWrite(); 
	tx_buff[0]=0x02; 
	tx_buff[1]=0x04; 
	tx_buff[2]=0x82; 
	tx_buff[3]=check_stat; 
	tx_buff[4]=(tx_buff[1]^tx_buff[2]^tx_buff[3]); 
	tx_buff[5]=0x03; 
	trace(tx_buff,6); 
} 
 
   
void PCLinkReader(void) 
{ 
	tx_buff[3]=UART_MESSAGE_OK; 
	tx_buff[0]=0x02; 
	tx_buff[1]=0x04; 
	tx_buff[2]=0x84; 
	tx_buff[4]=(tx_buff[1]^tx_buff[2]^tx_buff[3]); 
	tx_buff[5]=0x03; 
	trace(tx_buff,6); 
	speak_on(); 
} 
 
void Readonly_autodetection(void) 
{ 
	uchar i,j,k,l; 
	 
	uchar idata autodection_data[32]; 
	uchar array_subscript;	//小标 
	uchar bit_subscript;		 
	uint capt; 
  	uint icr;  
	bit flag_RO_last_capt_half=0;		 
	uchar count_autodection_bit=0; 
	bit flag_header_found=0;		 
	bit flag_stop_found=0;		 
	bit flag_line_check=0;		 
	bit flag_column_check=0;		 
	uchar check=0;		 
	uchar custID=0; 
	uchar idata DataItem[4]={0,0,0,0}; 
	uchar bit_number; 
	bit flag_tag_datarate_bigger;		 
	bit flag_invalid_edge_manchester;	 
	uchar times_capture_manchester;	 
    
	//halfDataRate = 32;//config_data_rate+1; 
	MaxCaptureHalfDateRate = 48;//halfDataRate+(halfDataRate>>1); 
	MaxCaptureDateRate = 80;//halfDataRate+halfDataRate+(halfDataRate>>1); 
	//lwr = 7;//config_lwr; 
	//maxTDefaultRead = 0x3000;//2*((lwr-4)*4*8)*2*((uint32)halfDataRate); 
	maxCaptureTimeLow = 0x3000;//(uint)maxTDefaultRead;  
  	maxCaptureTimeHi = 0x30;//(uchar)(maxTDefaultRead >> 16); 
	last_capture = 0xcfff;//~maxCaptureTimeLow;  
	TF2 = 0; 
	TR2 = 0; 	 	       
	TL2 = 0xff;//(uchar)(~maxCaptureTimeLow);  
	TH2= 0xcf;//(uchar)((~maxCaptureTimeLow)>>8) ;           
	currentMaxTimeHi = 0xcf;//~maxCaptureTimeHi;		  
	flag_tag_datarate_bigger=0; 
	 
	for(j=0;j<32;j++)		 
	{ 
		autodection_data[j]=0; 
	} 
	for(i=0;i<0xf8;i++) 
	{ 
		if(DEMOD_OUT == 0)		//等待低电平,超时退出 
			break; 
	} 
	if(i>=0xf0) 
	{ 
		return_00(); 
		return; 
	} 
	for(i=0;i<0xf8;i++) 
	{ 
		if(DEMOD_OUT == 1)		//等待高电平,超时退出 
			break; 
	} 
	if(i>=0xf0) 
	{ 
		return_00(); 
		return; 
	} 
	ET2=1; 
	TR2=1;					//counter 2 start run,interrupt enable 
	flag_wait=1; 
	 
	while(flag_wait)		//counter 2 is runing  
	{ 
		for(i=0;i<0xf8;i++) 
		{ 
			if(DEMOD_OUT == 0)		//等待低电平,超时退出 
				break; 
		} 
		if(i>=0xf0) 
		{ 
			return_00(); 
			return; 
		} 
	 
		 
		icr=count_module();  
		capt=icr-last_capture; 
		last_capture=icr; 
		if ((capt>MaxCaptureHalfDateRate)&&(capt=0xf0) 
		{ 
			return_00(); 
			return; 
		} 
		 
		icr=count_module();  
		capt=icr-last_capture; 
		last_capture=icr;				 
	} 
		 
	flag_RO_last_capt_half=0; 
	flag_invalid_edge_manchester=0; 
	count_autodection_bit=0; 
	array_subscript=0; 
	bit_subscript=0; 
		 
//	//manchester 
	times_capture_manchester=0; 
	while(flag_wait)				//counter 2 is runing  
	{ 
		for(i=0;i<0xf8;i++) 
		{ 
			if(DEMOD_OUT == 1)		//,test low time 等待高电平,超时退出 
				break; 
		} 
		 
		if(i>=0xf0) 
		{ 
			return_00(); 
			return; 
		} 
		 
		icr=count_module();  
		capt=icr-last_capture; 
		last_capture=icr; 
		if((capt>3); 
				bit_subscript=(count_autodection_bit%8); 
				autodection_data[array_subscript]=(autodection_data[array_subscript]|(1<MaxCaptureHalfDateRate)&&(capt>3); 
				bit_subscript=(count_autodection_bit%8); 
				autodection_data[array_subscript]=(autodection_data[array_subscript]|(1<=0xf0) 
		{ 
			return_00(); 
			return; 
		} 
		 
		icr=count_module();  
		capt=icr-last_capture; 
		last_capture=icr;	 
		if((capt>3); 
				bit_subscript=(count_autodection_bit%8); 
				autodection_data[array_subscript]=(autodection_data[array_subscript]|(1<MaxCaptureHalfDateRate)&&(capt>3); 
				bit_subscript=(count_autodection_bit%8); 
				autodection_data[array_subscript]=(autodection_data[array_subscript]|(1<64) 
	{ 
		flag_header_found=0; 
		for (j=0;j<(count_autodection_bit-54);j++)		//找标志头9 bit 1 
		{ 
			array_subscript=(j>>3); 
			bit_subscript=(j%8); 
			if ((autodection_data[array_subscript]&(1<>3); 
					bit_subscript=(k%8); 
					if ((autodection_data[array_subscript]&(1<>3); 
			bit_subscript=((j+64)%8); 
			if ((autodection_data[array_subscript]&(1<>3); 
					bit_subscript=(l%8); 
					check=check^((autodection_data[array_subscript]>>bit_subscript)&1); 
				} 
				array_subscript=(l>>3); 
				bit_subscript=(l%8); 
				if ((autodection_data[array_subscript]&(1<>3); 
					bit_subscript=(l%8); 
					check=check^((autodection_data[array_subscript]>>bit_subscript)&1);							 
				} 
				array_subscript=(l>>3); 
				bit_subscript=(l%8); 
				if ((autodection_data[array_subscript]&(1<>3); 
				bit_subscript=(k%8); 
				custID=(custID|(((autodection_data[array_subscript]&(1<>bit_subscript)<>bit_subscript)<>3); 
					bit_subscript=(l%8); 
					DataItem[k]=(DataItem[k]|(((autodection_data[array_subscript]&(1<>bit_subscript)<>= 1; 
  	*forward_ptr++ = cmd; 
  	line_parity ^= cmd; 
 	 cmd >>= 1; 
  	*forward_ptr++ = cmd; 
  	line_parity ^= cmd; 
  	*forward_ptr++ = (line_parity & 1);  	 
    return 6;                         	 
} 
 
 
uchar Prepare_Addr( uchar addr )  
{ 
  	register uchar line_parity; 
  	*forward_ptr++ = addr; 
  	line_parity = addr; 
  	addr >>= 1;   
  	*forward_ptr++ = addr; 
  	line_parity ^= addr; 
  	addr >>= 1;   
  	*forward_ptr++ = addr; 
  	line_parity ^= addr; 
  	addr >>= 1;   
  	*forward_ptr++ = addr; 
  	line_parity ^= addr; 
  	*forward_ptr++ = 0; 
  	*forward_ptr++ = 0; 
  	*forward_ptr++ = (line_parity & 1); 
  	return 7;                      //return number of emited bits 
} 
 
 
 
uchar Prepare_Data( uint data_low, uint data_hi)  
{ 
  	register uchar line_parity; 
  	register uchar column_parity; 
  	register uchar i, j; 
  	register uint datas; 
 
  	datas = data_low; 
  	column_parity = 0; 
 
  	for(i=0; i<4; i++)  
  	{ 
    	line_parity = 0; 
    	for(j=0; j<8; j++)  
    	{ 
      		line_parity ^= datas; 
      		column_parity ^= (datas&1) << j; 
      		*forward_ptr++ = datas; 
      		datas >>= 1; 
    	} 
    	*forward_ptr++ = line_parity; 
    	if(i == 1) 
      		datas = data_hi; 
  	} 
 
  	for(j=0; j<8; j++)  
  	{ 
    	*forward_ptr++ = column_parity; 
    	column_parity >>= 1; 
  	} 
  	*forward_ptr = 0; 
 
  	return 45;                             //return number of emited bits 
} 
 
// Forward Link setup function 
// Requires: forwarLink_data filled with valid bits (1 bit per byte) 
//           fwd_bit_count set with number of bits to be sent 
void SendForward(uchar fwd_bit_count)  
{ 
	uchar sync=1; 
  	fwd_write_ptr = forwardLink_data; 
  	fwd_bit_sz = fwd_bit_count; 
  	fwd_bit_phase = 3; 
  	field_stop = fwd_1st_pulse;		//fwd_1st_pulse = 256-20 
 
	TR0=0; 
  	TH0=0xff;TL0=1;          //minimum startup pulse length,255 
  	MOD=0;                    
  	TF0=0;                    
  	ET0=0;          		//disable T0 interrupt          
  	TMOD=(TMOD|0x05);			//计数器,16位计数器 
  	TR0=1;      
 
  // waiting for clearing T0IE0 => command sending 
  	while (!TF0)  
  	{ 
    	if ((sync == 1) && (!DEMOD_OUT))   
    		sync = 0; 
    	if ((sync == 0) && (DEMOD_OUT))   
    		break; 
  	} 
  	MOD=1;               	//force 1st mod pulse 
  	fwd_bit_sz--;         	//prepare next bit modulation 
  	fwd_write_ptr++; 
  	TF0=0;                 	//clear any pending flag 
  	TR0=0; 
  	TH0=0xFF;TL0= field_stop; 
  	TR0=1; 
  	field_stop = fwd_01_stop;            
  	fwd_bit_phase = 2; 
  	ET0=1;                 //enable overflow interrupt 
 
  // waiting for clearing T0IE0 => command sending 
  	while ( ET0== 1 ) ; 
} 
 
 
void Wait(uint period)  
{ 
  	TR2 = 0;                              
   	TF2=0;       
  	TL2=(uchar)(~period);  TH2=(uchar)((~period)>>8);                       
  	currentMaxTimeHi = 0xFF; 
   	ET2=1; 
  	TR2=1;                     
  	flag_wait=1; 
  	while ( flag_wait);    
} 
 
//读卡程序, Manchester解码 
void ManchesterRead(void) 
{ 
	uchar i,j; 
	uchar	captured_bits_count; 
	ClearCaptureBuffers(); 
	captured_bit_count = 0; 
	capture_cnt = 0; 
	captured_byte=0; 
	capture_check=0; 
	capture_check_count=0; 
	buffer_capture_check=0; 
	compute_capture_check=0; 
	check_stat=0; 
 
	for(i=0;i<120;i++)	//2006-5-13 14:19 
	{ 
		capture_time[i]=0xff; 
	}	 
	 
	TR2 = 0;  
	TF2 = 0;       
	TL2 = (uchar)(~maxCaptureTimeLow); 		//0xd7 
	TH2 = (uchar)((~maxCaptureTimeLow)>>8);	//0xf0,	//set timer with initial time 
	currentMaxTimeHi = ~maxCaptureTimeHi;	//0xff 
 
	last_capture = ~maxCaptureTimeLow; 		//~0x0f28 
	capture_read_time_data_ptr = capture_time;		// capture ptr 
 
	flag_wait=1; 
	ET2=1; 				//enable t2 interrupt 
 
	check_stat=ERR_EM4469_NEITHER_ACK;		//if read card ok,check_stat will change 
	for(i=0;i<0xf0;i++) 
	{ 
		if(DEMOD_OUT == 0)		//等待低电平,超时退出 
			break; 
	} 
	if(i>=0xf0) 
	{ 
		for(i=0;i<120;i++) 
		{ 
			capture_time[i]=0xff; 
		} 
		return; 
	} 
	 
	for(i=0;i<0xf0;i++) 
	{ 
		if(DEMOD_OUT == 1)		//等待高电平,超时退出 
			break; 
	} 
	if(i>=0xf0) 
	{ 
		for(i=0;i<120;i++) 
		{ 
			capture_time[i]=0xff; 
		} 
		return; 
	} 
	 
	TR2=1;  //                    
	while ( flag_wait )             //接收 
	{ 
		for(i=0;i<0xf0;i++) 
		{ 
			if(DEMOD_OUT == 0) 
				break; 
		} 
		if(i>=0xf0) 
			return; 
		capture();					//hi电平时间 
		 
		for(i=0;i<0xf0;i++) 
		{ 
			if(DEMOD_OUT == 1) 
				break; 
		} 
		if(i>=0xf0) 
			return; 
		capture();					//low电平时间 
	} 
 
	check_stat=ERR_EM4469_NEITHER_ACK; 
	for (j=0;j<5;j++) 
	{ 
		if (((j%2)==0)&&(capture_time[j]MaxCaptureHalfDateRate)\ 
		&&(capture_time[j+3]>MaxCaptureHalfDateRate)&&(capture_time[j+4]>MaxCaptureHalfDateRate)\ 
		&&(capture_time[j+5]>MaxCaptureHalfDateRate)) 
		{ 
			check_stat = UART_MESSAGE_OK; 
			break; 
		} 
		if (((j%2)==0)&&(capture_time[j]MaxCaptureHalfDateRate)) 
		{ 
			check_stat = ERR_EM4469_NACK; 
			break;		 
		} 
	}	 
 
	captured_bits_count=0; 
	if (check_stat==UART_MESSAGE_OK) 
	{ 
		//解码 
		for (i=(j+6);;i++) 
		{ 
			if (capture_time[i]45) //45位数据结构,参考EM4469文档 
					break; 
			} 
			else if((capture_time[i]>MaxCaptureHalfDateRate) &&(capture_time[i]45) //45位数据结构,参考EM4469文档 
					break; 
			} 
			else   
			{ 
				check_stat=ERR_EM4469_FLOWLINK_ERR; 
				break; 
			} 
		} 
	} 
 
	if ((check_stat!=ERR_EM4469_NEITHER_ACK)&&(check_stat!=ERR_EM4469_NACK)&&(check_stat!=ERR_EM4469_FLOWLINK_ERR)) 
	{ 
		if (((capture_check&0x10)!=0)||((compute_capture_check&0x0f)!=(capture_check&0x0f))) 
		{ 
			check_stat=ERR_EM4469_PARITY_ERR; 
		} 
		else 
		{			//capture_data[4] CRC 
			if ((capture_data[0]^capture_data[1]^capture_data[2]^capture_data[3])!=capture_data[4]) 
			{ 
				check_stat=ERR_EM4469_PARITY_ERR; 
			} 
			else 
			{ 
				check_stat=UART_MESSAGE_OK; //读卡成功 
			} 
		} 
	} 
	//trace(capture_time,120); 
	//trace(capture_data,32); 
	for(i=0;i<120;i++) 
	{ 
		capture_time[i]=0xff; 
	} 
} 
 
//写卡程序,Manchester解码 
void ManchesterWrite(void) 
{ 
	uchar i,j; 
	ClearCaptureBuffers(); 
	captured_bit_count = 0; 
	capture_cnt = 0; 
	captured_byte=0; 
	capture_check=0; 
	capture_check_count=0; 
	buffer_capture_check=0; 
	compute_capture_check=0; 
	check_stat=0; 
	TR2 = 0;  
	TF2=0;      //clear pending interrupts 
	TL2=(uchar)(~maxCaptureTimeLow); TH2=(uchar)((~maxCaptureTimeLow)>>8) ;             //set timer with initial time 
	currentMaxTimeHi = ~maxCaptureTimeHi; 
	last_capture=~maxCaptureTimeLow;  
	capture_read_time_data_ptr=capture_time; 
	flag_wait=1;ET2=1; 
 
	for(i=0;i<0xf0;i++) 
	{ 
		if(DEMOD_OUT == 0)		//等待低电平,超时退出 
			break; 
	} 
	if(i>=0xf0) 
	{ 
		for(i=0;i<120;i++) 
		{ 
			capture_time[i]=0xff; 
		} 
		return; 
	} 
 
	for(i=0;i<0xf0;i++) 
	{ 
		if(DEMOD_OUT == 1)		//等待高电平,超时退出 
			break; 
	} 
	if(i>=0xf0) 
	{ 
		for(i=0;i<120;i++) 
		{ 
			capture_time[i]=0xff; 
		} 
		return; 
	} 
 
	TR2=1;                      
	while ( flag_wait )          
	{ 
		for(i=0;i<0xf0;i++) 
		{ 
			if(DEMOD_OUT == 0)		//等待低电平,超时退出 
				break; 
		} 
		if(i>=0xf0) 
		{ 
			for(i=0;i<120;i++) 
			{ 
				capture_time[i]=0xff; 
			} 
			return; 
		} 
 
		capture(); 
 
		for(i=0;i<0xf0;i++) 
		{ 
			if(DEMOD_OUT == 1)		//等待高电平,超时退出 
				break; 
		} 
		if(i>=0xf0) 
		{ 
			for(i=0;i<120;i++) 
			{ 
				capture_time[i]=0xff; 
			} 
			return; 
		} 
 
		capture(); 
	} 
 
 
	check_stat=ERR_EM4469_NEITHER_ACK; 
	for (j=0;j<5;j++) 
	{ 
		if (((j%2)==0)&&(capture_time[j]MaxCaptureHalfDateRate)) 
		{ 
			check_stat = ERR_EM4469_NACK; 
			break;		 
		} 
	}	 
	if (check_stat != ERR_EM4469_NACK) 
	{ 
		for (j=0;j<76;j++) 
		{ 
			if (((j%2)!=0)&&(capture_time[j]MaxCaptureHalfDateRate)&&(capture_time[j+2]>MaxCaptureHalfDateRate)\ 
		&&(capture_time[j+3]>MaxCaptureHalfDateRate)&&(capture_time[j+4]>MaxCaptureHalfDateRate)) 
			{ 
				check_stat = UART_MESSAGE_OK; 
				break; 
			} 
		} 
	} 
 
	for(i=0;i<120;i++) 
	{ 
		capture_time[i]=0xff; 
	} 
} 
 
 
 
void ClearCaptureBuffers(void)  
{ 
  	uchar i; 
  	for(i=0; i> 3) | (READER_YEAR << 1); 
	tx_buff[7]=0x5a;//READER_FAMILY;		 
	tx_buff[8]=0x91;//(tx_buff[1]^tx_buff[2]^tx_buff[3]^tx_buff[4]^tx_buff[5]^tx_buff[6]^tx_buff[7]); 
	tx_buff[9]=0x03; 
	trace(tx_buff,10); 
} 
 
 
//从串口发送数据出去 
void trace(uchar *str,uchar len) 
{ 
	uint i; 
	MYTI = 0; 
	for(i=0;i>1); 
	MaxCaptureDateRate = 80;//halfDataRate+halfDataRate+(halfDataRate>>1); 
	//lwr = 7;//config_lwr; 
	//maxTDefaultRead = 0x3000;//2*((lwr-4)*4*8)*2*((uint32)halfDataRate); 
	maxCaptureTimeLow = 0x3000;//(uint)maxTDefaultRead;  
  	maxCaptureTimeHi = 0x30;//(uchar)(maxTDefaultRead >> 16); 
	last_capture = 0xcfff;//~maxCaptureTimeLow;  
	TF2 = 0; 
	TR2 = 0; 	 	       
	TL2 = 0xff;//(uchar)(~maxCaptureTimeLow);  
	TH2= 0xcf;//(uchar)((~maxCaptureTimeLow)>>8) ;           
	currentMaxTimeHi = 0xcf;//~maxCaptureTimeHi;		  
	flag_tag_datarate_bigger=0; 
	 
	for(j=0;j<32;j++)		 
	{ 
		autodection_data[j]=0; 
	} 
	for(i=0;i<0xf8;i++) 
	{ 
		if(DEMOD_OUT == 0)		//等待低电平,超时退出 
			break; 
	} 
	if(i>=0xf0) 
	{ 
		return_00(); 
		return; 
	} 
	for(i=0;i<0xf8;i++) 
	{ 
		if(DEMOD_OUT == 1)		//等待高电平,超时退出 
			break; 
	} 
	if(i>=0xf0) 
	{ 
		return_00(); 
		return; 
	} 
	ET2=1; 
	TR2=1;					//counter 2 start run,interrupt enable 
	flag_wait=1; 
	 
	while(flag_wait)		//counter 2 is runing  
	{ 
		for(i=0;i<0xf8;i++) 
		{ 
			if(DEMOD_OUT == 0)		//等待低电平,超时退出 
				break; 
		} 
		if(i>=0xf0) 
		{ 
			return_00(); 
			return; 
		} 
	 
		 
		icr=count_module();  
		capt=icr-last_capture; 
		last_capture=icr; 
		if ((capt>MaxCaptureHalfDateRate)&&(capt=0xf0) 
		{ 
			return_00(); 
			return; 
		} 
		 
		icr=count_module();  
		capt=icr-last_capture; 
		last_capture=icr;				 
	} 
		 
	flag_RO_last_capt_half=0; 
	flag_invalid_edge_manchester=0; 
	count_autodection_bit=0; 
	array_subscript=0; 
	bit_subscript=0; 
		 
//	//manchester 
	times_capture_manchester=0; 
	while(flag_wait)				//counter 2 is runing  
	{ 
		for(i=0;i<0xf8;i++) 
		{ 
			if(DEMOD_OUT == 1)		//,test low time 等待高电平,超时退出 
				break; 
		} 
		 
		if(i>=0xf0) 
		{ 
			return_00(); 
			return; 
		} 
		 
		icr=count_module();  
		capt=icr-last_capture; 
		last_capture=icr; 
		if((capt>3); 
				bit_subscript=(count_autodection_bit%8); 
				autodection_data[array_subscript]=(autodection_data[array_subscript]|(1<MaxCaptureHalfDateRate)&&(capt>3); 
				bit_subscript=(count_autodection_bit%8); 
				autodection_data[array_subscript]=(autodection_data[array_subscript]|(1<=0xf0) 
		{ 
			return_00(); 
			return; 
		} 
		 
		icr=count_module();  
		capt=icr-last_capture; 
		last_capture=icr;	 
		if((capt>3); 
				bit_subscript=(count_autodection_bit%8); 
				autodection_data[array_subscript]=(autodection_data[array_subscript]|(1<MaxCaptureHalfDateRate)&&(capt>3); 
				bit_subscript=(count_autodection_bit%8); 
				autodection_data[array_subscript]=(autodection_data[array_subscript]|(1<64) 
	{ 
		flag_header_found=0; 
		for (j=0;j<(count_autodection_bit-54);j++)		//找标志头9 bit 1 
		{ 
			array_subscript=(j>>3); 
			bit_subscript=(j%8); 
			if ((autodection_data[array_subscript]&(1<>3); 
					bit_subscript=(k%8); 
					if ((autodection_data[array_subscript]&(1<>3); 
			bit_subscript=((j+64)%8); 
			if ((autodection_data[array_subscript]&(1<>3); 
					bit_subscript=(l%8); 
					check=check^((autodection_data[array_subscript]>>bit_subscript)&1); 
				} 
				array_subscript=(l>>3); 
				bit_subscript=(l%8); 
				if ((autodection_data[array_subscript]&(1<>3); 
					bit_subscript=(l%8); 
					check=check^((autodection_data[array_subscript]>>bit_subscript)&1);							 
				} 
				array_subscript=(l>>3); 
				bit_subscript=(l%8); 
				if ((autodection_data[array_subscript]&(1<>3); 
				bit_subscript=(k%8); 
				custID=(custID|(((autodection_data[array_subscript]&(1<>bit_subscript)<>bit_subscript)<>3); 
					bit_subscript=(l%8); 
					DataItem[k]=(DataItem[k]|(((autodection_data[array_subscript]&(1<>bit_subscript)<