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

📄 main.c

📁 本程序是基于MFRC500射频卡读写器的单片机控制程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
* File :  main.c                                                            *
* COPYRIGHT BY HUOYAN LTD.COMPANY                                           *
* Version:      V5.2                                       			        *
* Created:      18.11.2002                                                  *
* Last Change:  8.Jan.2005                                                  *
* Author:       NIL                                                         *
* Compiler:     KEIL C51 V7.10                                              *
* Description:  AT89S52-Firmware for MFRC500 Demo Serial Reader             *
*                                                                           *
****************************************************************************/
#define __SRC
#include "main.h"
#undef  __SRC

#include <string.h>
#include <stdio.h>
#include <absacc.h>
#include <intrins.h>
#include "AT89S52.h"
#include "Mfreg500.h"
#include "M500a.h"


#define uchar	unsigned char
#define uint unsigned int
//#define DataPort P0				// 数据端口


//pin define  mcu控制管脚定义
     
sbit RC500RST   =   P1^0;		//由高变低时复位RC500
sbit RC500CS=P1^1;
sbit CARD_LED=P1^2;
sbit SPEAKER    =   P1^3; 		  

bit bcard;

///////////////////////////////////////////////////////////////////////
// 主函数
///////////////////////////////////////////////////////////////////////
void main(void)
{ 	//设置变量
    uchar baud;
  

    InitSystem();       //初始化系统	  
	// bcard=0;
    
   	delay_10ms(5);					
    while (1)
    { 	
	
        // KeyPress();	处理按键
   		delay_10ms(5);   
		//检查串口命令标志	
 	    if (bCmd)   
	    {	
		     
		    bCmd = FALSE;     //清零命令标志以便接收下一个命令
			if(RevBuffer[0]==0x10)	    //测试蜂鸣器
		    {
		    	RevBuffer[2]=RevBuffer[1];    //蜂鸣时间存到RevBuffer[2]
	  	    	cmd_ok();               //发送测试结果01 00给上位机
		    	TI=1;		                  //准备发给上位机数据
		    	SPEAKER=1;              //开蜂鸣器和指示灯
		        CARD_LED=ON;
				delay_10ms(RevBuffer[2]);    //延时
		    	SPEAKER=0;
                CARD_LED=OFF;              
 			    
		    }
	    	else if(RevBuffer[0]==0x11)   //串口参数设置,设置通讯波特率
	    	{
    			switch(RevBuffer[1])     
    			{
    				case 0:
	    				baud=BAUD_9600;
	    				break;
	    			case 1:
	    				baud=BAUD_14400;
		    			break;
	    			case 2:
	    				baud=BAUD_19200;
	    				break;
	    			case 3:
	    				baud=BAUD_28800;
	    				break;
	    			case 4:
	    				baud=BAUD_38400;
	    				break;
	    			case 5:
	    				baud=BAUD_57600;
	    				break;
	    			case 6:
	    				baud=BAUD_115200;
	    				break;
	    			default:
	    				baud=BAUD_19200;
	    				break;
	    		}				
	    		cmd_ok();	        //发送测试结果01 00给上位机
	    		TI=1;                    
	    		delay_10ms(5);			//延时设置波特率 
	    		TR1   = 0;
	    		TH1   = baud;
	    		TL1   = TH1;
	    		delay_10ms(2);
	    		TR1   = TRUE;
	    	}
	    	    	
       		else
    		{
     			uart_process();        // 进入串口处理程序	
    			TI=1;                 //处理完准备发送结果给上位机 
    		}
	
					                 		  			
	 			
			 }
		
	 }
}

///////////////////////////////////////////////////////////////////////
// 系统初始化
///////////////////////////////////////////////////////////////////////
void InitSystem(void)
{ 
    RC500CS=0;	            	//选中RC500
	RC500RST=0;	               //复位

	ET2 = FALSE; 	              // T/C2关中断
	T2CON = 0x04;		      //TR2=1,设为TIMER2,auto reload 
    PCON = 0x80;              
    SCON = 0x70;              // SMOD = 1;  
    TMOD = 0x21;              //TMOD = 0x22;

	TH1   = BAUD_19200;       //默认波特率
	TL1   = TH1;
	TR1   = TRUE;             // 以T1作为波特率发生器
    
	ET1=FALSE;
	IT0 =TRUE;    			// Config ext0 as edge trigger for RC500
    EX0 =TRUE; 			// Enable ext0 interrupt for RC500
    EA = TRUE;			// Enable all interrupts
	TR2=FALSE;                   //Close T2
	IP=0x10;			// 设串口中断高优先级
 	ES = TRUE;               //打开串口

	bCmd=FALSE;         //初始化为0,没有收到命令
					
	beep(1);          //开机喇叭和指示灯测试
    splash(1);
 	MfConfig();			//配置RC500    
   
  
}

