rfid1-stc11f32x

淘宝上买了一个rfid板,
如下,左边是单片机stc11f32x,右边是rfid小板

射频小板的主控芯片是rc522,可读iso 14443 type a卡,比如s50卡,店主送了两张。简介一下s50卡吧,

注:ICC(Integrated Circuit Card)为集成电路卡,CD(Coupling Device)指读写设备

s50卡的eeprom共16扇区;每扇区4块,共64块;每块16字节,则每扇区16x4=64字节,每卡64x16=1024字节,如下


所有块统一编址,每扇区的尾块是控制块,其余为数据块,但扇区1的块0特殊一点,记录了厂家序列号之类的,只读。
本例将数据存入扇区1的块4。对某扇区进行读写需要通过密码验证,密码保存在该扇区的控制块中。

先看连线,如下,左边是单片机右边是rc522的接口,rc522支持spi i2c 串口,但是stc11f32x却没有这些接口,所以stc11f32x只能模拟spi时序与rc522通讯,模拟用的引脚是
P0.5  MF_SDA(NSS片选)
P0.6  MF_SCK(时钟)
P0.7  MF_MOSI
P4.1  MF_MISO
P2.7  MF_RST



相关单片机程序如下
void InitRc522(void)//初始化rc522
{
  PcdReset();
  PcdAntennaOff();  
  PcdAntennaOn();
  M500PcdConfigISOType( 'A' );
}
void InitAll(void)
{
  Dlms(100);
  InitPort();
  Dlms(100);
  InitLcd0108();
  InitRc522();
  EA=0;
  init_time0();
  uart_init();
  EA=1; //re-enable interrupts  
  TimeShowMenu=0;
  bShowMenu=0;
//  bShowTime=1;
  bWarn=0;
  bPass=0;
  SysTime=0;
  KeyTime=0;
  KeyNum=0;
  bTimed=1;
  bMenued=0; 
  bShowWelcome=1; 
  TimeShowMenu=250;
}


