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
相关单片机程序如下
rc522.h
http://download.csdn.net/detail/songqqnew/3716567
如下,左边是单片机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