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

📄 r6c.c

📁 采用C52+R6C完成的ISO15693标准的刷卡器程序
💻 C
字号:
#include "typedef.h"



////////////////////////////////////////////////////
void _sendBit(bit temp)
{
	DIN = 1;
	SCLOCK = 0; _nop_();    
	DIN = temp; _nop_();  
	SCLOCK = 1; _nop_(); 
	SCLOCK = 0;
}
/************************************************************************/
/* clockmaster transfer from uctrl to ASIC*/
/************************************************************************/
void _trans1(void)
{
	SCLOCK = 0;  
	DIN = 0;  _nop_();
	DIN = 1;  _nop_();
	DIN = 0;  _nop_();
	DIN = 1;  _nop_();
	SCLOCK = 1;_nop_();
}
/*****************************************************************/
/* clockmaster transfer from ASIC to uctrl************************/
/*****************************************************************/

void _trans2(void)
{
	SCLOCK = 0;  
	DIN = 1;   _nop_();
	DIN = 0;  _nop_();
	DIN = 1;  _nop_();
	DIN = 0;  _nop_();
}

/*****************************************************************/
/*startbit S1:rising edge on Din while SCLOCK high   *************/
/*****************************************************************/
void _startBit(void)
{ 
	SCLOCK = 0;    _nop_(); 
	DIN    = 0;    _nop_(); 
	SCLOCK = 1;    _nop_(); 
	DIN    = 1;    _nop_(); 
	SCLOCK = 0;    _nop_(); 
}

/*****************************************************************/
/* stopbit ES1:falling edge on Din while SCLOCK high  ************/
/*****************************************************************/
void _stopBit(void)
{ 
	SCLOCK = 0;  _nop_();
	DIN    = 1;  _nop_();
	SCLOCK = 1;  _nop_();
	DIN    = 0;  _nop_();
	SCLOCK = 0;  _nop_();
}
/*****************************************************************/
/* find S2:  a SOF sent by the TAG *******************************/
/*****************************************************************/
bit TIMERINT;

uchar _findS2(void)
{
	uchar S2=0;
	while ((!SCLOCK)&&(!TIMERINT));	//等到SCLK变高
	if (SCLOCK)						//sclk变到高电平
	{
		while ((SCLOCK)&&(!TIMERINT)&&(!DOUT));	//等到dout输出为高
		if (DOUT)	//dout已经为高电平
		{
			while ((SCLOCK)&&(!TIMERINT)&&(DOUT));//等sclk变为低电平,dout为高
			if (!SCLOCK)
			{
				S2 = 1;	//找到起始信号
			}
		}
	}
	return (S2);
}

/*****************************************************************/
/* readbit:read data from DOUT*************************************/
/*****************************************************************/
uchar _readbit(void)
{
	uchar i, sample, doutstore;
	uchar debounce=1; 					// min clockpulse is 4.7us for 106kBaud
	while ((!SCLOCK)&&(!TIMERINT)); 	//wait for rising edge
   
  	for (i=0; i<debounce;i++); 
  	if (SCLOCK)
	{
		if(M_ERR)
		{  
			if(M_ERR) { sample = 2; return (sample); }
		}
		doutstore=DOUT;
		if (!DOUT)
			sample = 0;
		else
			sample = 1; 				//store sample: no debouncing!
		
		while ((SCLOCK)&&(!TIMERINT)&&(doutstore ==DOUT));
		
		if ((SCLOCK)&&(doutstore != DOUT) )		// ES2
		{
			sample = 0x03;
		}
		else if (TIMERINT)						// timeout
		{
			sample = 0x04;
		}	  
	}
	return(sample);  
}

/*****************************************************************/
/***read on DOUT and write on DIN, with uctrl master of clock.****/
/*****************************************************************/

uchar _rwbit(uchar wbit)
{ 
	uchar i, rbit;
	if(wbit)
		DIN = 1;
	else
		DIN = 0;
	SCLOCK = 1;
	DOUT = 1;
	for (i=0;i<2;i++); //dummy
	if (!DOUT)
		rbit=0;
	else
		rbit=1;
	SCLOCK = 0;
	return (rbit);
}
/*****************************************************************/

unsigned char prgCnt = 0;
uchar pwUpScanCnt = 0;
uchar spkerCnt = 0;
uchar timeout;
bit b_spker = 0;
bit b_com_r6c;

void time(void) interrupt 1 using 2
{
	
	TH0=0xdc;                    //10ms的基准定时,11.0592M
	TL0=0x00;

	prgCnt ++;	//prg run
	pwUpScanCnt ++;	
	if(b_spker)spkerCnt++;
	if(b_com_r6c) 
	{
		timeout --;
		if(timeout==0)
		{ 
			TIMERINT=1;
			b_com_r6c=0;
		}
	}

}
/**************************************************************/

