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

📄 m500auc.c

📁 ISO14443协议的实现
💻 C
📖 第 1 页 / 共 3 页
字号:
#pragma small DEBUG SYMBOLS OBJECTEXTEND CODE
#include <string.h>
#include <stdio.h>
#include <absacc.h>
#include <intrins.h>
#include "Mfreg500.h"                                         //RC500寄存器
#include "MfErrNo.h"                                          //错误标识
#include "reg52.h"                                            //89C52寄存器
#include "M500AuC.h"
#define uchar unsigned char
#define uint unsigned int
#define GetRegPage(addr) (0x80 | (addr>>3))
#define NO_TIMER2 1
uchar   status;
uchar	ID,command,NAD;
uchar   LcLe,Rlen,sw1,sw2;
uchar	cla,ins,pcb,pcb_r;
uchar	block_num;
uchar	timer0;
uint    Len,ramlen,tt0;
uchar   TC1,DD,WI;

void delay_1ms(unsigned char _1ms);
void delay_50us(unsigned char _50us);
uchar M500PcdRfReset(unsigned char ms);
uchar SetBitMask(unsigned char reg,unsigned char mask);
void M500PcdSetTmo(unsigned char tmoLength);
uchar M500PcdCmd(
                volatile unsigned char data * rcv,
                volatile MfCmdInfo idata *info);
uchar ClearBitMask(unsigned char reg,unsigned char mask);
void FlushFIFO(void);
void toPpc(unsigned int Address,unsigned char value)         //向外存中写入数据
{
        //XBYTE[0x8000+Address]=value;                //20030317 片选引脚改变
	XBYTE[0xc000+Address]=value;
}
unsigned char fromPpc(unsigned int Address)                  //从外存中读出数据
{
        //return XBYTE[0x8000+Address];                     //20030317 片选引脚改变
        return XBYTE[0xc000+Address];
}

void WriteRawIO(unsigned char Address,unsigned char value)   //向RC500寄存器中写数据
{
        //XBYTE[0x6000+Address]=value;                       //20030317 片选引脚改变
	XBYTE[0xa000+Address]=value;
}
unsigned char ReadRawIO(unsigned char Address)               //从RC500寄存器中读数据
{
        //return XBYTE[0x6000+Address];                      //20030317 片选引脚改变
	return XBYTE[0xa000+Address];
}

void WriteIO(unsigned char Address, unsigned char value)
{
   WriteRawIO(0x00,GetRegPage(Address));
   WriteRawIO(Address,value);
}
unsigned char ReadIO(unsigned char Address)
{
   WriteRawIO(0x00,GetRegPage(Address));
   return ReadRawIO(Address);
}