void ctrlprocess(void)
{
  float data money_value;
//  unsigned char ConsumedData;
  unsigned char data ii;
  char data status;
  status=PcdRequest(PICC_REQIDL,&RevBuffer[0]);//寻天线区内未进入休眠状态的卡,返回卡片类型 2字节
  if(status!=MI_OK)
  {
    return;
  }
  status=PcdAnticoll(&RevBuffer[2]);//防冲撞,返回卡的序列号 4字节
  if(status!=MI_OK)
  {
    return;
  }
  if(!bShowMenu)
  {
    bShowMenu=1;
    //bShowWelcome=0;
      bTimed=0;
      bMenued=1;    
    ShowMenu();
  }
  TimeShowMenu=0;
  //Clear88(0,5,2,8);
  Clear88(2,5,2,8);
  Clear88(4,5,2,8);
  //Clear88(6,5,2,8);
  memcpy(MLastSelectedSnr,&RevBuffer[2],4);
  for(ii=0;ii<4;ii++)
  {
    Show816(0,5+2*ii,(MLastSelectedSnr[ii]>>4)&0x0f);
    Show816(0,6+2*ii,MLastSelectedSnr[ii]&0x0f);
  } 
  status=PcdSelect(MLastSelectedSnr);//选卡
  if(status!=MI_OK)
  {
    return;
  }
  if(oprationcard==REGCARD)//注册
  {
    status=PcdAuthState(PICC_AUTHENT1A,7,LastKeyA,MLastSelectedSnr);//????KUAI4?
    //DelayNS(1);
    if(status!=MI_OK)
    {
      bWarn=1;
      return;
    }
    status=PcdWrite(7,&NewKey[0]);
    if(status!=MI_OK)
    {
      bWarn=1;
      return;
    }
    for(ii=0;ii<16;ii++)
    {
      Write_First_Data[ii]=0xaa;
    }
    status=PcdWrite(4,&Write_First_Data[0]);
    if(status!=MI_OK)
    {
      bWarn=1;
      return;
    }
    bPass=1;						
    PcdHalt();		
  }
  else if(oprationcard==READCARD)//读卡
  {
    status=PcdAuthState(PICC_AUTHENT1A,7,NewKeyA,MLastSelectedSnr);//????KUAI4?
    if(status!=MI_OK)
    {
      return;
    }
    status=PcdRead(4,Read_Data);
    if(status!=MI_OK)
    {
      bWarn=1;
      return;
    }


	    for(ii=0;ii<16;ii++)
    {
      Write_First_Data[ii]=0xaa;
    }
    status=PcdWrite(4,&Write_First_Data[0]);



    for(ii=0;ii<4;ii++)
    {
      fltchr.chr[ii]=Read_Data[ii];
	  	  sendchar1(fltchr.chr[ii]);
    }		
    //ShowFloat816(4,5,fltchr.flt); 
	ShowFloat816(4,5,fltchr.flt); 
    if(fltchr.flt<0)
    {
      bWarn=1;
    }  
    bPass=1;
    PcdHalt();	
  }
  else if(oprationcard==CONSUME)//消费
  {
    status=PcdAuthState(PICC_AUTHENT1A,7,NewKeyA,MLastSelectedSnr);//????KUAI4?
    if(status!=MI_OK)
    {
      return;
    }
    status=PcdRead(4,Read_Data);
    if(status!=MI_OK)
    {
      bWarn=1;
      return;
    }
    for(ii=0;ii<4;ii++)		  //////////////////
    {
      fltchr.chr[ii]=Read_Data[ii];
	  sendchar1(fltchr.chr[ii]);

    }
    money_value=fltchr.flt;
    if(money_value<-100)
    {
      money_value=-100;
    }
    if(money_value<0)
    {
      money_value+=100;
    }
    fltchr.flt=money_value-2.5;
    for(ii=0;ii<4;ii++)
    {
      Write_Consume_Data[ii]=fltchr.chr[ii];
    }
    status=PcdWrite(4,&Write_Consume_Data[0]);


	    for(ii=0;ii<4;ii++)		////////////////////////
    {
	  sendchar1(fltchr.chr[ii]);

    }




    if(status!=MI_OK)
    {
      bWarn=1;
      return;
    }		
    ShowFloat816(2,5,2.58);
    ShowFloat816(4,5,fltchr.flt); 
    if(fltchr.flt<0)
    {
      bWarn=1;
    }  
    else
    { 
      bPass=1;
    }
    PcdHalt();	
  }
  else if(oprationcard==ADDMONEY)//充值
  {
    status=PcdAuthState(PICC_AUTHENT1A,7,NewKeyA,MLastSelectedSnr);//????KUAI4?
    if(status!=MI_OK)
    {
      return;
    }
    status=PcdRead(4,Read_Data);
    if(status!=MI_OK)
    {
      bWarn=1;
      return;
    }
    for(ii=0;ii<4;ii++)
    {
      fltchr.chr[ii]=Read_Data[ii];
    }
    money_value=fltchr.flt;
    if(money_value<-100)
    {
      money_value=-100;
    }
    if(money_value<0)
    {
      money_value+=100;
    }
    fltchr.flt=money_value+50;
    for(ii=0;ii<4;ii++)
    {
      Write_Consume_Data[ii]=fltchr.chr[ii];
    }
    //status=PcdWrite(4,&Write_Consume_Data[0]);

    for(ii=0;ii<16;ii++)		//向块4写入初始数值
    {
      Write_First_Data[ii]=0xaa;
    }
    status=PcdWrite(4,&Write_First_Data[0]); //



    if(status!=MI_OK)
    {
      bWarn=1;
      return;
    }		
    ShowFloat816(2,5,50.00);
    ShowFloat816(4,5,fltchr.flt); 
    bPass=1;
    PcdHalt();	
  }
  /*else
  {
    status=PcdAuthState(PICC_AUTHENT1A,7,NewKeyA,MLastSelectedSnr);//????KUAI4?
    if(status!=MI_OK)
    {
      return;
    }
    status=PcdRead(4,Read_Data);
    if(status!=MI_OK)
    {
      return;
    }
    for(ii=0;ii<4;ii++)
    {
      fltchr.chr[ii]=Read_Data[ii];
    }		
    ShowFloat816(4,5,fltchr.flt); 
    PcdHalt();	
  }*/  					
}