BOOL _setTimer(uchar timeout_temp)
{
	b_com_r6c = 1;
	timeout = timeout_temp;
	TIMERINT= 0;
	TR0 = 1;
	return(TRUE);
}
void _clrTimer(void)
{
	b_com_r6c = 0;
	timeout = 0;
	TIMERINT = 0;
}


/**************************************************************/


uchar idata pcdata[140];  
uchar code tab1[16]={0x00,0x08,0x04,0x0c,0x02,0x0a,0x06,0x0e ,0x01,0x09,0x05,0x0d,0x03,0x0b,0x07,0x0f};

////////////////////////////////////////////////////////////////////

BYTE ReflectBYTE(BYTE byOrg) 
{
	BYTE j,k;
	j = byOrg & 0x0f;
	j = tab1[j];
	j = j<<4;
	k = byOrg>>4;
	k = tab1[k];
	j = j + k;
	return(j);
}

#define POLYNOMIAL  0x8408   /*x^16+x^12+x^5+1*/
#define PRESET_VALUE 0xFFFF
#define CHECK_VALUE 0xF0B8
#define CALC_CRC     1
#define CHECK_CRC    0

WORD crc16Calculate(BYTE idata * pBuf,BYTE byLen)
{
	unsigned int current_crc_value;
	BYTE i,j;
 	current_crc_value = PRESET_VALUE;
 	for(i=0;i<byLen;i++)
  	{
		current_crc_value = current_crc_value^pBuf[i];
		for(j=0;j<8;j++)
		{
			if(current_crc_value & 0x0001)
			{
				current_crc_value = (current_crc_value>>1)^POLYNOMIAL;
			}
			else
			{
				current_crc_value = (current_crc_value>>1);
			}
		}
   	}
	current_crc_value = ~current_crc_value;		//?????
 	return(current_crc_value);
 } 

#define HIBYTE(w)	((BYTE)(w>>8))
#define LOBYTE(w)	((BYTE)(w))
bit chkCRC(BYTE idata * cBuf,BYTE cLen)
{
   bit flag =1;
   uchar i;
   uint j;
   for(i=0;i<cLen;i++) { cBuf[i] = ReflectBYTE(cBuf[i]); }
   j = crc16Calculate(cBuf,cLen-2);
   flag  = (cBuf[cLen-2] == LOBYTE(j) );		//crc LSByte
   flag &= (cBuf[cLen-1] == HIBYTE(j) );		//crc MSByte
   return(flag);
}

void _sendfifocmd(void)
{
	bit flag;
	uchar Bytecnt,nrofBytes ,bitcnt,nbBit,ISOcmd;
	uint i;  
	
	ISOcmd = ReflectBYTE(pcdata[5]);
	/*
	pcdata[1] = pcdata[1]&0x07;
	if (pcdata[2]==0x16)
		nrofBytes = pcdata[0]-3-2; //last 2 bytes are for CRC.
	else if (pcdata[2]==0x18)
	{
		nrofBytes = 1; // send only command nr
		pcdata[1] = 0;
	}
	else
		nrofBytes = pcdata[0]-3;
		*/
	nrofBytes = pcdata[0]-3;

	_startBit();
	
	for(Bytecnt=0;Bytecnt<nrofBytes ;Bytecnt++)
	{
		if(Bytecnt<nrofBytes-1)
			nbBit = 8;
		else if(!pcdata[1])
			nbBit = 8;
		else
			nbBit = pcdata[1];
		for(bitcnt=0;bitcnt<nbBit;bitcnt++)
		{	
			//_setTimer(2);	
			while ((DOUT)&&(!TIMERINT)); //FIFO Management
			clrTimer();
			pcdata[Bytecnt+3] = pcdata[Bytecnt+3] << 1;
			flag = CY;
			_sendBit(flag);
		}
		if(Bytecnt == 0)
		{
			for(i=0;i<0x5FF;i++);
		}
	}
	/*	
   switch (ISOcmd)
   {
		case 0x21: case 0x22: case 0x24:
		case 0x27: case 0x28: case 0x29: case 0x2A:
		case 0xA2: case 0xA3: case 0xa4: case 0xa5:
		{		
			_setTimer(2);
			while((DOUT)&&(!TIMERINT)); _stopBit();
			
			_clrTimer();
			for(i=0;i<0xbff;i++);  break;
		}
	}
	*/
}

bit b_collision;
bit userCardOk;
#define TIME_OUT_ASICRDY  3     //30 ms
#define TIME_OUT_TAGRDY   3     //30 ms
#define TIME_OUT_READDATA 10     //80 ms