///////////////////////////////////////////////////////////////////////
// 串口接收和发送中断
//数据包格式:数据包长度L(1byte)+命令字C(1byte)+数据包D(L-1 bytes)
//其中数据包长度是从命令字开始算起的。
///////////////////////////////////////////////////////////////////////
void Uart_Int(void) interrupt 4 using 1
{
    uchar len, i;
  	uint j=0;
 
  	if(RI)        //收到数据
	{	
		len=SBUF;  //第一个字节是数据包的长度
		RI=0;	   //清零RI以便接收下一个
		for(i=0;i<len;i++)
		{
			while(!RI)
			{
				j++;
				if(j>1000)
				{
				    break;
				}
			}
			if(j<1000)
			{
				RevBuffer[i]=SBUF;    
				RI=0;
				j=0;
			}
			else
			{
			    break;
			}
		}
		if(i==len)
		{
			REN=0;            // 清零接收位
			bCmd=TRUE;       //接收完毕,收到命令有效,置位1
		}
	}
	else if(!RI && TI)   //发送-RI=0,TI=1
	{
		TI=0;
		len=RevBuffer[0];    //发送的第一个字节是包的长度
		for(i=0;i<len+1;i++)
		{
			SBUF=RevBuffer[i];
			while(!TI);
			TI=0;			
		}
		REN=1;
	}
}
///////////////////////////////////////////////////////////////////////
// IC卡命令处理函数
///////////////////////////////////////////////////////////////////////
void uart_process(void)
{
	uchar cmd;
	uchar status;
	
	cmd = RevBuffer[0];
	switch(cmd)
	{		
				
		case 0x20:     // Request ,寻卡
			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=mifare1S70;       // Mifare1 S70 卡
			else if(RevBuffer[2]==4)
				cardtype=mifare1S50;       // Mifare1 S50 卡
			else if(RevBuffer[2]==16)
				cardtype=mifarelight;     // Mifare Light 卡
			else
				cardtype=unknowncard;
			RevBuffer[0]=3;	               // 返回3个字节:状态(1字节)+卡类型(2字节)
			RevBuffer[1]=status;
			break;
			
		case 0x21:                         // 防冲突 读卡的系列号 CardSnr
			status = M500PiccCascAnticoll(0,&RevBuffer[2]);
			if(status!=0)		//失败
			{
				RevBuffer[0]=1;
				RevBuffer[1]=status;
				break;
			}
			memcpy(CardSnr,&RevBuffer[2],4);   //读出4字节序列号
			RevBuffer[0]=5;          // 返回5个字节:状态(1字节)+序列号(4字节)                
			RevBuffer[1]=status;
			break;	
		case 0x22:		                    // 选择卡 Select Card
			status=M500PiccCascSelect(CardSnr,&RevBuffer[2]);
			if(status!=MI_OK)
			{
				RevBuffer[0]=1;	
				RevBuffer[1]=status;
				break;
			}

			RevBuffer[0]=3;
			RevBuffer[1]=status;            
			break;
		case 0x23:	    // Key loading into the MF RC500's EEPROM
		            // 校验卡密码(E2)
			status=M500PiccAuthE2(RevBuffer[1],CardSnr,RevBuffer[2],RevBuffer[3]);
			RevBuffer[0]=1;
			RevBuffer[1]=status;			
			break;							
		case 0x24:     // 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 0x25:     // Read the mifare card
		            // 读卡
			status=M500PiccRead(RevBuffer[1],&RevBuffer[2]);
			if(status==0)
			{
				if(cardtype==mifare1S50||cardtype==mifare1S70)
					RevBuffer[0]=17;
				else if(cardtype==1)
					RevBuffer[0]=9;
				else
					RevBuffer[0]=16;			
			}
			else
			{
			    RevBuffer[0]=1;
			}
			RevBuffer[1]=status;			
			break;
		case 0x26:     // Write the mifare card
		            // 写卡  下载密码
			status=M500PiccWrite(RevBuffer[1],&RevBuffer[2]);
			RevBuffer[0]=1;
			RevBuffer[1]=status;			
			break;
		case 0x27:    //钱包块值操作:加.减,
			status = M500PiccValue(RevBuffer[1],RevBuffer[2],&RevBuffer[3],RevBuffer[7]);
			RevBuffer[0]=1;	
			RevBuffer[1]=status;
			break;
		case 0x28:                  //终止卡的操作
			status=M500PiccHalt();			
			RevBuffer[0]=1;			//返回休眠卡的结果
			RevBuffer[1]=status;
			break;			
	   case 0x29:								//进入软件掉电模式
		    SetBitMask(RegControl,0x10);        // PowerDown = 1       
		    cmd_ok();	                    // 内部电流消耗模块包括晶振在内关闭
			break;
		case 0x30:								//退出软件掉电模式
		    ClearBitMask(RegControl,0x10);      // PowerDown = 0        
		    cmd_ok();
		    break;	
		default:						    	// 其余默认操作错误
			RevBuffer[0]=1;
			RevBuffer[1]=1;
		    break;		
	}
	
}

///////////////////////////////////////////////////////////////////////
//发送命令成功信号0100给上位机
///////////////////////////////////////////////////////////////////////
void cmd_ok(void)
{
	RevBuffer[0]=1;	
	RevBuffer[1]=0;
}
///////////////////////////////////////////////////////////////////////

