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

📄 m500auc.c

📁 51单片机进行mifare1射频卡开发
💻 C
📖 第 1 页 / 共 5 页
字号:
            if (irqBits & 0x01)     /* 如果缓冲器FIFO未满成立 */
            {
                nbytes = 64 - ReadRawIO(RegFIFOLength);
                if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes)
                {
                    nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;
                    WriteRawIO(RegInterruptEn,0x01);
                }
                for ( cnt = 0;cnt < nbytes;cnt++)
                {
                    WriteRawIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);
                    MpIsrInfo->nBytesSent++;
                }
                WriteRawIO(RegInterruptRq,0x01);
            }
            if (irqBits & 0x10)     /* 如果有发送中断请求 */
            {
                WriteRawIO(RegInterruptRq,0x10);    /* 则置发送中断请求 */
                WriteRawIO(RegInterruptEn,0x82);    /* 缓冲区FIFO满中断使能 */
                if (MpIsrInfo->cmd == PICC_ANTICOLL1)
	            {
                    WriteIO(RegChannelRedundancy,0x02);
                    WriteRawIO(0,0x80);
	            }
            }
            if (irqBits & 0x0E)      /* 如果有接收中断请求? */
            {
                nbytes = ReadRawIO(RegFIFOLength);
                for ( cnt = 0; cnt < nbytes; cnt++)
                {
                    MpIsrOut[MpIsrInfo->nBytesReceived] = ReadRawIO(RegFIFOData);
                    MpIsrInfo->nBytesReceived++;
                }
                WriteRawIO(RegInterruptRq,0x0A & irqBits);
            }
            if (irqBits & 0x04)      /* 如果有IDLE中断请求 */
            {
                WriteRawIO(RegInterruptEn,0x20);     /* 则置计时器中断使能和请求 */
                WriteRawIO(RegInterruptRq,0x20);
                irqBits &= ~0x20;
                MpIsrInfo->irqSource &= ~0x20;
                WriteRawIO(RegInterruptRq,0x04);
            }
            if (irqBits & 0x20)       /* 如果有计时器中断请求 */
            {
                WriteRawIO(RegInterruptRq,0x20);
                MpIsrInfo->status = MI_NOTAGERR;    /* 则表明无卡在此场中 */
            }
        }
    }
}

///////////////////////////////////////////////////////////////////////
 /* RS232异步串行通信接收和发送中断子程序 */
///////////////////////////////////////////////////////////////////////
void isr_UART(void) interrupt 4 using 1
{
    unsigned char len, i;
  	unsigned int j=0;

  	if(RI)
	{
		len=SBUF;                             /* LEN为数据个数 */
		RI=0;
		for(i=0;i<len;i++)
		{
			while(!RI)
			{
				j++;
				if(j>1000)
				{
				    break;
				}
			}
			if(j<1000)
			{
				RevBuffer[i]=SBUF;     /* 接收来自上位机PC的数据 */
				RI=0;
				j=0;
			}
			else
			{
			    break;
			}
		}
		if(i==len)
		{
			REN=0;
			CmdValid=1;
		}
	}
	else if(!RI && TI)
	{
		TI=0;
		len=RevBuffer[0];                  /* LEN为数据个数 */
		for(i=0;i<len+1;i++)
		{
			SBUF=RevBuffer[i];         /* 发送单片机里的已知数据 */
			while(!TI);
			TI=0;
		}
		REN=1;
	}
}

///////////////////////////////////////////////////////////////////////
/* MF RC500软硬件配置总程序 */
///////////////////////////////////////////////////////////////////////
char MfConfig(void)
{
	char status=MI_OK;

	M500PcdConfig();       /* 配置RC500读写器的引脚,重启时序 */
	M500PcdMfOutSelect(2);  /* ? */
	return status;
}

///////////////////////////////////////////////////////////////////////
/* 系统初始化---单片机和RC500芯片 */
///////////////////////////////////////////////////////////////////////
void init(void)
{
	RC500RST=0;
	ET2 = 0;              // 禁止定时器2中断
	T2CON = 0x04;         // 启动定时器2(tr2=1)
         PCON = 0x00;
         SCON = 0x70;         // 8位uart,波特率可变
         TMOD = 0x21;         //TMOD = 0x22;  两个定时器均为自动重载方式

	TH1   = BAUD_9600;
	TL1   = TH1;
	TR1   = TRUE;             // 串行口波特率发生器---定时器1

	TH0 = 0x60;               // 定时器0初始化
        TL0 = 0x60;
        TR0 = 0;

        ET0=0;                    //定时器0中断禁止---用作一般定时器
	ET1=0;                    //定时器1中断禁止---用作波特率发生器
	EA=1;                     //总中断允许
	EX0=1;                    //外部中断0允许----rc500的irq
	IT0 = 1;                  //外部中断0触发类型--下降沿触发
	TR2=0;                    // 关闭定时器2(tr2=1)
 	ES = TRUE;                //串行口中断允许
	CmdValid=0;

        SPEAKER=1;
	delay_10ms(30);
	SPEAKER=0;
	delay_10ms(30);
	SPEAKER=1;

        reset_7289();
 	MfConfig();             /* 调用RC500软硬件配置总程序 */
}