void Warn(void)
{
  uchar data ii;
  for(ii=0;ii<3;ii++)
  {
    SET_BEEP;
    delay_ms(120);
    CLR_BEEP;
    delay_ms(120);
  }
}



void main(void)
{
    InitAll();//其中调用InitRc522(),通过模拟spi输出数据初始化rfid模块
    #pragma ASM
    SETB P3.5
    NOP
    #pragma ENDASM       
  oprationcard=CONSUME;
  //刚一上电,是消费模式。之后通过按键可以改变模式,并保存在oprationcard变量中
  while(1)
  {
    KeyNum=GetKey();
    // sendchar1(1);
    if(bMenued)
   {
    if( (KeyNum==N_1)&&(!KeyTime) )
    //if(!keytime)<=>if(keytime==0)    
    //当第一次按下k1时,keytime=0,所以执行之
    //当第二次按下k1时, 如果此时距第一次按下k1的时间在15个time溢出周期内,不会执行之。否则执行之,
    {
      KeyTime=15;
      TimeShowMenu=0;  //卡片放在上面,从没有任何按键操作算起,超过250个time溢出周期,则会进入welcom页面,相当于待机时间
      oprationcard=CONSUME;
      sendchar1(KeyNum);
      ShowHZ1616(2,0,4); //消  
      ShowHZ1616(2,2,5); //费        
    }
    else if( (KeyNum==N_2)&&(!KeyTime) )
    {
      KeyTime=15;
      TimeShowMenu=0;
      oprationcard=ADDMONEY;
      sendchar1(KeyNum);
      ShowHZ1616(2,0,6); //充值 
      ShowHZ1616(2,2,7); //       
    }
    else if( (KeyNum==N_3)&&(!KeyTime) )
    {
      KeyTime=15;
      TimeShowMenu=0;
      oprationcard=REGCARD;
      sendchar1(KeyNum);
      ShowHZ1616(2,0,10); //注册 
      ShowHZ1616(2,2,11); //       
    } 
    else if( (KeyNum==N_4)&&(!KeyTime) )
    {
      KeyTime=15;
      TimeShowMenu=0;
      oprationcard=READCARD;
      sendchar1(KeyNum);
     // sendchar1(55);
      ShowHZ1616(2,0,12); //读卡
      ShowHZ1616(2,2,13); //       
    }  
   
   }      
    if(bShowWelcome)
    {
      bShowWelcome=0;
      bTimed=1;
      bMenued=0;
      ShowWelcome();  
    }
    if(bWarn)
    {
      bWarn=0;
      Warn();
    }
    if(bPass)
    {
      bPass=0;
      Pass();
    }
    ctrlprocess();//rc522寻卡读写等函数


  }  
}

rc522.h
/////////////////////////////////////////////////////////////////////
//MF522命令字
/////////////////////////////////////////////////////////////////////
#define PCD_IDLE              0x00               //取消当前命令
#define PCD_AUTHENT           0x0E               //验证密钥
#define PCD_RECEIVE           0x08               //接收数据
#define PCD_TRANSMIT          0x04               //发送数据
#define PCD_TRANSCEIVE        0x0C               //发送并接收数据
#define PCD_RESETPHASE        0x0F               //复位
#define PCD_CALCCRC           0x03               //CRC计算

/////////////////////////////////////////////////////////////////////
//Mifare_One卡片命令字
/////////////////////////////////////////////////////////////////////
#define PICC_REQIDL           0x26               //寻天线区内未进入休眠状态
#define PICC_REQALL           0x52               //寻天线区内全部卡
#define PICC_ANTICOLL1        0x93               //防冲撞
#define PICC_ANTICOLL2        0x95               //防冲撞
#define PICC_AUTHENT1A        0x60               //验证A密钥
#define PICC_AUTHENT1B        0x61               //验证B密钥
#define PICC_READ             0x30               //读块
#define PICC_WRITE            0xA0               //写块
#define PICC_DECREMENT        0xC0               //扣款
#define PICC_INCREMENT        0xC1               //充值
#define PICC_RESTORE          0xC2               //调块数据到缓冲区
#define PICC_TRANSFER         0xB0               //保存缓冲区中数据
#define PICC_HALT             0x50               //休眠

