RC522 讀卡器和寫卡器 讀寫測試程式----基於cc2530開發板

smilestone322發表於2015-12-29
RC522 寫卡器操作步驟:1)尋卡,2)防衝突;3)選卡;4)授權;5)寫操作;6)讀操作;具體步驟見原始碼,紅色的部分是我增加的程式碼,其它的都是開發板自帶的程式碼;
/****************************************************************************
* 文 件 名: main.c
* 描    述: 讀寫RFID
****************************************************************************/
#include <ioCC2530.h>
#include <string.h>
#include "LCD.h"
#include "mfrc522.h"

typedef unsigned char uchar;
typedef unsigned char uint8;
typedef unsigned int  uint;
typedef unsigned long ulong;


#define ON 0
#define OFF 1
#define LED1 P1_0 //定義P1.0口為LED1控制端
#define LED2 P1_1 //定義P1.1口為LED2控制端
#define LED3 P1_4 //定義P1.4口為LED3控制端

#define BUZZER_PIN  P0_7   //蜂鳴器控制腳


#define KEY1  0x01
#define KEY2  0x02

//M1卡的某一塊寫為如下格式,則該塊為錢包,可接收扣款和充值命令
//4位元組金額(低位元組在前)+4位元組金額取反+4位元組金額+1位元組塊地址+1位元組塊地址取反+1位元組塊地址+1位元組塊地址取反 
unsigned char data2[4]  = {0x12,0,0,0};
unsigned char DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 
unsigned char g_ucTempbuf[20];    
unsigned char MLastSelectedSnr[4];
unsigned char RevBuffer[30];  
unsigned char SerBuffer[20]; 
unsigned char CmdValid; 
unsigned char waitCommData=1;
int data_len=0;
int data_index=0;

/****************************************************************************
* 名    稱: InitLed()
* 功    能: 設定LED燈相應的IO口
* 入口引數: 無
* 出口引數: 無
****************************************************************************/
void InitLed(void)
{
  P1DIR |= 0x13; //P1.0、P1.1、p1.4定義為輸出
  LED1 = 1; //預設LED燈為熄滅狀態
  LED2 = 1;
  LED3 = 1;
  
  P0_7=1;
}

void InitUart0(void)
{
    PERCFG  &= ~ 0x01;           //外設控制暫存器 USART 0的IO位置:0為P0口位置1 
    P0SEL = 0x0c;            //P0_2,P0_3用作串列埠(外設功能)
    P2DIR &= ~0xC0;          //P0優先作為UART0
    
    U0CSR |= 0x80;           //設定為UART方式
    U0GCR |= 11;				       
    U0BAUD |= 216;           //波特率設為115200

    UTX0IF = 0;              //UART0 TX中斷標誌初始置位0
    U0CSR |= 0x40;           //允許接收 
    IEN0 |= 0x84;            //開總中斷允許接收中斷  
}


/****************************************************************************
* 名    稱: UART0_ISR(void) 串列埠中斷處理函式 
* 描    述: 當串列埠0產生接收中斷,將收到的資料儲存在RxBuf中
****************************************************************************/
#pragma vector = URX0_VECTOR 
__interrupt void UART0_ISR(void) 
{
    unsigned char bbb=U0DBUF;

    URX0IF=0;
	if(waitCommData>0)
	{
		waitCommData=0;
		data_len=U0DBUF;
		data_index=0;
		memset(RevBuffer, 0, sizeof(RevBuffer));
	}
	else
	{
		RevBuffer[data_index]=U0DBUF;
		data_index++;

		if(data_len==data_index)
		{
			U0CSR &= ~0x40;                    //禁止接收 
			CmdValid=1;

			waitCommData=1;
                        
                        U0CSR |= 0x40;
		}
	}
}


void Uart0SendString(char *Data, int len)
{
	uint i;
	for(i=0; i<len; i++)
	{
		U0DBUF = *Data++;
		while(UTX0IF == 0);
		UTX0IF = 0;
	}
}


void InitClockTo32M(void)
{   
    CLKCONCMD &= ~0x40;              //設定系統時鐘源為 32MHZ晶振
    while(CLKCONSTA & 0x40);         //等待晶振穩定 
    CLKCONCMD &= ~0x47;              //設定系統主時脈頻率為 32MHZ
}