/**********************RC500操作函数定义******************************/
///////////////////////////////////////////////////////////////////////
// 往一个地址写一个数据
///////////////////////////////////////////////////////////////////////
void WriteRawIO(uchar Address,uchar value)
{
	XBYTE[Address]=value;
}

///////////////////////////////////////////////////////////////////////
// 从一个地址读出一个数据
///////////////////////////////////////////////////////////////////////
uchar ReadRawIO(uchar Address)
{
	return XBYTE[Address];
}

///////////////////////////////////////////////////////////////////////
// G E N E R I C    W R I T E
// 往一个地址写一个数据(EEPROM)
///////////////////////////////////////////////////////////////////////
void WriteIO(uchar Address, uchar value)
{
    WriteRawIO(0x00,GetRegPage(Address));  
    WriteRawIO(Address,value);              
}

///////////////////////////////////////////////////////////////////////
//          G E N E R I C    R E A D
// 从一个地址读出一个数据(EEPROM)
///////////////////////////////////////////////////////////////////////
uchar ReadIO(uchar Address)
{
   WriteRawIO(0x00,GetRegPage(Address));
   return ReadRawIO(Address);                    
}  

///////////////////////////////////////////////////////////////////////
// 设置RC500定时时间
///////////////////////////////////////////////////////////////////////
void M500PcdSetTmo(uchar tmoLength)
{
    switch(tmoLength)
    {  
        case 1:                       
            WriteIO(RegTimerClock,0x07); 
            WriteIO(RegTimerReload,0x6a);
            break;
        case 2:                       
            WriteIO(RegTimerClock,0x07); 
            WriteIO(RegTimerReload,0xa0);
            break;
        case 3:  
            WriteIO(RegTimerClock,0x09); 
            WriteIO(RegTimerReload,0xa0);
            break;
        case 4: 
            WriteIO(RegTimerClock,0x09);
            WriteIO(RegTimerReload,0xff);
            break;
        case 5:  
            WriteIO(RegTimerClock,0x0b); 
            WriteIO(RegTimerReload,0xff);
            break;
        case 6:                       
            WriteIO(RegTimerClock,0x0d); 
            WriteIO(RegTimerReload,0xff);
            break;
        case 7:                      
            WriteIO(RegTimerClock,0x0f); 
            WriteIO(RegTimerReload,0xff);
            break;
        default:                       
            WriteIO(RegTimerClock,0x07); 
            WriteIO(RegTimerReload,tmoLength);
            break;
    }     
}

///////////////////////////////////////////////////////////////////////
// Request Command defined in ISO14443(Mifare)
///////////////////////////////////////////////////////////////////////
char  M500PcdCmd(uchar cmd,
               volatile uchar data *rcv,
                MfCmdInfo idata *info)
{
    char          idata status    = MI_OK;
    char          idata tmpStatus ;
    uchar idata lastBits;
    unsigned int  idata timecnt = 0;
    uchar idata irqEn = 0x00;
    uchar idata waitFor = 0x00;
    uchar idata timerCtl  = 0x00;

    WriteIO(RegInterruptEn,0x7F);			//Clear Int
    WriteIO(RegInterruptRq,0x7F);
    WriteIO(RegCommand,PCD_IDLE); 			// (0x00) No action: cancel current command

    FlushFIFO();     
    MpIsrInfo = info;  
    MpIsrOut = rcv;
    info->irqSource = 0x00;
    switch(cmd)
    {
        case PCD_IDLE:                
            irqEn = 0x00;
            waitFor = 0x00;
            break;
        case PCD_WRITEE2:            
            irqEn = 0x11;
            waitFor = 0x10;
            break;
        case PCD_READE2:     
            irqEn = 0x07;
            waitFor = 0x04;
            break;
        case PCD_LOADCONFIG:  
        case PCD_LOADKEYE2:   
        case PCD_AUTHENT1:    
            irqEn = 0x05;
            waitFor = 0x04;
            break;
        case PCD_CALCCRC:
            irqEn = 0x11;
            waitFor = 0x10;
            break;
        case PCD_AUTHENT2: 
            irqEn = 0x04;
            waitFor = 0x04;
            break;
        case PCD_RECEIVE:     
            info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
            irqEn = 0x06;
            waitFor = 0x04;
            break;
        case PCD_LOADKEY: 
            irqEn = 0x05;
            waitFor = 0x04;
            break;
        case PCD_TRANSMIT: 
            irqEn = 0x05;
            waitFor = 0x04;
            break;
        case PCD_TRANSCEIVE: 
	        info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
            irqEn = 0x3D;
            waitFor = 0x04;
            break;
        default:
            status = MI_UNKNOWN_COMMAND;
    }        
    if (status == MI_OK)
    {
        irqEn |= 0x20;                     
        waitFor |= 0x20;      
        timecnt=1000;
        WriteIO(RegInterruptEn,irqEn | 0x80); 

⌨️ 快捷键说明

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