void M500PcdSetTmo(unsigned char tmoLength)                //设置计时器
{switch(tmoLength)
   {  // 时钟频率13.56MHz
      case 1:                       // short timeout (1,0 ms)
         WriteIO(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128
         WriteIO(RegTimerReload,0x6a);// TReloadVal = 'h6a =106(dec)
         break;
      case 2:                       // medium timeout (1,5 ms)
         WriteIO(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128
         WriteIO(RegTimerReload,0xa0);// TReloadVal = 'ha0 =160(dec)
         break;
      case 3:                       // medium timeout (6 ms)
         WriteIO(RegTimerClock,0x09); // TAutoRestart=0,TPrescale=4*128
         WriteIO(RegTimerReload,0xa0);// TReloadVal = 'ha0 =160(dec)
         break;
      case 4:                       // long timeout (9.6 ms)
         WriteIO(RegTimerClock,0x09); // TAutoRestart=0,TPrescale=4*128
         WriteIO(RegTimerReload,0xff);// TReloadVal = 'hff =255(dec)
         break;
      case 5:                       // long timeout (38.5 ms)
         WriteIO(RegTimerClock,0x0b); // TAutoRestart=0,TPrescale=16*128
         WriteIO(RegTimerReload,0xff);// TReloadVal = 'hff =255(dec)
         break;
      case 6:                       // long timeout (154 ms)
         WriteIO(RegTimerClock,0x0d); // TAutoRestart=0,TPrescale=64*128
         WriteIO(RegTimerReload,0xff);// TReloadVal = 'hff =255(dec)
         break;
      case 7:                       // long timeout (616.2 ms)
         WriteIO(RegTimerClock,0x0f); // TAutoRestart=0,TPrescale=256*128
         WriteIO(RegTimerReload,0xff);// TReloadVal = 'hff =255(dec)
         break;
      default:                       //
         WriteIO(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128
         WriteIO(RegTimerReload,tmoLength);// TReloadVal = 'h6a =tmoLength(dec)
         break;
   }
}
void t0int(void) interrupt 1 using 3
{
	timer0++;
}




//---------------------------------------------------------------------------------------

void ES_int(void) interrupt 4 using 3  //从串口读出第一个字节
{
        EA = 0;
        ES = 0;//ES int off
        STATE_FLAG = 0;
        RI = 0;
        if(SBUF != 0xaa) {ES = EA = 1;return ;}//Head = 0xAA
        ESint = 1;
        EA = 1;
}

void SRCH232(void)                    //设置串行通讯端口
  {
        INH = 0;
	TH1=TL1=254;//57600bps with 22.1184MHz
	TR1=1;
	delay_1ms(1);//1ms
	XC1=XC2=1;
	delay_1ms(1);//1ms
	RI=0;
  }

void SRCH_ICC(uchar C4052)//?/*建立与CPU_ICC.AT24c16.AT45d041通信关系*/
{
        INH = 0;

                 TH1=TL1=BAUD_9600;


        TR1 = 1;
	delay_1ms(1);//1ms
	if(C4052==CPUtype)			//cpu card
		{XC1=XC2=0;}
	if(C4052==SAM1type)			//sam card
		{XC1=1;XC2=0;}
	if(C4052==AT24type)
		{XC1=0;XC2=1;}//AT24C16
	delay_1ms(1);//1ms
        tt0 = timer0 = 0;
        RI=0;
}
//---------------------------------------------------------------------------------------

uchar recv_pc(void)                    //从PC接受一个字符
	{
        ET0 = 0;
	timer0 = 0;
	STATE_FLAG=0;
        ET0 = 1;EA = 1;
	while(!RI)	if(timer0 > 20000) break;//10
	if(RI==0)
        {STATE_FLAG=1;return(0x84);}//time out
	RI=0;
        ET0 = 0;
	return(SBUF);
	}

uchar recvfrompc(void)                //从PC接受数据
	{
	uchar temp=0;
	uint i;
        uint length;
        uchar Bcc = 0;
        Rlen = 0;
        led=0;
        SRCH232();
        ES = 0;
        do
        {
          while(!RI)
          {
             if(ICSW)
               {
                EX1 = 1;
                led = 1;
               }
              else
               {
                 EX1 = 0;
                 led = 0;
               }

           }
          RI=0;
        } while(SBUF != 0xaa); //Head = 0xAA

        temp=SBUF;
	ID=recv_pc();                                  //device
	if(STATE_FLAG) return(ID);

	command=recv_pc();                             //command
        if(STATE_FLAG) return(command);

	temp=recv_pc();                                //block addr/No.
	if(STATE_FLAG) return(temp);

	block_num=recv_pc();                           //block number
	if(STATE_FLAG) return(block_num);

	length=recv_pc();                              //length.L
	if(STATE_FLAG) return((uchar)length);

	temp=recv_pc();                                //length.H
	if(STATE_FLAG) return(temp);
	length|=((uint)temp)<<8;

  if(length!=0)
	{
	NAD=recv_pc();
	if(STATE_FLAG) return(NAD);
        Bcc ^= NAD;

	pcb=recv_pc();
	if(STATE_FLAG) return(pcb);
        Bcc ^= pcb;

	Rlen=recv_pc();
	if(STATE_FLAG) return(Rlen);
        Bcc ^= Rlen;

        if(command == 0x52) return 0;

        Len=length-3;

	for(i=0;i<length - 3;i++)
		{
		temp=recv_pc();
        	if(STATE_FLAG)
                              return(temp);
 		toPpc(i,temp);
                Bcc ^= temp;
		}


	temp=recv_pc();
        if(Bcc != temp)
               return -1;

	cla=fromPpc(0);
	ins=fromPpc(1);
	LcLe=fromPpc(4);
        return 0;
	}

}


void SEND_PC(uchar chr)          //向PC发送一个字节
	{
	TXD = 1;
	while(!TXD);
	ACC = chr;
	TB8 = P;
	SBUF = ACC;
	while(!TI);
	TI=0;
	}



void sendtopc(void)              //向PC发送数据
	{
	uint i;
	uchar chr,Bcc;

ET0 = 0;
	SEND_PC(0x55);//send headle
        Bcc = 0x55;
        SEND_PC(ID);//send device
        Bcc ^= ID;
	SEND_PC(command);//send command/ST
        Bcc ^= command;
	SEND_PC(Len);//send lengthL
        Bcc ^= Len;
	SEND_PC(0);//send lengthH

	if(Len!=0)
	{
		//Bcc=0;//BCC
		for(i = 0; i < Len; i++)
			{
			chr=fromPpc(i);
			SEND_PC(chr);//send DATA
			Bcc^=chr;
			}
	}
	SEND_PC(Bcc);//send BCC
	}
//M500PcdCmd函数负责取得命令代码cmd,数据指针rcv,状态指针info,并向RC500发送命令,取得应答返回到数据指针
uchar  M500PcdCmd(
               volatile unsigned char data *rcv,
                MfCmdInfo idata *info)
{
   char          idata status    = MI_OK;
   char          idata tmpStatus ;
   unsigned char idata lastBits;
   unsigned int idata timecnt=0;
   uint i;
   unsigned char idata irqEn     = 0x00;
   unsigned char idata waitFor   = 0x00;
   unsigned char idata timerCtl  = 0x00;

   WriteIO(RegInterruptEn,0x7F);
   WriteIO(RegInterruptRq,0x7F);
   WriteIO(RegCommand,PCD_IDLE);

   FlushFIFO();
   MpIsrInfo = info;
   MpIsrOut   = rcv;
   info->irqSource = 0x0;

   info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
   irqEn = 0x3D;
   waitFor = 0x04;


   if (status == MI_OK)              //如果没有错误
   {
      irqEn |= 0x20;
      waitFor |= 0x20;
      timecnt=1000;
      WriteIO(RegInterruptEn,irqEn | 0x80);
      WriteIO(RegCommand,0x1E);         //发送命令
      for(i=0;i<200;i++)
      {
      if(info->nBytesReceived)         //取得应答
         {
          MpIsrInfo->status=0;
          info->status=0;
          break;
          }
      delay_1ms(tt0);
      }

      WriteIO(RegInterruptEn,0x7F);
      WriteIO(RegInterruptRq,0x7F);
      SetBitMask(RegControl,0x04);
      WriteIO(RegCommand,PCD_IDLE);     //通知RC500命令执行完毕
      if(i==200)  status = MI_NOTAGERR; //如果在200ms内没有取得应答,返回错误代码
      else
         status = MpIsrInfo->status;

      if (status == MI_OK)             //根据错误代码返回不同的status值
      {
         if (tmpStatus = (ReadIO(RegErrorFlag) & 0x17))
         {
            if (tmpStatus & 0x01)
            {
               info->collPos = ReadIO(RegCollPos);
               status = MI_COLLERR;
            }
            else
            {
               info->collPos = 0;
               if (tmpStatus & 0x02)
               {
                  status = MI_PARITYERR;
               }
            }
            if (tmpStatus & 0x04)
            {
               status = MI_FRAMINGERR;
            }
            if (tmpStatus & 0x10)
            {
               FlushFIFO();
               status = MI_OVFLERR;
            }
 	    if (tmpStatus & 0x08)
	    {
               status = MI_CRCERR;
	    }
            if (status == MI_OK)
               status = MI_NY_IMPLEMENTED;
         }

            lastBits = ReadIO(RegSecondaryStatus) & 0x07;      //判断是否有CRC效验
            if (lastBits)
               info->nBitsReceived += (info->nBytesReceived-1) * 8 + lastBits;
            else
               info->nBitsReceived += info->nBytesReceived * 8;

      }
      else
      {
         info->collPos = 0x00;
      }
   }
   MpIsrInfo = 0;
   MpIsrOut  = 0;
   MpIsrOut   = 0;
   tt0=1;
   return status;
}

uchar SetBitMask(unsigned char reg,unsigned char mask) //将RC500中某一寄存器的数据的某几位置1
{
   char idata tmp = 0x0;

   tmp = ReadIO(reg);
   WriteIO(reg,tmp | mask);  // set bit mask
   return 0x0;
}

uchar ClearBitMask(unsigned char reg,unsigned char mask) //将RC500中某一寄存器的数据的某几位清0
{
   char idata tmp = 0x0;

   tmp = ReadIO(reg);
   WriteIO(reg,tmp & ~mask);  // clear bit mask
   return 0x0;
}

void FlushFIFO(void)                                   //清空FIFO
{
   SetBitMask(RegControl,0x01);
}



uchar M500PcdReset(void)                                //复位RC500

⌨️ 快捷键说明

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