void iccardcode()
{	     
  	unsigned char cmd;
	unsigned char status;
	
	cmd = RevBuffer[0];
	switch(cmd)
 	{
		case 1:     // Halt the card     //終止卡的操作
			status= PcdHalt();;			
			RevBuffer[0]=1;
			RevBuffer[1]=status;
			break;			
		case 2:     // Request,Anticoll,Select,return CardType(2 bytes)+CardSerialNo(4 bytes)
			        // 尋卡,防衝突,選擇卡    返回卡型別(2 bytes)+ 卡系列號(4 bytes)
			status= PcdRequest(RevBuffer[1],&RevBuffer[2]);
			if(status!=0)
			{
				status= PcdRequest(RevBuffer[1],&RevBuffer[2]);
				if(status!=0)				
				{
					RevBuffer[0]=1;	
					RevBuffer[1]=status;
					break;
				}
			}  
			RevBuffer[0]=3;	
			RevBuffer[1]=status;
			break;
			
		case 3:                         // 防衝突 讀卡的系列號 MLastSelectedSnr
			status = PcdAnticoll(&RevBuffer[2]);
			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=PcdSelect(MLastSelectedSnr);
			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
            status = PcdAuthState(RevBuffer[1], RevBuffer[3], DefaultKey, MLastSelectedSnr);// 校驗卡密碼
			RevBuffer[0]=1;
			RevBuffer[1]=status;			
			break;							
		case 6: 
			RevBuffer[0]=1;
			RevBuffer[1]=status;			
			break;				
		case 7:     
    		RevBuffer[0]=1;
			RevBuffer[1]=status;			
			break;
		case 8:     // Read the mifare card
		            // 讀卡
			status=PcdRead(RevBuffer[1],&RevBuffer[2]);
			if(status==0)
			{RevBuffer[0]=17;}
			else
			{RevBuffer[0]=1;}
			RevBuffer[1]=status;			
			break;
		case 9:     // Write the mifare card
		            // 寫卡  下載密碼
			status=PcdWrite(RevBuffer[1],&RevBuffer[2]);
			RevBuffer[0]=1;
			RevBuffer[1]=status;			
			break;
		case 10:
            PcdValue(RevBuffer[1],RevBuffer[2],&RevBuffer[3]);
			RevBuffer[0]=1;	
			RevBuffer[1]=status;
			break;
		case 12:    // 引數設定
		    PcdBakValue(RevBuffer[1], RevBuffer[2]);
			RevBuffer[0]=1;	//contact
			RevBuffer[1]=0;
			break;		
	}
}


/////////////////////////////////////////////////////////////////////
//系統初始化
/////////////////////////////////////////////////////////////////////
void InitializeSystem()
{
    //P0_4、P0_5、P0_6、p1_0和p1_1用於控制RFID
    //P0_7用於控制蜂鳴器  
  
    P0DIR |= 0xF0; //P0_4、P0_5、P0_6、P0_7定義為輸出
    P1DIR |= 0x03;//p1_0、p1_1輸出
    
    P0 |= 0xF0; //P0_4、P0_5、P0_6、P0_7輸出1
    P1 |= 0x03; //P1_0輸出高電平

    
    
	CmdValid=0; 
    
    PcdReset();
    PcdAntennaOff(); 
    PcdAntennaOn();  
    M500PcdConfigISOType( 'A' );
    
    delay_10ms(10);
	LED2=OFF;
    delay_10ms(10);
}

//BCD碼轉成ASC碼
char NumberToLetter(unsigned char number)
{
	char buff[]="0123456789ABCDEF";

	if(number>15) return 0;

	return buff[number];

}

//蜂鳴器響兩聲
void buzzerOn()
{
    BUZZER_PIN=0;
    DelayMS(200);
    BUZZER_PIN=1;
    DelayMS(50);
    BUZZER_PIN=0;
    DelayMS(200);
    BUZZER_PIN=1;
}