void _gettagresponse(uchar responseaftercmd, char SID)
{
	uchar Bytecnt,bitcnt, ASICRDY, TAGRDY, TAGDONE, bitval, temp;
	bit b_col = 0;
	b_collision = 0;
	ASICRDY = 0;	TAGRDY = 0; 
	while((DOUT)); _stopBit(); _nop_(); _nop_();
	while((DOUT));    
	_trans1();
	if (responseaftercmd)                         // wait for buffer to empty before cont.
	{  
		TH0 = 0x63; TL0 = 0xc0;                      //12ms
		_setTimer(TIME_OUT_ASICRDY);                 //wait for ERR-pulse
		while ((!M_ERR)&&(!TIMERINT));
		if (M_ERR)
		{
			while ((M_ERR)&&(!TIMERINT));
			if (!M_ERR)
			{                                       //err pulse (typ. 18us) detected
				ASICRDY = 1;
				TH0 = 0x63; TL0 = 0xc0;                      //12ms
				_setTimer(TIME_OUT_TAGRDY);				
			}
		}
	}
	/*
	else
	{
		ASICRDY=1;
		TH0 = 0x63; TL0 = 0xc0;                      //12ms
		_setTimer(TIME_OUT_TAGRDY);
	}
	*/
	if(ASICRDY)
	{                                             // wait for tag to respond; wait for S2 signal.
		while((!TAGRDY)&&(!TIMERINT))
		{
			if (_findS2())
			{
				TAGRDY=1;				
				TH0 = 0x63; TL0 = 0xc0;                      //12ms
				_setTimer(TIME_OUT_READDATA);				
			}
		}
	}
	if(TAGRDY)
	{
		TAGDONE=0;
		bitcnt=0;
		Bytecnt=3;		//It's value is nr of bytes -1 (i.e. the value in [o])

		temp= 0;
		while ((!TAGDONE)&&(!TIMERINT))
		{
			bitval =_readbit();
			switch (bitval)
			{
				case 0x02:
					b_col = 1; 
				break;

				case 0x03:
					TAGDONE =1; 		//received ES2				
					pcdata[Bytecnt] = temp;
					pcdata[0] = Bytecnt;
					pcdata[1] = bitcnt;			
					if(chkCRC(pcdata+3,Bytecnt-3))
					{
                  		userCardOk = 1;
               		} 
          		break;

          		case 0x04: //timeout
	    		break;

          		default:
				if (bitcnt==8) //start new byte
				{
					if(Bytecnt <100) 
					{
						pcdata[Bytecnt] = temp;
						temp=0;
						bitcnt =0;
						Bytecnt++; 
					}
				}
				bitcnt++;
				temp = temp*2 + bitval;
				break;
			}
		}
	}
	/*
	else if (SID) //no tag in slot, doesn't mean timeout
		TIMERINT=0;//TIFR = TIFR|0x10; //reset TIMERINT
		*/
	
	b_collision = b_col;
	_trans2(); //uctrl becomes again master of clock
	_clrTimer();
}
uchar rd_ConReg(void)
{
	uchar j,bitval;
	bit flag;
	
	pcdata[2]=0;
	_startBit();
	pcdata[0] =4;
	pcdata[1] =0;
	pcdata[2] =0;
	pcdata[3]=0x71;                      /* send command */
	for(j=0;j<8;j++)
	{
		pcdata[3]  = pcdata[3] << 1;
		flag = CY;
		_sendBit(flag);
	}
	for(j=0;j<8;j++)                      /*get regCfg*/
	{
		bitval = _rwbit(0);
		pcdata[2] = pcdata[2]*2 + bitval;
	}
	_stopBit();                           /*send ES1*/
	pcdata[0] = 0x03;
	pcdata[1] = 0x00;
	return(pcdata[2]);
}


void switchon(void)
{
	_startBit();
	_sendBit(1);
	_stopBit();
}

uchar xx = 0x30;
uchar _commandrd(void)
{
	uchar i;
	pcdata[1] = 0;                       
	pcdata[2] = 0x00;
	pcdata[3] = 0x39;                     /* 通讯参数设置:调制100%、低数据率、FM调制、无曼彻斯特解调*/


	//if(++xx>0x3F) xx = 0x30;
	
	
	for(i= 4;i<pcdata[0];i++)
	{
		pcdata[i] = ReflectBYTE(pcdata[i]);  /*数据倒序*/
	}	
	_sendfifocmd();	
	_gettagresponse(1,0);
   if (TIMERINT)  { return(0); }               
   else           { return(1); }
}

void send_ISO_cmd(uchar flags,uchar cmd,uchar dataPstion,uchar paraLength)
{
   	uint crc_val;
	
	pcdata[4] = flags;
	pcdata[5] = cmd;
	
	crc_val = crc16Calculate(pcdata+4,2+paraLength);
	pcdata[6+paraLength] = LOBYTE(crc_val);
	pcdata[7+paraLength] = HIBYTE(crc_val);
	pcdata[0] = 8+paraLength;   
	_commandrd();
}

⌨️ 快捷键说明

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