/////////////////////////////////////////////////////////////////////
//MF522 FIFO长度定义
/////////////////////////////////////////////////////////////////////
#define DEF_FIFO_LENGTH       64                 //FIFO size=64byte
#define MAXRLEN  18

/////////////////////////////////////////////////////////////////////
//MF522寄存器定义
/////////////////////////////////////////////////////////////////////
// PAGE 0
#define     RFU00                 0x00    
#define     CommandReg            0x01    
#define     ComIEnReg             0x02    
#define     DivlEnReg             0x03    
#define     ComIrqReg             0x04    
#define     DivIrqReg             0x05
#define     ErrorReg              0x06    
#define     Status1Reg            0x07    
#define     Status2Reg            0x08    
#define     FIFODataReg           0x09
#define     FIFOLevelReg          0x0A
#define     WaterLevelReg         0x0B
#define     ControlReg            0x0C
#define     BitFramingReg         0x0D
#define     CollReg               0x0E
#define     RFU0F                 0x0F
// PAGE 1     
#define     RFU10                 0x10
#define     ModeReg               0x11
#define     TxModeReg             0x12
#define     RxModeReg             0x13
#define     TxControlReg          0x14
#define     TxAutoReg             0x15
#define     TxSelReg              0x16
#define     RxSelReg              0x17
#define     RxThresholdReg        0x18
#define     DemodReg              0x19
#define     RFU1A                 0x1A
#define     RFU1B                 0x1B
#define     MifareReg             0x1C
#define     RFU1D                 0x1D
#define     RFU1E                 0x1E
#define     SerialSpeedReg        0x1F
// PAGE 2    
#define     RFU20                 0x20  
#define     CRCResultRegM         0x21
#define     CRCResultRegL         0x22
#define     RFU23                 0x23
#define     ModWidthReg           0x24
#define     RFU25                 0x25
#define     RFCfgReg              0x26
#define     GsNReg                0x27
#define     CWGsCfgReg            0x28
#define     ModGsCfgReg           0x29
#define     TModeReg              0x2A
#define     TPrescalerReg         0x2B
#define     TReloadRegH           0x2C
#define     TReloadRegL           0x2D
#define     TCounterValueRegH     0x2E
#define     TCounterValueRegL     0x2F
// PAGE 3      
#define     RFU30                 0x30
#define     TestSel1Reg           0x31
#define     TestSel2Reg           0x32
#define     TestPinEnReg          0x33
#define     TestPinValueReg       0x34
#define     TestBusReg            0x35
#define     AutoTestReg           0x36
#define     VersionReg            0x37
#define     AnalogTestReg         0x38
#define     TestDAC1Reg           0x39  
#define     TestDAC2Reg           0x3A   
#define     TestADCReg            0x3B   
#define     RFU3C                 0x3C   
#define     RFU3D                 0x3D   
#define     RFU3E                 0x3E   
#define     RFU3F		  		  0x3F

/////////////////////////////////////////////////////////////////////
//和MF522通讯时返回的错误代码
/////////////////////////////////////////////////////////////////////
#define 	MI_OK                 0
#define 	MI_NOTAGERR           (-1)
#define 	MI_ERR                (-2)

#define	SHAQU1	0X01
#define	KUAI4	0X04
#define	KUAI7	0X07
#define	REGCARD	0xa1
#define	CONSUME	0xa2
#define READCARD	0xa3
#define ADDMONEY	0xa4


sbit  spi_cs=P0^5;
sbit  spi_ck=P0^6;
sbit  spi_mosi=P0^7;
sbit  spi_miso=P4^1;
sbit  spi_rst=P2^7;


#define SET_SPI_CS  spi_cs=1
#define CLR_SPI_CS  spi_cs=0

#define SET_SPI_CK  spi_ck=1
#define CLR_SPI_CK  spi_ck=0

#define SET_SPI_MOSI  spi_mosi=1
#define CLR_SPI_MOSI  spi_mosi=0

#define STU_SPI_MISO  spi_miso

#define SET_RC522RST  spi_rst=1
#define CLR_RC522RST  spi_rst=0

http://download.csdn.net/detail/songqqnew/3716567

posted on 2011-10-23 09:06  _song  阅读(535)  评论(0编辑  收藏  举报