void main(void)
{
    uint8 SendBuf[10]={0};
    uint8 error=0;    

	InitLed();
	InitializeSystem();
	InitClockTo32M();
	InitUart0();
    LCD_Init();
    LCD_CLS();
    LCD_P8x16Str(20, 0, "SZ_YY RFID");

    //週期地在尋卡
	while (1)
	{
        //尋卡命令
        RevBuffer[0]=0x02;
        RevBuffer[1]=0x26;

         // 尋卡
        iccardcode();
        
        error=0;
        if(RevBuffer[1]==0)//尋卡成功
        {
            //讀卡命令
            SendBuf[0]=RevBuffer[2];  //data
            SendBuf[1]=RevBuffer[3];  //data        

            //找到卡
            //讀卡
            RevBuffer[0]=0x03;
            iccardcode();

            if(RevBuffer[1]==0)
            {
                //讀卡成功
                //記錄卡ID
                SendBuf[2]=RevBuffer[2];  //data
                SendBuf[3]=RevBuffer[3];  //data
                SendBuf[4]=RevBuffer[4];  //data
                SendBuf[5]=RevBuffer[5];  //data
            }
            else
            {
                error=1;
            }
        }
        else
        {
            error=1;
        }        

        if(error==0)
        {
              char card_buff[20]={0};
              
              
              //各種卡的含義
              //                0x4400 = Mifare_UltraLight
              //                0x0400 = Mifare_One(S50)
              //                0x0200 = Mifare_One(S70)
              //                0x0800 = Mifare_Pro(X)
              //                0x4403 = Mifare_DESFire
  
              if(SendBuf[0]==0x44 && SendBuf[1]==0x00)
              {
                  LCD_P8x16Str(0, 2, "Mifare_UltraLight");
                  Uart0SendString((uint8 *)"Mifare_UltraLight", strlen("Mifare_UltraLight"));
              }
              else if(SendBuf[0]==0x04 && SendBuf[1]==0x00)
              {
                  LCD_P8x16Str(0, 2, "Mifare_One(S50)");
                  Uart0SendString((uint8 *)"Mifare_One(S50)", strlen("Mifare_One(S50)"));
              }
              else if(SendBuf[0]==0x02 && SendBuf[1]==0x00)
              {
                  LCD_P8x16Str(0, 2, "Mifare_One(S70)");
                  Uart0SendString((uint8 *)"Mifare_One(S70)", strlen("Mifare_One(S70)"));
              }
              else if(SendBuf[0]==0x08 && SendBuf[1]==0x00)
              {
                  LCD_P8x16Str(0, 2, "Mifare_One(X)");
                  Uart0SendString((uint8 *)"Mifare_One(X)", strlen("Mifare_One(X)"));
              }
              else if(SendBuf[0]==0x44 && SendBuf[1]==0x03)
              {
                  LCD_P8x16Str(0, 2, "Mifare_DESFire");
                  Uart0SendString((uint8 *)"Mifare_DESFire", strlen("Mifare_DESFire"));
              }
              else
              {
                  error=1;
                  LCD_P8x16Str(0, 2, "");
                  LCD_P8x16Str(0, 4, "");
                  Uart0SendString((uint8 *)"find error", strlen("find error"));
              }
              Uart0SendString((uint8 *)"\r\n", 2);
              
              
              /*
              card_buff[0]='I';
              card_buff[1]='D';
              card_buff[2]=':';
              
              //BCD轉ASC碼
              //ID輪換
              for(int i=0; i<4; i++)
              {
                  unsigned char temp= SendBuf[2+i];
                  card_buff[3+i*2]=NumberToLetter((temp>>4)&0x0f);
                  card_buff[3+i*2+1]=NumberToLetter(temp&0x0f);
              }

              //LCD顯示ID
              LCD_P8x16Str(0, 4,card_buff);
              
              //串列埠輸出ID
              Uart0SendString(card_buff, strlen(card_buff));
              Uart0SendString((uint8 *)"\r\n", 2);

              //蜂鳴器提示
              buzzerOn();
              */
              
             <span style="color:#ff0000;"> //選擇卡
              RevBuffer[0]=0x04;
              iccardcode();
                   
              //授權
              RevBuffer[0]=0x05;
              RevBuffer[1]=0x60;
              RevBuffer[3]=0x06;
              iccardcode();
             
              
             if(RevBuffer[1]==0)
              {
                  //授權成功,進行寫操作
                  //mifire卡寫卡
                  RevBuffer[0]=0x09;
                  RevBuffer[1]=0x06;
                  
                  for(int j=0;j<16;j++)
                  {
                      RevBuffer[j+2]=j;
                  }
                  
                  iccardcode();
                  
                  //mifire 卡讀卡;
                  RevBuffer[0]=0x08;
                  RevBuffer[1]=0x06;
                  
                  //清空快取區
                  for(int j=0;j<16;j++)
                  {
                      RevBuffer[j+2]=0;
                  }
                  
                  iccardcode();
                  //LCD顯示讀到的資料
                  
                  for(int i=0; i<8; i++)
                  {
                    unsigned char temp= RevBuffer[2+i];
                    card_buff[i*2]=NumberToLetter((temp>>4)&0x0f);
                    card_buff[i*2+1]=NumberToLetter(temp&0x0f);
                  }
         
                  LCD_P8x16Str(0, 4,card_buff);
                  Uart0SendString((uint8 *)"\r\n", 2);
</span>              }     
        }
        else
        {
            //尋不到卡
            LCD_P8x16Str(0, 2,"                ");
            LCD_P8x16Str(0, 4,"                ");
        }
        
        DelayMS(500);
	}    
}


 

 

相關文章