///////////////////////////////////////////////////////////////////////
// IC卡处理函数
///////////////////////////////////////////////////////////////////////
void cmd_execution(void)
{
	unsigned char cmd;
	unsigned char status;

	cmd = RevBuffer[0];    /* 来自上位机的命令存于REVBUFFER[0] */
	switch(cmd)
	{
		case 1:           /* 终止卡的操作 */
			status=M500PiccHalt();

			RevBuffer[0]=1;
			RevBuffer[1]=status;    /* 返回给上位机的内容 */
			break;
		case 2:     // Request,Anticoll,Select,return CardType(2 bytes)+CardSerialNo(4 bytes)
			        // 寻卡,防冲突,选择卡    返回卡类型(2 bytes)+ 卡序列号(4 bytes)
		       	status=M500PiccCommonRequest(RevBuffer[1],&RevBuffer[2]);
			if(status!=0)                 /* 寻卡指令,应答信息 */
			{ /* 寻卡不成功 */
				status=M500PiccCommonRequest(RevBuffer[1],&RevBuffer[2]);    /* 再次寻卡 */
				if(status!=0)
				{  /* 寻卡还是不成功 */

					RevBuffer[0]=1;
					RevBuffer[1]=status;   /* 做出应答信息给上位机 */
					break;
				}
			}

			if(RevBuffer[2]==2)             //返回信息
				cardtype=mifarepro;     // Mifare Pro 卡
			else if(RevBuffer[2]==4)
			       {cardtype=mifare1;       // Mifare One 卡

                                }
			else if(RevBuffer[2]==16)
				cardtype=mifarelight;   // Mifare Light 卡
			else
				cardtype=unknowncard;

			RevBuffer[0]=3;
			RevBuffer[1]=status;            /* 做出应答信息给上位机 */

			break;

		case 3:                         // 防冲突 读卡的系列号 MLastSelectedSnr
		       {status = M500PiccCascAnticoll(0,&RevBuffer[2]);
                        status=0;
			if(status!=0)
			{   /* 反冲突失败 */
				RevBuffer[0]=1;
				RevBuffer[1]=status;  /* 做出失败的应答信息给上位机 */

				break;
			}
                        /* 反冲突成功 */
			memcpy(MLastSelectedSnr,&RevBuffer[2],4);    /* 存储序列号 */
			RevBuffer[0]=5;
			RevBuffer[1]=status;          /* 做出成功的应答信息给上位机 */

                       }
			break;

		case 4:		                    // 选择卡 Select Card
			status=M500PiccCascSelect(MLastSelectedSnr,&RevBuffer[2]);

			if(status!=MI_OK)
			{
				RevBuffer[0]=1;
				RevBuffer[1]=status;  /* 做出失败的应答信息给上位机 */
				break;
			}
			RevBuffer[0]=3;
			RevBuffer[1]=status;          /* 做出成功的应答信息给上位机 */

			break;
		case 5:	    // Key loading into the MF RC500's EEPROM
		            // 校验卡密码(E2)
			status=M500PiccAuthE2(RevBuffer[1],MLastSelectedSnr,RevBuffer[2],RevBuffer[3]);
			RevBuffer[0]=1; /* 入口参数:AUTH_MODE:A/B卡型号,SNR:卡序列号,KEYNR:密钥所在EE扇区数,BLOCK:密钥所在卡数据块*/
			RevBuffer[1]=status;
			break;
		case 6:     // Key loading into the MF RC500's EEPROM
		            // 下载密码(E2)
			status=M500PcdLoadKeyE2(RevBuffer[1],RevBuffer[2],&RevBuffer[3]);
			RevBuffer[0]=1;
			RevBuffer[1]=status;
			break;
		case 7:     // Authentication with direct key loading from the uC
		            // 直接校验密码
			memcpy(&RevBuffer[9],&RevBuffer[3],6);
			M500HostCodeKey(&RevBuffer[9],&RevBuffer[3]);
			status=M500PiccAuthKey(RevBuffer[1],MLastSelectedSnr,&RevBuffer[3],RevBuffer[2]);
			RevBuffer[0]=1; /* 入口参数:AUTH_MODE:A/B卡型号,SNR:卡序列号,KEYNR:密钥所在RAM地址,BLOCK:密钥所在卡数据块*/
			RevBuffer[1]=status;
			break;
		case 8:     // Read the mifare card
		            // 读卡
			status=M500PiccRead(RevBuffer[1],&RevBuffer[2]);
			if(status==0)
			{
				if(cardtype==mifare1||cardtype==mifarepro)
					RevBuffer[0]=17;    /* 卡类型决定一次能读出的数据个数 */
				else if(cardtype==1)
					RevBuffer[0]=9;     /* 一次读出9个 */
				else
					RevBuffer[0]=16;    /* 一次读出16个(MIFARE1) */
			}
			else
			{
			    RevBuffer[0]=1;
			}
			RevBuffer[1]=status;
			break;
		case 9:     // Write the mifare card
		            // 写卡  下载密码
			status=M500PiccWrite(RevBuffer[1],&RevBuffer[2]);
			RevBuffer[0]=1;
			RevBuffer[1]=status;
			break;
		case 10:    // 写卡  改变卡内EEROM中数据块中的内容
			status = M500PiccValue(RevBuffer[1],RevBuffer[2],&RevBuffer[3],RevBuffer[7]);
			RevBuffer[0]=1;   /* 入口参数:三种命令(自增,自减,改变),卡块地址,要写入的值,卡块地址 */
			RevBuffer[1]=status;
			break;
		case 12:    // 参数设置
			RevBuffer[0]=1;	//contact
			RevBuffer[1]=0;
			break;
	}
}

///////////////////////////////////////////////////////////////////////
// 主函数
///////////////////////////////////////////////////////////////////////
void main(void)
{
    init();
    while (1)
    {
     if (CmdValid)
        {
         CmdValid = FALSE;
         cmd_execution();        // 进入IC卡处理程序
         CALL_isr_UART();
        }
    }
}

⌨️ 快捷键说明

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