TIDZ-RC522读卡模块使用说明
RC522
本文设计的读卡器系统以PICl6F7x单片机作为主控芯片,选用MIFARE S50卡片,读卡器与卡片间以106kbps速率通信,同时实现读卡过程中的防冲突处理和对卡E2PROM块内容的读/写等功能。
读卡器内部设置了FLASH存储器以存放卡数据,在FLASH容量满的情况下可通过读卡器的以太网口读出全部数据到管理中心上位机,便于建立对卡数据的综合管理系统。
1 硬件系统设计读卡器硬件框图如图1所示。
单片机PICl6F7x通过SPI总线与RC522和FLASH芯片AT45D011相连,同时用简化的ISA 总线连接以太网接口芯片C58900,以提供连接到局域网的能力。
AT45D0ll存储容量为lMb,可同时存储7400多组MIFARE的E2PROM块和UID号,提供了足够读卡器一天内读取的信息量的存放容量。
对于RC522天线部分的设计,PHILIPS公司有专门的手册详细介绍,本文不再赘述。
RC522的SPI总线接口有其自身的时序要求。
它只能工作于从模式,最高传输速率为10 Mbps,数据与时钟相位关系满足“空闲态时钟为低电平,在时钟上升沿同步接收和发送数据,在下降沿数据转换”的约束关系。
PICl6F7x系列单片机的片上外设包括1个SSP模块。
该模块可配置为SPI接口使用,通过相应的寄存器可控制SPI接口的数据传输率、数据一时钟相位天系等通信参数。
本文中配置SSP模块工作于SPI主模式下,时钟为1/4单片机主频,接收和发送数据都在时钟上升沿发生。
需要注意的是,由于RC522支持的数字接口形式多种多样,因此芯片在每次复位时都会检测外部引脚连接关系。
对于SPI接口,RC522的相关引脚必须按照图2所示的连接关系配置。
除了通用的4条SPI信号线(时钟线SCK、输入数据线MOSI、输出数据线MOSO和选通线NSS)以外,RC522要求额外的2个引脚I2C和EA分别固定接低电平和高电平。
这2个引脚不参与SPI总线传输,只起设定RC522数字界面采用SPI接口的作用。
STM8-RC522-读写IC卡程序
#include "stm8s.h"#include "uart.h"void Delay(u32 nCount);extern u8 RxBuffer[RxBufferSize];extern u8 UART_RX_NUM;unsigned char CT[2];//卡类型unsigned char SN[4]; //卡号unsigned char write[16] ={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10}; unsigned char read[16] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; unsigned char key[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};#define countof(a) (sizeof(a) / sizeof(*(a)))#define BufferSize (countof(Tx_Buffer)-1)u8 Tx_Buffer[] = "STM8S RFID TEST";u8 Rx_Buffer[BufferSize];u32 FLASH_ID ;void cardNo2String(u8 *cardNo, u8 *str);void main(void){unsigned char status;/*设置内部时钟16M为主时钟*/CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);status = memcmp(read,write,16);GPIO_DeInit(GPIOA);GPIO_DeInit(GPIOC);Uart_Init();GPIO_Init( GPIOA, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST);InitRc522();UART2_SendString(Tx_Buffer,BufferSize);while(1){status = PcdRequest(PICC_REQALL,CT); /*扫描卡*/status = PcdAnticoll(SN); /*防冲撞*/if (status==MI_OK){GPIO_LOW(GPIOA, GPIO_PIN_4); //寻卡成功UART2_SendString("The card Id is:",15); //串口发送卡号cardNo2String(SN, Tx_Buffer);UART2_SendString(Tx_Buffer, 17);Reset_RC522();}else{GPIO_HIGH(GPIOA, GPIO_PIN_4);}}}void Delay(u32 nCount){while (nCount != 0){nCount--;}}void Hex2String(u8 hex,u8 *str){str[0] = (hex / 100) + '0';str[1] = (hex % 100 / 10) + '0';str[2] = (hex % 10) + '0';}void cardNo2String(u8 *cardNo, u8 *str){u8 Count = 0;for(Count = 0; Count < 4; Count++){Hex2String(cardNo[Count], str + Count * 4);if(Count == 3){str[15] = '\n';}else{str[Count * 4 + 3] = ':';}}}void delay_ns(u32 ns){u32 i;for(i=0;i<ns;i++){asm("nop");asm("nop");asm("nop");}}u8 SPIWriteByte(u8 Byte){u8 tmp;while (SPI_GetFlagStatus( SPI_FLAG_TXE) == RESET); SPI_SendData(Byte);if (SPI_GetFlagStatus(SPI_FLAG_RXNE)){tmp = SPI_ReceiveData();}return tmp;}void SPI2_Init(void){SPI_DeInit();SPI_Init(SPI_FIRSTBIT_MSB, //帧模式,先发送MSB还是LSBSPI_BAUDRATEPRESCALER_8, //波特率分频值SPI_MODE_MASTER, //模式,主从模式SPI_CLOCKPOLARITY_LOW, //时钟极性,空闲时SCK为高/空闲时SCK为低SPI_CLOCKPHASE_1EDGE, //数据采样的边沿选择SPI_DATADIRECTION_2LINES_FULLDUPLEX, //双线单向数据模式,使用C6/C7两条线,数据传输方向位单向SPI_NSS_SOFT, //软件从设备0x07);SPI_Cmd(ENABLE);}void InitRc522(void){SPI2_Init();PcdReset();PcdAntennaOff();PcdAntennaOn();M500PcdConfigISOType( 'A' );}void Reset_RC522(void){PcdReset();PcdAntennaOff();PcdAntennaOn();}///////////////////////////////////////////////////////////////////////功能:寻卡//参数说明: req_code[IN]:寻卡方式// 0x52 = 寻感应区内所有符合14443A标准的卡// 0x26 = 寻未进入休眠状态的卡// pTagType[OUT]:卡片类型代码// 0x4400 = Mifare_UltraLight// 0x0400 = Mifare_One(S50)// 0x0200 = Mifare_One(S70)// 0x0800 = Mifare_Pro(X)// 0x4403 = Mifare_DESFire//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdRequest(u8 req_code,u8 *pTagType){char status;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ClearBitMask(Status2Reg,0x08);WriteRawRC(BitFramingReg,0x07);SetBitMask(TxControlReg,0x03);ucComMF522Buf[0] = req_code;status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x10)){*pTagType = ucComMF522Buf[0];*(pTagType+1) = ucComMF522Buf[1];}else{ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:防冲撞//参数说明: pSnr[OUT]:卡片序列号,4字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdAnticoll(u8 *pSnr){char status;u8 i,snr_check=0;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ClearBitMask(Status2Reg,0x08);WriteRawRC(BitFramingReg,0x00);ClearBitMask(CollReg,0x80);ucComMF522Buf[0] = PICC_ANTICOLL1;ucComMF522Buf[1] = 0x20;status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);if (status == MI_OK){for (i=0; i<4; i++){*(pSnr+i) = ucComMF522Buf[i];snr_check ^= ucComMF522Buf[i];}if (snr_check != ucComMF522Buf[i]){ status = MI_ERR; }}SetBitMask(CollReg,0x80);return status;}///////////////////////////////////////////////////////////////////////功能:选定卡片//参数说明: pSnr[IN]:卡片序列号,4字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdSelect(u8 *pSnr){char status;u8 i;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_ANTICOLL1;ucComMF522Buf[1] = 0x70;ucComMF522Buf[6] = 0;for (i=0; i<4; i++){ucComMF522Buf[i+2] = *(pSnr+i);ucComMF522Buf[6] ^= *(pSnr+i);}CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);ClearBitMask(Status2Reg,0x08);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x18)){ status = MI_OK; }else{ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:验证卡片密码//参数说明: auth_mode[IN]: 密码验证模式// 0x60 = 验证A密钥// 0x61 = 验证B密钥// addr[IN]:块地址// pKey[IN]:密码// pSnr[IN]:卡片序列号,4字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdAuthState(u8 auth_mode,u8 addr,u8 *pKey,u8 *pSnr){char status;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = auth_mode;ucComMF522Buf[1] = addr;memcpy(&ucComMF522Buf[2], pKey, 6);memcpy(&ucComMF522Buf[8], pSnr, 4);status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08))){ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:读取M1卡一块数据//参数说明: addr[IN]:块地址// p [OUT]:读出的数据,16字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdRead(u8 addr,u8 *p ){char status;u8 unLen;u8 i,ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_READ;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x90)){for (i=0; i<16; i++){ *(p +i) = ucComMF522Buf[i]; }}else{ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:写数据到M1卡一块//参数说明: addr[IN]:块地址// p [IN]:写入的数据,16字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdWrite(u8 addr,u8 *p ){char status;u8 unLen;u8 i,ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_WRITE;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){ status = MI_ERR; }if (status == MI_OK){for (i=0; i<16; i++){ucComMF522Buf[i] = *(p +i);}CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);status =PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){ status = MI_ERR; }}return status;}///////////////////////////////////////////////////////////////////////功能:命令卡片进入休眠状态//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdHalt(void){u8 status;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_HALT;ucComMF522Buf[1] = 0;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);return MI_OK;}///////////////////////////////////////////////////////////////////////用MF522计算CRC16函数/////////////////////////////////////////////////////////////////////void CalulateCRC(u8 *pIn ,u8 len,u8 *pOut ){u8 i,n;ClearBitMask(DivIrqReg,0x04);WriteRawRC(CommandReg,PCD_IDLE);SetBitMask(FIFOLevelReg,0x80);for (i=0; i<len; i++){ WriteRawRC(FIFODataReg, *(pIn +i)); }WriteRawRC(CommandReg, PCD_CALCCRC);i = 0xFF;do{n = ReadRawRC(DivIrqReg);i--;}while ((i!=0) && !(n&0x04));pOut [0] = ReadRawRC(CRCResultRegL);pOut [1] = ReadRawRC(CRCResultRegM);}///////////////////////////////////////////////////////////////////////功能:复位RC522//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdReset(void){GPIO_HIGH(RC522RST_GPIO_PORT,RC522RST_GPIO_PIN);delay_ns(10);GPIO_LOW(RC522RST_GPIO_PORT,RC522RST_GPIO_PIN);delay_ns(10);GPIO_HIGH(RC522RST_GPIO_PORT,RC522RST_GPIO_PIN);delay_ns(10);WriteRawRC(CommandReg,PCD_RESETPHASE);delay_ns(10);WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363 WriteRawRC(TReloadRegL,30);WriteRawRC(TReloadRegH,0);WriteRawRC(TModeReg,0x8D);WriteRawRC(TPrescalerReg,0x3E);WriteRawRC(TxAutoReg,0x40);//必须要return MI_OK;}////////////////////////////////////////////////////////////////////////设置RC632的工作方式//////////////////////////////////////////////////////////////////////char M500PcdConfigISOType(u8 type){if (type == 'A') //ISO14443_A{ClearBitMask(Status2Reg,0x08);WriteRawRC(ModeReg,0x3D);WriteRawRC(RxSelReg,0x86);WriteRawRC(RFCfgReg,0x7F);WriteRawRC(TReloadRegL,30);WriteRawRC(TReloadRegH,0);WriteRawRC(TModeReg,0x8D);WriteRawRC(TPrescalerReg,0x3E);delay_ns(1000);PcdAntennaOn();}else{return 1;}return MI_OK;}///////////////////////////////////////////////////////////////////////功能:读RC632寄存器//参数说明:Address[IN]:寄存器地址//返回:读出的值u8 ReadRawRC(u8 Address){u8 ucAddr;u8 ucResult=0;GPIO_LOW(RC522NSS_GPIO_PORT,RC522NSS_GPIO_PIN);ucAddr = ((Address<<1)&0x7E)|0x80;SPIWriteByte(ucAddr);ucResult=SPIReadByte();GPIO_HIGH(RC522NSS_GPIO_PORT,RC522NSS_GPIO_PIN);return ucResult;}///////////////////////////////////////////////////////////////////////功能:写RC632寄存器//参数说明:Address[IN]:寄存器地址// value[IN]:写入的值/////////////////////////////////////////////////////////////////////void WriteRawRC(u8 Address, u8 value){u8 ucAddr;GPIO_LOW(RC522NSS_GPIO_PORT,RC522NSS_GPIO_PIN);ucAddr = ((Address<<1)&0x7E);SPIWriteByte(ucAddr);SPIWriteByte(value);GPIO_HIGH(RC522NSS_GPIO_PORT,RC522NSS_GPIO_PIN);}///////////////////////////////////////////////////////////////////////功能:置RC522寄存器位//参数说明:reg[IN]:寄存器地址// mask[IN]:置位值/////////////////////////////////////////////////////////////////////void SetBitMask(u8 reg,u8 mask){char tmp = 0x0;tmp = ReadRawRC(reg);WriteRawRC(reg,tmp | mask); // set bit mask}///////////////////////////////////////////////////////////////////////功能:清RC522寄存器位//参数说明:reg[IN]:寄存器地址// mask[IN]:清位值/////////////////////////////////////////////////////////////////////void ClearBitMask(u8 reg,u8 mask){char tmp = 0x0;tmp = ReadRawRC(reg);WriteRawRC(reg, tmp & ~mask); // clear bit mask}//功能:通过RC522和ISO14443卡通讯//参数说明:Command[IN]:RC522命令字// pIn [IN]:通过RC522发送到卡片的数据// InLenByte[IN]:发送数据的字节长度// pOut [OUT]:接收到的卡片返回数据// *pOutLenBit[OUT]:返回数据的位长度/////////////////////////////////////////////////////////////////////char PcdComMF522(u8 Command,u8 *pIn ,u8 InLenByte,u8 *pOut ,u8 *pOutLenBit){char status = MI_ERR;u8 irqEn = 0x00;u8 waitFor = 0x00;u8 lastBits;u8 n;u16 i;switch (Command){case PCD_AUTHENT:irqEn = 0x12;waitFor = 0x10;break;case PCD_TRANSCEIVE:irqEn = 0x77;waitFor = 0x30;break;default:break;}WriteRawRC(ComIEnReg,irqEn|0x80);ClearBitMask(ComIrqReg,0x80); //清所有中断位WriteRawRC(CommandReg,PCD_IDLE);SetBitMask(FIFOLevelReg,0x80); //清FIFO缓存for (i=0; i<InLenByte; i++){WriteRawRC(FIFODataReg, pIn [i]);}WriteRawRC(CommandReg, Command);// n = ReadRawRC(CommandReg);if (Command == PCD_TRANSCEIVE){SetBitMask(BitFramingReg,0x80); //开始传送}//i = 600;//根据时钟频率调整,操作M1卡最大等待时间25msi = 10000;do{n = ReadRawRC(ComIrqReg);i--;}while ((i!=0) && !(n&0x01) && !(n&waitFor)); ClearBitMask(BitFramingReg,0x80);if (i!=0){if(!(ReadRawRC(ErrorReg)&0x1B)){status = MI_OK;if (n & irqEn & 0x01){status = MI_NOTAGERR;}if (Command == PCD_TRANSCEIVE){n = ReadRawRC(FIFOLevelReg);lastBits = ReadRawRC(ControlReg) & 0x07;if (lastBits){*pOutLenBit = (n-1)*8 + lastBits;}else{*pOutLenBit = n*8;}if (n == 0){n = 1;}if (n > MAXRLEN){n = MAXRLEN;}for (i=0; i<n; i++){pOut[i] = ReadRawRC(FIFODataReg);}}}else{status = MI_ERR;}}SetBitMask(ControlReg,0x80); // stop timer nowWriteRawRC(CommandReg,PCD_IDLE);return status;}///////////////////////////////////////////////////////////////////////开启天线//每次启动或关闭天险发射之间应至少有1ms的间隔/////////////////////////////////////////////////////////////////////void PcdAntennaOn(void){u8 i;i = ReadRawRC(TxControlReg);if (!(i & 0x03)){SetBitMask(TxControlReg, 0x03);}}///////////////////////////////////////////////////////////////////////关闭天线/////////////////////////////////////////////////////////////////////void PcdAntennaOff(void){ClearBitMask(TxControlReg, 0x03);}///////////////////////////////////////////////////////////////////////功能:扣款和充值//参数说明: dd_mode[IN]:命令字// 0xC0 = 扣款// 0xC1 = 充值// addr[IN]:钱包地址// pValue[IN]:4字节增(减)值,低位在前//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdValue(u8 dd_mode,u8 addr,u8 *pValue){char status;u8 unLen;u8 ucComMF522Buf[MAXRLEN];//u8 i;ucComMF522Buf[0] = dd_mode;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){status = MI_ERR;}if (status == MI_OK){memcpy(ucComMF522Buf, pValue, 4);//for (i=0; i<16; i++)//{ ucComMF522Buf[i] = *(pValue+i); }CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]);unLen = 0;status =PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen);if (status != MI_ERR){ status = MI_OK; }}if (status == MI_OK){ucComMF522Buf[0] = PICC_TRANSFER;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status =PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){ status = MI_ERR; }}return status;}。
51单片机RC522射频卡驱动
/*-----------------------------------------------.H文件-----------------------------------------*/#ifndef __RC522_H_#define __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 RFU3F0x3F///////////////////////////////////////////////////////////////////// //和MF522通讯时返回的错误代码///////////////////////////////////////////////////////////////////// #define MI_OK 0#define MI_NOTAGERR (-1)#define MI_ERR (-2)#define SHAQU10X01#define KUAI40X04#define KUAI70X07#define REGCARD0xa1#define CONSUME0xa2#define READCARD0xa3#define ADDMONEY0xa4//void delay_ns(uint16 ns);void delay10us(void);void delay1ms(void);uint8 SPIReadByte(void);void SPIWriteByte(uint8 SPIData);char PcdRequest(uint8 req_code,uint8 *pTagType);char PcdAnticoll(uint8 *pSnr);char PcdSelect(unsigned char *pSnr);char PcdAuthState(uint8 auth_mode,uint8 addr,uint8 *pKey,uint8 *pSnr);char PcdRead(uint8 addr,uint8 *pData);char PcdWrite(uint8 addr,uint8 *pData);char PcdHalt(void);void CalulateCRC(uint8 *pIndata,uint8 len,uint8 *pOutData);char PcdReset(void);char M500PcdConfigISOType(uint8 type);uint8 ReadRawRC(uint8 Address);void WriteRawRC(uint8 Address, uint8 value);void SetBitMask(uint8 reg,uint8 mask);void ClearBitMask(uint8 reg,uint8 mask);char PcdComMF522(uint8 Command,uint8 *pInData,uint8 InLenByte,uint8 *pOutData,uint16 *pOutLenBit);void PcdAntennaOn(void);void PcdAntennaOff(void);void InitRc522(void);void delay1ms500us(void);sbit SPI_CS = P1^3;sbit SPI_CK = P1^4;sbit SPI_MOSI = P1^5;sbit SPI_MISO = P1^6;sbit SPI_RST = P1^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 SET_SPI_MISO SPI_MISO#define SET_RC522RST SPI_RST=1#define CLR_RC522RST SPI_RST=0#endif/*-----------------------------------------------.c文件-----------------------------------------*/#include "rc522.h"/*void delay_ns(uint16 ns){uint16 xdata i;for(i=0;i<ns;i++){nop();nop();nop();}}*/void delay10us(void) //误差0us{unsigned char a,b;for(b=1;b>0;b--)for(a=2;a>0;a--);}void delay1ms(void) //误差0us{unsigned char a,b,c;for(c=1;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--);}void delay1ms500us(void) //误差0us{uint8 xdata a,b;for(b=115;b>0;b--)for(a=5;a>0;a--);}uint8 SPIReadByte(void){uint8 xdata SPICount; // Counter used to clock out the datauint8 xdata SPIData;SPIData = 0;for (SPICount = 0; SPICount < 8; SPICount++) // Prepare to clock in the data to be read{SPIData <<=1; // Rotate the data CLR_SPI_CK; nop();nop(); // Raise the clock to clock the data out of the MAX7456if(SET_SPI_MISO){SPIData|=0x01;}SET_SPI_CK; nop();nop(); // Drop the clock ready for the next bit} // and loop back return (SPIData); // Finally return the read data}void SPIWriteByte(uint8 SPIData){uint8 xdata SPICount; // Counter used to clock out the datafor (SPICount = 0; SPICount < 8; SPICount++){if (SPIData & 0x80){SET_SPI_MOSI;}else{CLR_SPI_MOSI;} nop();nop();CLR_SPI_CK;nop();nop();SET_SPI_CK;nop();nop();SPIData <<= 1;}}///////////////////////////////////////////////////////////////////////功能:寻卡//参数说明: req_code[IN]:寻卡方式// 0x52 = 寻感应区内所有符合14443A标准的卡// 0x26 = 寻未进入休眠状态的卡// pTagType[OUT]:卡片类型代码// 0x4400 = Mifare_UltraLight// 0x0400 = Mifare_One(S50)// 0x0200 = Mifare_One(S70)// 0x0800 = Mifare_Pro(X)// 0x4403 = Mifare_DESFire//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdRequest(uint8 req_code,uint8 *pTagType){char xdata status;uint16 xdata unLen;uint8 xdata ucComMF522Buf[MAXRLEN];ClearBitMask(Status2Reg,0x08);WriteRawRC(BitFramingReg,0x07);SetBitMask(TxControlReg,0x03);ucComMF522Buf[0] = req_code;status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x10)){*pTagType = ucComMF522Buf[0];*(pTagType+1) = ucComMF522Buf[1];}else{ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:防冲撞//参数说明: pSnr[OUT]:卡片序列号,4字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdAnticoll(uint8 *pSnr){char xdata status;uint8 xdata i,snr_check=0;uint16 xdata unLen;uint8 xdata ucComMF522Buf[MAXRLEN];ClearBitMask(Status2Reg,0x08);WriteRawRC(BitFramingReg,0x00);ClearBitMask(CollReg,0x80);ucComMF522Buf[0] = PICC_ANTICOLL1;ucComMF522Buf[1] = 0x20;status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);if (status == MI_OK){for (i=0; i<4; i++){*(pSnr+i) = ucComMF522Buf[i];snr_check ^= ucComMF522Buf[i];}if (snr_check != ucComMF522Buf[i]){ status = MI_ERR; }}SetBitMask(CollReg,0x80);return status;}///////////////////////////////////////////////////////////////////////功能:选定卡片//参数说明: pSnr[IN]:卡片序列号,4字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdSelect(uint8 *pSnr){char xdata status;uint8 xdata i;uint16 xdata unLen;uint8 xdata ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_ANTICOLL1;ucComMF522Buf[1] = 0x70;ucComMF522Buf[6] = 0;for (i=0; i<4; i++){ucComMF522Buf[i+2] = *(pSnr+i);ucComMF522Buf[6] ^= *(pSnr+i);}CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);ClearBitMask(Status2Reg,0x08);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x18)){ status = MI_OK; }else{ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:验证卡片密码//参数说明: auth_mode[IN]: 密码验证模式// 0x60 = 验证A密钥// 0x61 = 验证B密钥// addr[IN]:块地址// pKey[IN]:密码// pSnr[IN]:卡片序列号,4字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdAuthState(uint8 auth_mode,uint8 addr,uint8 *pKey,uint8 *pSnr){char xdata status;uint16 xdata unLen;uint8 xdata i,ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = auth_mode;ucComMF522Buf[1] = addr;for (i=0; i<6; i++){ ucComMF522Buf[i+2] = *(pKey+i); }for (i=0; i<6; i++){ ucComMF522Buf[i+8] = *(pSnr+i); }// memcpy(&ucComMF522Buf[2], pKey, 6);// memcpy(&ucComMF522Buf[8], pSnr, 4);status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08))){ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:读取M1卡一块数据//参数说明: addr[IN]:块地址// pData[OUT]:读出的数据,16字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdRead(uint8 addr,uint8 *pData){char xdata status;uint16 xdata unLen;uint8 xdata i,ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_READ;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x90))// { memcpy(pData, ucComMF522Buf, 16); }{for (i=0; i<16; i++){ *(pData+i) = ucComMF522Buf[i]; }}else{ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:写数据到M1卡一块//参数说明: addr[IN]:块地址// pData[IN]:写入的数据,16字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdWrite(uint8 addr,uint8 *pData){char xdata status;uint16 xdata unLen;uint8 xdata i,ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_WRITE;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){ status = MI_ERR; }if (status == MI_OK){//memcpy(ucComMF522Buf, pData, 16);for (i=0; i<16; i++){ucComMF522Buf[i] = *(pData+i);}CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){ status = MI_ERR; }}return status;}///////////////////////////////////////////////////////////////////////功能:命令卡片进入休眠状态//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdHalt(void){char xdata status;uint16 xdata unLen;uint8 xdata ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_HALT;ucComMF522Buf[1] = 0;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);return MI_OK;}///////////////////////////////////////////////////////////////////////用MF522计算CRC16函数/////////////////////////////////////////////////////////////////////void CalulateCRC(uint8 *pIndata,uint8 len,uint8 *pOutData){uint8 xdata i,n;ClearBitMask(DivIrqReg,0x04);WriteRawRC(CommandReg,PCD_IDLE);SetBitMask(FIFOLevelReg,0x80);for (i=0; i<len; i++){ WriteRawRC(FIFODataReg, *(pIndata+i)); }WriteRawRC(CommandReg, PCD_CALCCRC);i = 0xFF;do{n = ReadRawRC(DivIrqReg);i--;}while ((i!=0) && !(n&0x04));pOutData[0] = ReadRawRC(CRCResultRegL);pOutData[1] = ReadRawRC(CRCResultRegM);}///////////////////////////////////////////////////////////////////////功能:复位RC522//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdReset(void){//PORTD|=(1<<RC522RST);SET_RC522RST;delay10us();//PORTD&=~(1<<RC522RST);CLR_RC522RST;delay10us();//PORTD|=(1<<RC522RST);SET_RC522RST;delay10us();WriteRawRC(CommandReg,PCD_RESETPHASE);delay10us();WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363 WriteRawRC(TReloadRegL,30);WriteRawRC(TReloadRegH,0);WriteRawRC(TModeReg,0x8D);WriteRawRC(TPrescalerReg,0x3E);WriteRawRC(TxAutoReg,0x40);//必须要return MI_OK;}////////////////////////////////////////////////////////////////////////设置RC632的工作方式//////////////////////////////////////////////////////////////////////char M500PcdConfigISOType(uint8 type){if (type == 'A') //ISO14443_A{ClearBitMask(Status2Reg,0x08);WriteRawRC(ModeReg,0x3D);//3FWriteRawRC(RxSelReg,0x86);//84WriteRawRC(RFCfgReg,0x7F); //4FWriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec) WriteRawRC(TReloadRegH,0);WriteRawRC(TModeReg,0x8D);WriteRawRC(TPrescalerReg,0x3E);delay1ms();PcdAntennaOn();}else{ return -1; }return MI_OK;}///////////////////////////////////////////////////////////////////////功能:读RC632寄存器//参数说明:Address[IN]:寄存器地址//返回:读出的值/////////////////////////////////////////////////////////////////////uint8 ReadRawRC(uint8 Address){uint8 xdata ucAddr;uint8 xdata ucResult=0;CLR_SPI_CS;ucAddr = ((Address<<1)&0x7E)|0x80;SPIWriteByte(ucAddr);ucResult=SPIReadByte();SET_SPI_CS;return ucResult;}///////////////////////////////////////////////////////////////////// //功能:写RC632寄存器//参数说明:Address[IN]:寄存器地址// value[IN]:写入的值///////////////////////////////////////////////////////////////////// void WriteRawRC(uint8 Address, uint8 value){uint8 xdata ucAddr;CLR_SPI_CS;ucAddr = ((Address<<1)&0x7E);SPIWriteByte(ucAddr);SPIWriteByte(value);SET_SPI_CS;}///////////////////////////////////////////////////////////////////// //功能:置RC522寄存器位//参数说明:reg[IN]:寄存器地址// mask[IN]:置位值///////////////////////////////////////////////////////////////////// void SetBitMask(uint8 reg,uint8 mask){char xdata tmp = 0x0;tmp = ReadRawRC(reg);WriteRawRC(reg,tmp | mask); // set bit mask}///////////////////////////////////////////////////////////////////// //功能:清RC522寄存器位//参数说明:reg[IN]:寄存器地址// mask[IN]:清位值///////////////////////////////////////////////////////////////////// void ClearBitMask(uint8 reg,uint8 mask){char xdata tmp = 0x0;tmp = ReadRawRC(reg);WriteRawRC(reg, tmp & ~mask); // clear bit mask}///////////////////////////////////////////////////////////////////// //功能:通过RC522和ISO14443卡通讯//参数说明:Command[IN]:RC522命令字// pInData[IN]:通过RC522发送到卡片的数据// InLenByte[IN]:发送数据的字节长度// pOutData[OUT]:接收到的卡片返回数据// *pOutLenBit[OUT]:返回数据的位长度/////////////////////////////////////////////////////////////////////char PcdComMF522(uint8 Command,uint8 *pInData,uint8 InLenByte,uint8 *pOutData,uint16 *pOutLenBit){char xdata status = MI_ERR;uint8 xdata irqEn = 0x00;uint8 xdata waitFor = 0x00;uint8 xdata lastBits;uint8 xdata n;uint16 xdata i;switch (Command){case PCD_AUTHENT:irqEn = 0x12;waitFor = 0x10;break;case PCD_TRANSCEIVE:irqEn = 0x77;waitFor = 0x30;break;default:break;}WriteRawRC(ComIEnReg,irqEn|0x80);ClearBitMask(ComIrqReg,0x80);WriteRawRC(CommandReg,PCD_IDLE);SetBitMask(FIFOLevelReg,0x80);for (i=0; i<InLenByte; i++){ WriteRawRC(FIFODataReg, pInData[i]); }WriteRawRC(CommandReg, Command);if (Command == PCD_TRANSCEIVE){ SetBitMask(BitFramingReg,0x80); }//i = 600;//根据时钟频率调整,操作M1卡最大等待时间25msi = 2000;do{n = ReadRawRC(ComIrqReg);i--;}while ((i!=0) && !(n&0x01) && !(n&waitFor));ClearBitMask(BitFramingReg,0x80);if (i!=0){if(!(ReadRawRC(ErrorReg)&0x1B)){status = MI_OK;if (n & irqEn & 0x01){ status = MI_NOTAGERR; }if (Command == PCD_TRANSCEIVE){n = ReadRawRC(FIFOLevelReg);lastBits = ReadRawRC(ControlReg) & 0x07;if (lastBits){ *pOutLenBit = (n-1)*8 + lastBits; }else{ *pOutLenBit = n*8; }if (n == 0){ n = 1; }if (n > MAXRLEN){ n = MAXRLEN; }for (i=0; i<n; i++){ pOutData[i] = ReadRawRC(FIFODataReg); } }}else{ status = MI_ERR; }}SetBitMask(ControlReg,0x80); // stop timer nowWriteRawRC(CommandReg,PCD_IDLE);return status;}///////////////////////////////////////////////////////////////////////开启天线//每次启动或关闭天险发射之间应至少有1ms的间隔///////////////////////////////////////////////////////////////////// void PcdAntennaOn(void){uint8 xdata i;i = ReadRawRC(TxControlReg);if (!(i & 0x03)){SetBitMask(TxControlReg, 0x03);}}///////////////////////////////////////////////////////////////////// //关闭天线///////////////////////////////////////////////////////////////////// void PcdAntennaOff(void){ClearBitMask(TxControlReg, 0x03);}///////////////////////////////////////////////////////////////////// //rc522初始化///////////////////////////////////////////////////////////////////// void InitRc522(void){PcdReset();PcdAntennaOff();delay1ms500us();PcdAntennaOn();M500PcdConfigISOType( 'A' );}。
rc522产品手册
rc522产品手册一、概述RC522是一款广泛应用的非接触式射频识别(RFID)读写器芯片,专为高频(13.56 MHz)射频通信设计。
由于其高效性能、低功耗及易于集成等特性,RC522在物联网、电子门锁、智能支付等领域有着广泛的应用。
本手册将详细介绍RC522的主要功能、技术规格、使用方法及常见问题解答。
二、产品特性工作频率:13.56 MHz。
支持ISO14443A/MIFARE标准。
高集成度:将射频前端、解调器、安全逻辑和EEPROM 存储器集成于单芯片中。
低功耗:在待机状态下电流消耗仅为170μA,读写时为3.3mA。
高速数据传输:支持高达848 kbps的通信速率。
多种接口选择:可与SPI、I2C、UART等接口进行连接。
安全性:支持加密和解密功能,确保数据传输的安全性。
三、使用方法硬件连接:根据所选接口,将RC522与微控制器或其他设备进行连接。
注意确保天线连接良好,以获得最佳的通信效果。
电源供应:为RC522提供稳定的电源,建议电压范围为3.3-5V。
寄存器配置:根据需求,通过SPI、I2C或UART接口对RC522的寄存器进行配置。
这包括设置通信参数、选择工作模式等。
读写操作:使用配置好的寄存器参数,对RFID标签进行读写操作。
数据处理:对从RFID标签读取的数据进行解码和安全性验证,确保数据的准确性和安全性。
四、常见问题及解答1.RC522支持哪些类型的RFID标签?答:RC522支持ISO14443A标准和MIFARE系列标签,可读写多种类型的RFID 标签。
2.为什么无法读取RFID标签?答:可能的原因包括天线连接不良、标签与读卡器之间的距离过远、存在干扰等。
请检查天线连接和工作环境,确保符合通信要求。
3.如何配置RC522的寄存器?答:根据需要,通过SPI、I2C或UART接口对RC522的寄存器进行配置。
具体配置方法可参考相关开发文档或手册。
rc522射频模块使用方法
rc522射频模块使用方法RC522射频模块是一种无线通信设备,具有超低功耗、小型化、低成本和强大的功能特性,广泛用于身份证、智能卡和一些可携式设备的读写。
本文旨在介绍RC522射频模块的工作原理及其相关的使用方法。
一、RC522射频模块的工作原理RC522射频模块由读卡器和智能卡组成, RC522射频模块采用13.56MHz非接触式射频识别技术,它基于ISO/IEC 14443A标准设计,具有高性能、高度灵活性、高功率处理能力和低成本等特点。
RC522射频模块可以实现快速、有效地读取智能卡的信息,从而实现身份验证的功能,这是它的基本功能,而且它还支持其他多种功能。
其次,RC522射频模块支持读写NFC、M1卡和其他类型的磁卡,如ISO14443A、ISO14443B、ISO15693、ISO18092,而且还支持FeliCa、Mifare系列卡等,具备良好的兼容性和可编程性,可以满足不同应用场景的需求。
最后,RC522射频模块可以根据接入不同类型的外设,支持具有高达106Kbps的ISO/IEC 14443A/Mifare卡片快速传输。
二、RC522射频模块的使用方法1、安装驱动在使用RC522射频模块之前,首先需要安装驱动,使用支持RC522射频模块的主板进行安装,然后按照说明文档中的步骤安装完成,以保证该模块的正常工作。
2、安装模块安装好驱动之后,可以将RC522射频模块安装到主板上,每个模块都有一个单独的安装位置,有着一定的精准度和敏感度,所以在安装时要谨慎,并将模块固定在安装位置,以确保模块正常工作。
3、操作模块当模块安装完成后,需要进行操作,操作模块可以通过编程语言完成,根据编程语言的不同,使用的模块操作方法也不同,比如C语言可以使用MFC实现,Python语言可以使用pyRFID实现等。
4、测试模块模块操作完成后,需要进行测试,以确保模块工作正常,可以使用测试卡书进行测试,该卡书上有用于测试的信息,如果检测到正确的信息,则表明模块正常工作,可以正常使用。
rc522射频模块使用方法
rc522射频模块使用方法RC522射频模块是一款用于读写非接触式13.56MHz智能卡的射频读卡组件,它是一种基于NFC/RFID的短距离无线支持技术,它可以识别ISO14443A标准和Mifare系列卡片。
RC522射频模块由射频芯片和一个控制板组成,并将其接入NFC手机或单片机系统,使其能够实现接受信号、解调和发射信号。
I.件连接要使用RC522射频模块,首先需要将其连接到电路板上,并连接相应的电源和I/O口。
由于RC522射频模块的每个引脚都有特定的用途,因此在连接时,应该根据电路板的连接指南将其连接到正确的位置。
此外,RC522射频模块的电源输入范围为3.3V,电流需求为13mA,因此需要将模块连接到一个可以提供3.3V电压的电源模块。
II.件驱动要使用RC522射频模块,需要安装特定的软件驱动,以便能够控制它进行发射和接收操作。
在安装软件驱动之前,最好检查该设备是否已经连接到计算机,并且正常工作。
一旦检查通过,即可安装驱动程序,并且可以根据官方说明进行安装。
在安装完成后,可以使用该软件来控制RC522射频模块的发射和接收操作。
III.射和接收要使用RC522射频模块完成发射和接收操作,首先需要检查该信号源是否已经被配置。
如果未配置,可以使用软件驱动进行配置,以便能够发射信号。
其次,在发射信号之前,需要将射频模块设置为发射模式,并且检查是否有任何外部干扰,以确保信号的准确发射。
在发射后,需要将RC522射频模块设置为接收模式,然后等待接收信号并解调。
在接收信号之后,需要检查接收的信号是否正常,以确保RC522射频模块能够正确的完成发射和接收操作。
IV.写数据在发射和接收操作完成后,就可以使用RC522射频模块读取13.56MHz非接触式智能卡中的数据了。
使用RC522射频模块进行读写操作时,需要先将其设置为读写模式,然后使用控制芯片和设置的波特率及编码格式,发送相应的指令,以实现对NFC/RFID智能卡中的数据进行读写操作。
MFRC522 IC卡模块使用手册V1.0
MFRC522 IC 卡模块使用手册 V1.0嵌达科技,快乐生活 欢迎访问:/shop/view_shop.htm?tracelog=twddp 程序功能: 当 IC 卡放在模块上时,先把预先赋值给 Write_Data[16]这个数组中的数据写 到 IC 卡中,然后马上把写入的数据读出来,显示在 PC 机的串口调试助手上。
操作步骤: 1、 下载程序到单片机中。
我们设计的电路板使用的是 AT89S52,因此只能通过 ISP 下载,为了布线方 便,我只引出了必须的 6 根线供下载,图如下:程 序 下 载 接 口 程 序 下 载 接我们都知道 ISP 下载器都是 10 脚的,从 10 脚转变成 6 脚就必须有所转换, 一般有两种解决方法:1)通过杜邦线一对一连,这种方法的前提是你必须知道 自己手上的 ISP 下载器引脚定义;2)通过另一块转接板把 10 脚转换为 6 脚,并 附加上开关功能,这种方法比较方便,如下图:由于此转换电路板制作费用较小,如果您买了 ISP 下载器或者买了读写卡模 块,我们将免费赠送。
2、 准备工作 ① 将读写卡模块插在电路板上; ② 将串口线连接电路板和电脑,保证可以实现串口通信的硬件连接; ③ 打开 PC 机上的串口调试助手,并打开对应端口,开启 16 进制显示,准 备接收数据。
口3、 实现读写卡 ① 给电路板通电; ② 把卡放在读卡器模块上,当绿灯亮时表示读写卡结束,此时串口调试助 手会显示出卡对应数据块中的数据,如下图:1、工程文件说明:我们的程序只用了四个文件,分别为:读写卡.c、read_card.h、read_card.c和 rc522.h。
下面我来介绍一下这四个文件的作用,各位亲,这部份仔细看哦, 尤其是那些还执着于在一个文件中实现所的函数编写的朋友们, 下面我们所展示 的文件架构可以适用于小中型工程的实现, 这会让您的程序看上去更有条理性和 逻辑性,更容易调试和修改程序,这对于您自身编程能力的提升是无往不利的。
TIDZ-RC522读卡模块使用说明
TJDZ-RC522 RFID读卡模块
用户操作手册
Ver_1.0_20121101
RC522 RFID读卡模块使用说明
(以MSP430F149处理器为例)
第一步:将RFID模块与MSP430F149最小系统板采用杜邦线连接;
第二步:程序通过BSL下载到MSP430F149中;
第三步:将串口线USB-RS232连接计算机与开发板;
第四步:打开串口调试手(正确设置波特率以及串口号);
第五步:按MSP430F149最小系统板上的复位键,则串口调试手出现如下画面:
第六步:在串口发送区,输入A点击发送,为自动寻卡模式;若输入F点击发送则为单次寻卡模式;
第七步:将卡片放到读卡模块上,则可以看到读出卡的ID号。
测试完毕。
MFRC522读卡
e;
//设置硬件控制流失能(失能:就是不管用的意思。
USART_ART_Mode=USART_Mode_Rx|USART_Mode_Tx; //设置发送使能,接收使能
USART_Init(USART1,&USART_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
//接口
for(n=0;n<4;n++)//CIPSEND[18]="AT+CIPSEND=0,4\r\n"; { USART_SendData(USART1,(u8)Card_ID[n]);
//stm32 发送字符串
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); delay_ms(1);
//将端口 4 设计成低电平
RCC_APB2PeriphClockCmd(RC522_RESET_GPIO_CLK,ENABLE); //设置时钟(使能)
GPIO_InitStructure.GPIO_Pin = RC522_RESET_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(RC522_RESET_GPIO_PORT, &GPIO_InitStructure);
uint8_t CWMODE[15]="AT+CWMODE=2\r\n";
//选择 AP 模式
uint8_t CWSAP[35]="AT+CWSAP='GUANLI','12345678',3333,3\r\n"; 码,通道号,加密方式 wpa2_psk uint8_t CIPMUX[15]="AT+CIPMUX=1\r\n"; //多路连接模式
RC522读卡模块使用说明
TJDZ-RC522 RFID 读卡模块
用户操作手册
Ver_1.0_20121101
RC522 RFID 读卡模块使用说明
(以 MSP430F149 处理器为例)
第一步:将 RFID 模块与 MSP430F149 最小系统板采用杜邦线连接;
RC522 接口MSP430F149 接口
SDA(数据接口) P2.7
SCK(时钟接口)P2.6
MOSI(SPI 接口主出从入)P2.5
MISO(SPI 接口主入从出)P2.1
NC(悬空)
GND(地)GND
RST(复位信号)P2.3
3.3V(电源) 3.3V
第二步:程序通过 BSL 下载到 MSP430F149 中;
第三步:将串口线 USB-RS232 连接计算机与开发板;
第四步:打开串口调试手(正确设置波特率以及串口号);
第五步:按 MSP430F149 最小系统板上的复位键,则串口调试手出现如下画面:
第六步:在串口发送区,输入 A 点击发送,为自动寻卡模式;若输入F 点击发送则为单次寻卡模式;
第七步:将卡片放到读卡模块上,则可以看到读出卡的 ID 号。
测试完毕。
mfrc522 手册
mfrc522手册MFRC522是一款常用的RFID读卡器模块,广泛应用于身份识别、门禁控制、移动支付等领域。
以下是对MFRC522的详细介绍:MFRC522是一款由NXP公司生产的低功耗、高灵敏度的RFID读卡器模块,其工作频率为13.56MHz,支持ISO14443A/MIFARE标准。
该模块具有SPI接口,可方便地与微控制器进行通信,从而实现快速、可靠地读取RFID卡的信息。
MFRC522的主要特点包括:1、支持多种RFID卡类型:MFRC522支持ISO14443A标准的RFID卡,包括MIFARE Classic、MIFARE Ultralight等常用卡型。
此外,它还支持多种加密算法,如DES、3DES等,确保数据的安全性。
2、高速数据传输:MFRC522的SPI接口数据传输速率最高可达800kbps,使得读卡器能够快速读取RFID卡的标签信息,提高了系统的响应速度。
3、自动寻卡功能:MFRC522具有自动寻卡功能,当有RFID卡靠近时,读卡器会自动唤醒并读取卡的信息,进一步简化了系统的设计。
4、低功耗设计:MFRC522采用低功耗设计,工作电流较小,有利于延长系统的使用寿命。
5、易于集成:MFRC522具有紧凑的尺寸和易于集成的特点,可方便地与其他电子元件一起应用于各种RFID读卡器设备中。
MFRC522的应用场景非常广泛,包括但不限于:1、身份识别:在门禁控制、考勤系统等应用中,MFRC522可以快速、准确地读取用户的RFID卡信息,从而实现身份的识别和验证。
2、移动支付:通过集成MFRC522,移动设备可以实现非接触式支付功能,为用户带来便捷的支付体验。
3、物流管理:在物流领域,MFRC522可以用于跟踪包裹的位置和状态,提高物流效率。
4、资产管理:在图书馆、仓储等场景中,MFRC522可以帮助管理者追踪和管理资产的位置和状态。
总之,MFRC522是一款功能强大、易于集成的RFID读卡器模块,可广泛应用于各种需要快速、可靠地读取RFID卡信息的场景中。
MF RC522应用说明书
不同的主机接口功能可满足不同用户的要求。
2.订购信息
待定。
3.管脚信息
3.1 封装
RC522 包含 QFN32 的封装形式。
表 1 封装信息
封装 QFN32
功能注 见第 19 章释的表面封装
2
RC522
3.2 管脚描述
表 2 管脚描述
注:管脚类型: I-输入;O-输出;PWR-电源
符号
QFN32
类型
3
DivIEnReg
4
ComIrqReg
5
DivIrqReg
6
ErrorReg
7
Status1Reg
8
Status2Reg
9
FIFODtataReg
A
FIFOLevelReg
B
WaterLevelReg
C
ControlRegDLeabharlann BitFramingReg
E
CollReg
F
RFU
PAGE1:命令
0
RFU
5.2.1.2 CommandReg 启动和停止命令的执行。
CommandReg 7
00
访问权限
RFU
表 7 CommandReg
RC522教程(基于mps430)
RFID-RC522速成教程(基于msp430单片机的程序讲解)学习一种模块,有很多种方法,其中一种方式是先去弄明白怎么使用这个模块,亲自体验了这个模块的大体功能之后,再回过头来了解该模块的工作原理,再去深层次的研究该模块。
在这里,着重介绍怎么用程序实现RC522模块的一些功能,而RC522的结构,功能等便不再介绍。
这个程序的讲解是基于MSP430F149/169单片机的。
模块使用的是SPI接口,与单片机接口如下:#define RF_LPCTL BIT3 // P2.3 射频卡休眠控制------RST#define RF_SS BIT7 // p2.7 射频卡从机选择(SS)---SDA#define RF_SCLK BIT6 // p2.6 射频卡数据时钟输出(SCLK)#define RF_DATA_OUT BIT5 // p2.5 射频卡数据输出(MOSI)#define RF_DATA_IN BIT1 // p2.1 射频模块输入(MISO)要想对模块内部的数据块进行读写,需要完成4个步骤:寻卡→防冲突→选卡→读/写卡;第一步:寻卡。
status2=PcdRequest(0x52,Temp);////寻卡参数Temp为返回的卡类型if(status2== MI_OK){tochar(Temp[0]);tochar(Temp[1]);//输出卡类型}其中0x52代表寻天线区内全部卡。
卡类型(TagType):0x4400 = Mifare_UltraLight0x0400 = Mifare_One(S50)0x0200 = Mifare_One(S70)0x0800 = Mifare_Pro(X)0x4403 = Mifare_DESFire比如,当Temp[0]=04,Temp[1]=00时,卡类型为S50。
第二步:防冲突。
status2 = PcdAnticoll(UID); //防冲撞处理,输出卡片序列号,4字节if(status2==MI_OK){PutString0("Card Id is:");tochar(UID[0]);tochar(UID[1]);tochar(UID[2]);tochar(UID[3]); //输出卡片序列号}第三步:选卡。
rc522模块基础教学
rc522模块基础教学
1. rc522模块简介
rc522模块是一款常用的射频识别模块,具有低成本,低功耗,较高的性能等优点。
它采用 ISO14443A/MIFARE卡协议,可以用来识别各类RFID标签,像门禁系统、考勤系统、刷卡消费等都离不开它。
此模块与其他模块如Arduino和树莓派等结合可以用来实现各种射频识别的应用。
2. rc522模块参数
rc522模块有两个特殊参数:
(1)频率:13.56 MHz
(2)数据传输速率:106 Kbps
3. rc522模块安装
(1)准备电路所需材料:
rc522模块(1个)
Arduino UNO(1个)
杜邦线(若干)
(2)接线安装:
将Arduino UNO和rc522模块的VCC接口用杜邦线连接到5V脚上;
将Arduino UNO和rc522模块的GND接口用杜邦线连接到GND脚上;
将Arduino UNO的3.3V脚和rc522模块的RST脚用杜邦线连接;
将Arduino UNO的SCK、MISO和MOSI引脚分别与rc522模块的SCK、MISO和MOSI引脚用杜邦线连接;
将Arduino UNO的D2引脚与rc522模块的SDA引脚用杜邦线连接。
RC522
本文设计的读卡器系统以PICl6F7x单片机作为主控芯片,选用MIFARE S50卡片,读卡器与卡片间以106kbps速率通信,同时实现读卡过程中的防冲突处理和对卡E2PROM块内容的读/写等功能。
读卡器内部设置了FLASH存储器以存放卡数据,在FLASH容量满的情况下可通过读卡器的以太网口读出全部数据到管理中心上位机,便于建立对卡数据的综合管理系统。
1 硬件系统设计读卡器硬件框图如图1所示。
单片机PICl6F7x通过SPI总线与RC522和FLASH芯片AT45D011相连,同时用简化的ISA 总线连接以太网接口芯片C58900,以提供连接到局域网的能力。
AT45D0ll存储容量为lMb,可同时存储7400多组MIFARE的E2PROM块和UID号,提供了足够读卡器一天内读取的信息量的存放容量。
对于RC522天线部分的设计,PHILIPS公司有专门的手册详细介绍,本文不再赘述。
RC522的SPI总线接口有其自身的时序要求。
它只能工作于从模式,最高传输速率为10 Mbps,数据与时钟相位关系满足“空闲态时钟为低电平,在时钟上升沿同步接收和发送数据,在下降沿数据转换”的约束关系。
PICl6F7x系列单片机的片上外设包括1个SSP模块。
该模块可配置为SPI接口使用,通过相应的寄存器可控制SPI接口的数据传输率、数据一时钟相位天系等通信参数。
本文中配置SSP模块工作于SPI主模式下,时钟为1/4单片机主频,接收和发送数据都在时钟上升沿发生。
需要注意的是,由于RC522支持的数字接口形式多种多样,因此芯片在每次复位时都会检测外部引脚连接关系。
对于SPI接口,RC522的相关引脚必须按照图2所示的连接关系配置。
除了通用的4条SPI信号线(时钟线SCK、输入数据线MOSI、输出数据线MOSO和选通线NSS)以外,RC522要求额外的2个引脚I2C和EA分别固定接低电平和高电平。
这2个引脚不参与SPI总线传输,只起设定RC522数字界面采用SPI接口的作用。
RC522通过SPI方式读写M1卡
1.准备工作战舰V3开发板,RC522模块为淘宝所买,赠送一张M1卡。
SPI方式实测可以读写。
2.RC522部分:rc522.h://///////////////////////////////////////////////////////////////////#include "sys.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#define SPIReadByte() SPIWriteByte(0)u8 SPIWriteByte(u8 byte);void SPI2_Init(void);#define SET_SPI_CS GPIO_SetBits(GPIOF,GPIO_Pin_0);#define CLR_SPI_CS GPIO_ResetBits(GPIOF,GPIO_Pin_0)#define SET_RC522RST GPIO_SetBits(GPIOF,GPIO_Pin_1);#define CLR_RC522RST GPIO_ResetBits(GPIOF,GPIO_Pin_1)void InitRc522(void);void Usart1_Send_String(unsigned char *str);void ClearBitMask(u8 reg,u8 mask);void WriteRawRC(u8 Address, u8 value);void SetBitMask(u8 reg,u8 mask);char PcdComMF522(u8 Command,u8 *pIn ,u8 InLenByte,u8 *pOut ,u8 *pOutLenBit);void CalulateCRC(u8 *pIn ,u8 len,u8 *pOut );u8 ReadRawRC(u8 Address);void PcdAntennaOn(void);char PcdReset(void);char PcdRequest(unsigned char req_code,unsigned char *pTagType);void PcdAntennaOn(void);void PcdAntennaOff(void);char M500PcdConfigISOType(unsigned char type);char PcdAnticoll(unsigned char *pSnr);char PcdSelect(unsigned char *pSnr);char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr);char PcdWrite(unsigned char addr,unsigned char *pData);char PcdRead(unsigned char addr,unsigned char *pData);char PcdHalt(void);void Reset_RC522(void);char PcdValue(u8 dd_mode,u8 addr,u8 *pValue);/////////////////////////////////////////////////////////////////////////////// ///////////////////////rc522.c:#include "sys.h"#include "rc522.h"#include "delay.h"void delay_ns(u32 ns){u32 i;for(i=0;i<ns;i++){__nop();__nop();__nop();}}u8 SPIWriteByte(u8 Byte){while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(SPI2, Byte);while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);return SPI_I2S_ReceiveData(SPI2);}//SPIx 读写一个字节//TxData:要写入的字节//返回值:读取到的字节u8 SPI2_ReadWriteByte(u8 TxData){u8 retry=0;while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位{retry++;if(retry>200)return 0;}SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据retry=0;while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位{retry++;if(retry>200)return 0;}return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据}void SPI2_Init(void){GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF, ENABLE );//PORTB时钟使能RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );//SPI2时钟使能GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //IO-->PF0、PF1 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOF, &GPIO_InitStructure); //根据设定参数初始化PF0、PF1GPIO_ResetBits(GPIOF,GPIO_Pin_1); //PF1输出低//GPIO_SetBits(GPIOF,GPIO_Pin_0);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PB13/14/15复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOBGPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //PB13/14/15上拉SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPISPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行同步时钟的空闲状态为低电平SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //串行同步时钟的第一个跳变沿(上升或下降)数据被采样SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; //定义波特率预分频的值:波特率预分频值为256SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式SPI_Init(SPI2, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器SPI_Cmd(SPI2, ENABLE); //使能SPI外设//SPI2_ReadWriteByte(0xff);//启动传输}void InitRc522(void){SPI2_Init();PcdReset();PcdAntennaOff();delay_ms(2);PcdAntennaOn();M500PcdConfigISOType( 'A' );}void Reset_RC522(void){PcdReset();PcdAntennaOff();delay_ms(2);PcdAntennaOn();}///////////////////////////////////////////////////////////////////////功能:寻卡//参数说明: req_code[IN]:寻卡方式// 0x52 = 寻感应区内所有符合14443A标准的卡// 0x26 = 寻未进入休眠状态的卡// pTagType[OUT]:卡片类型代码// 0x4400 = Mifare_UltraLight// 0x0400 = Mifare_One(S50)// 0x0200 = Mifare_One(S70)// 0x0800 = Mifare_Pro(X)// 0x4403 = Mifare_DESFire//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdRequest(u8 req_code,u8 *pTagType){char status;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ClearBitMask(Status2Reg,0x08);WriteRawRC(BitFramingReg,0x07);SetBitMask(TxControlReg,0x03);ucComMF522Buf[0] = req_code;status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x10)){*pTagType = ucComMF522Buf[0];*(pTagType+1) = ucComMF522Buf[1];}else{ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:防冲撞//参数说明: pSnr[OUT]:卡片序列号,4字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdAnticoll(u8 *pSnr){char status;u8 i,snr_check=0;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ClearBitMask(Status2Reg,0x08);WriteRawRC(BitFramingReg,0x00);ClearBitMask(CollReg,0x80);ucComMF522Buf[0] = PICC_ANTICOLL1;ucComMF522Buf[1] = 0x20;status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);if (status == MI_OK){for (i=0; i<4; i++){*(pSnr+i) = ucComMF522Buf[i];snr_check ^= ucComMF522Buf[i];}if (snr_check != ucComMF522Buf[i]){ status = MI_ERR; }}SetBitMask(CollReg,0x80);return status;}///////////////////////////////////////////////////////////////////////功能:选定卡片//参数说明: pSnr[IN]:卡片序列号,4字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdSelect(u8 *pSnr){char status;u8 i;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_ANTICOLL1;ucComMF522Buf[1] = 0x70;ucComMF522Buf[6] = 0;for (i=0; i<4; i++){ucComMF522Buf[i+2] = *(pSnr+i);ucComMF522Buf[6] ^= *(pSnr+i);}CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);ClearBitMask(Status2Reg,0x08);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x18)){ status = MI_OK; }else{ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:验证卡片密码//参数说明: auth_mode[IN]: 密码验证模式// 0x60 = 验证A密钥// 0x61 = 验证B密钥// addr[IN]:块地址// pKey[IN]:密码// pSnr[IN]:卡片序列号,4字节//返回: 成功返回MI_OK///////////////////////////////////////////////////////////////////// char PcdAuthState(u8 auth_mode,u8 addr,u8 *pKey,u8 *pSnr){char status;u8 unLen;u8 i,ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = auth_mode;ucComMF522Buf[1] = addr;// for (i=0; i<6; i++)// { ucComMF522Buf[i+2] = *(pKey+i); }// for (i=0; i<6; i++)// { ucComMF522Buf[i+8] = *(pSnr+i); }memcpy(&ucComMF522Buf[2], pKey, 6);memcpy(&ucComMF522Buf[8], pSnr, 4);status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08))){ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:读取M1卡一块数据//参数说明: addr[IN]:块地址// p [OUT]:读出的数据,16字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdRead(u8 addr,u8 *p ){char status;u8 unLen;u8 i,ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_READ;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x90))// { memcpy(p , ucComMF522Buf, 16); }{for (i=0; i<16; i++){ *(p +i) = ucComMF522Buf[i]; }}else{ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:写数据到M1卡一块//参数说明: addr[IN]:块地址// p [IN]:写入的数据,16字节//返回: 成功返回MI_OK///////////////////////////////////////////////////////////////////// char PcdWrite(u8 addr,u8 *p ){char status;u8 unLen;u8 i,ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_WRITE;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){ status = MI_ERR; }if (status == MI_OK){//memcpy(ucComMF522Buf, p , 16);for (i=0; i<16; i++){ucComMF522Buf[i] = *(p +i);}CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) { status = MI_ERR; }}return status;}///////////////////////////////////////////////////////////////////////功能:命令卡片进入休眠状态//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdHalt(void){u8 status;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_HALT;ucComMF522Buf[1] = 0;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);return MI_OK;}///////////////////////////////////////////////////////////////////////用MF522计算CRC16函数/////////////////////////////////////////////////////////////////////void CalulateCRC(u8 *pIn ,u8 len,u8 *pOut ){u8 i,n;ClearBitMask(DivIrqReg,0x04);WriteRawRC(CommandReg,PCD_IDLE);SetBitMask(FIFOLevelReg,0x80);for (i=0; i<len; i++){ WriteRawRC(FIFODataReg, *(pIn +i)); }WriteRawRC(CommandReg, PCD_CALCCRC);i = 0xFF;do{n = ReadRawRC(DivIrqReg);i--;}while ((i!=0) && !(n&0x04));pOut [0] = ReadRawRC(CRCResultRegL);pOut [1] = ReadRawRC(CRCResultRegM);}///////////////////////////////////////////////////////////////////////功能:复位RC522//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdReset(void){//PORTD|=(1<<RC522RST);SET_RC522RST;delay_ns(10);//PORTD&=~(1<<RC522RST);CLR_RC522RST;delay_ns(10);//PORTD|=(1<<RC522RST);SET_RC522RST;delay_ns(10);WriteRawRC(CommandReg,PCD_RESETPHASE);WriteRawRC(CommandReg,PCD_RESETPHASE);delay_ns(10);WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363 WriteRawRC(TReloadRegL,30);WriteRawRC(TReloadRegH,0);WriteRawRC(TModeReg,0x8D);WriteRawRC(TPrescalerReg,0x3E);WriteRawRC(TxAutoReg,0x40);//必须要return MI_OK;}////////////////////////////////////////////////////////////////////////设置RC632的工作方式//////////////////////////////////////////////////////////////////////char M500PcdConfigISOType(u8 type){if (type == 'A') //ISO14443_A{ClearBitMask(Status2Reg,0x08);WriteRawRC(ModeReg,0x3D);//3FWriteRawRC(RxSelReg,0x86);//84WriteRawRC(RFCfgReg,0x7F); //4FWriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec)WriteRawRC(TReloadRegH,0);WriteRawRC(TModeReg,0x8D);WriteRawRC(TPrescalerReg,0x3E);delay_ns(1000);PcdAntennaOn();}else{ return 1; }return MI_OK;}///////////////////////////////////////////////////////////////////////功能:读RC632寄存器//参数说明:Address[IN]:寄存器地址//返回:读出的值/////////////////////////////////////////////////////////////////////u8 ReadRawRC(u8 Address){u8 ucAddr;u8 ucResult=0;CLR_SPI_CS;ucAddr = ((Address<<1)&0x7E)|0x80;SPIWriteByte(ucAddr);delay_ms(5);ucResult=SPIReadByte();delay_ms(5);SET_SPI_CS;return ucResult;}///////////////////////////////////////////////////////////////////////功能:写RC632寄存器//参数说明:Address[IN]:寄存器地址// value[IN]:写入的值void WriteRawRC(u8 Address, u8 value){u8 ucAddr;// u8 tmp;CLR_SPI_CS;ucAddr = ((Address<<1)&0x7E);SPIWriteByte(ucAddr);delay_ms(5);SPIWriteByte(value);delay_ms(5);SET_SPI_CS;// tmp=ReadRawRC(Address);//// if(value!=tmp)// printf("wrong\n");}///////////////////////////////////////////////////////////////////// //功能:置RC522寄存器位//参数说明:reg[IN]:寄存器地址// mask[IN]:置位值///////////////////////////////////////////////////////////////////// void SetBitMask(u8 reg,u8 mask){char tmp = 0x0;tmp = ReadRawRC(reg);WriteRawRC(reg,tmp | mask); // set bit mask}///////////////////////////////////////////////////////////////////// //功能:清RC522寄存器位//参数说明:reg[IN]:寄存器地址// mask[IN]:清位值///////////////////////////////////////////////////////////////////// void ClearBitMask(u8 reg,u8 mask){char tmp = 0x0;tmp = ReadRawRC(reg);WriteRawRC(reg, tmp & ~mask); // clear bit mask}//功能:通过RC522和ISO14443卡通讯//参数说明:Command[IN]:RC522命令字// pIn [IN]:通过RC522发送到卡片的数据// InLenByte[IN]:发送数据的字节长度// pOut [OUT]:接收到的卡片返回数据// *pOutLenBit[OUT]:返回数据的位长度///////////////////////////////////////////////////////////////////// char PcdComMF522(u8 Command,u8 *pIn ,u8 InLenByte,u8 *pOut ,u8 *pOutLenBit){char status = MI_ERR;u8 irqEn = 0x00;u8 waitFor = 0x00;u8 lastBits;u8 n;u16 i;switch (Command){case PCD_AUTHENT:irqEn = 0x12;waitFor = 0x10;break;case PCD_TRANSCEIVE:irqEn = 0x77;waitFor = 0x30;break;default:break;}WriteRawRC(ComIEnReg,irqEn|0x80);ClearBitMask(ComIrqReg,0x80); //清所有中断位WriteRawRC(CommandReg,PCD_IDLE);SetBitMask(FIFOLevelReg,0x80); //清FIFO缓存for (i=0; i<InLenByte; i++){ WriteRawRC(FIFODataReg, pIn [i]); }WriteRawRC(CommandReg, Command);// n = ReadRawRC(CommandReg);if (Command == PCD_TRANSCEIVE){ SetBitMask(BitFramingReg,0x80); } //开始传送//i = 600;//根据时钟频率调整,操作M1卡最大等待时间25msi = 2000;do{n = ReadRawRC(ComIrqReg);i--;}while ((i!=0) && !(n&0x01) && !(n&waitFor));ClearBitMask(BitFramingReg,0x80);if (i!=0){if(!(ReadRawRC(ErrorReg)&0x1B)){status = MI_OK;if (n & irqEn & 0x01){ status = MI_NOTAGERR; }if (Command == PCD_TRANSCEIVE){n = ReadRawRC(FIFOLevelReg);lastBits = ReadRawRC(ControlReg) & 0x07;if (lastBits){ *pOutLenBit = (n-1)*8 + lastBits; }else{ *pOutLenBit = n*8; }if (n == 0){ n = 1; }if (n > MAXRLEN){ n = MAXRLEN; }for (i=0; i<n; i++){ pOut [i] = ReadRawRC(FIFODataReg); } }}else{ status = MI_ERR; }}SetBitMask(ControlReg,0x80); // stop timer now WriteRawRC(CommandReg,PCD_IDLE);return status;}///////////////////////////////////////////////////////////////////////开启天线//每次启动或关闭天险发射之间应至少有1ms的间隔/////////////////////////////////////////////////////////////////////void PcdAntennaOn(void){u8 i;i = ReadRawRC(TxControlReg);if (!(i & 0x03)){SetBitMask(TxControlReg, 0x03);}}///////////////////////////////////////////////////////////////////////关闭天线/////////////////////////////////////////////////////////////////////void PcdAntennaOff(void){ClearBitMask(TxControlReg, 0x03);}///////////////////////////////////////////////////////////////////////功能:扣款和充值//参数说明: dd_mode[IN]:命令字// 0xC0 = 扣款// 0xC1 = 充值// addr[IN]:钱包地址// pValue[IN]:4字节增(减)值,低位在前//返回: 成功返回MI_OK///////////////////////////////////////////////////////////////////// char PcdValue(u8 dd_mode,u8 addr,u8 *pValue){char status;u8 unLen;u8 ucComMF522Buf[MAXRLEN];//u8 i;ucComMF522Buf[0] = dd_mode;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) { status = MI_ERR; }if (status == MI_OK){memcpy(ucComMF522Buf, pValue, 4);//for (i=0; i<16; i++)//{ ucComMF522Buf[i] = *(pValue+i); }CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]);unLen = 0;status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen);if (status != MI_ERR){ status = MI_OK; }}if (status == MI_OK){ucComMF522Buf[0] = PICC_TRANSFER;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) { status = MI_ERR; }}return status;}art部分用的串口1,打印读写数据到串口调试助手,hex_to_str函数为16进制转换为字符格式,可以不转换,直接串口打印数据,串口调试助手需要勾选hex。
RC522 调试笔记
RC522调试笔记任永2011年1月11日晴准备工作1、阅读文档,了解RC522的UART工作方式。
2、初始化RC522为UART工作方式。
3、初始化化RC5224、查看初始化结果是否成功5、示波器测试PCB发送天线参数。
寄存器位行为描述UART读数据帧结构UART写数据帧结构命令概要命令概要命令命令码行为描述空闲0000无其它多余动作,取消当前命令的执行存储0001存储25个字节到内部缓冲区产生随机数ID0010生成一个10字节的随机ID号计算CRC码0011激活CRC协处理器或执行自检发送0100发送FIFO缓冲区中数据无命令0111没有命令变化,可以用来修改,而不会影响命令CommandReg寄存器。
接收1000激活接收电路收发器1100发送FIFO缓冲区中数据传输到天线,并自动激活后传输接收机。
——1101保留,将来使用MFIFARE认证1110执行MIFARE标准认证作为阅读器软复位1111复位MFRC5222011年1月12日晴初步调试使用串口调试助手1、选择使用串口号;2、设置波特率9600,起始位1bit,数据位8bit,停止位1bit,无奇偶效验,无流控制位;3、设置发送数据格式十六进制(HEX),接收数据显示格式十六进制。
4、打开串口。
5、填写发送数据(HEX格式)。
6、发送;7、观察返回数据(HEX格式)8、示波器测试各个测试点。
8.1、天线TX1,TX2,低通滤波电路,匹配电路9、测试捕获卡片距离。
测试结果:可以在2cm内捕获卡片;缺陷:捕获卡片距离太近,需要提升捕获距离。
2011年1月13日阴调试捕获卡片距离,获取卡片数据1、示波器测试各个测试点。
8.1、天线TX1,TX2,低通滤波电路,匹配电路2、调整天线匹配电容参数3、改变天线的发磁场方向。
结果:卡片捕获距离提升到4cm以上;缺陷:对低质量卡片捕获距离还是不够高,在3cm左右;需要调整。
下一步工作计划:1、绘制RC522工作流程图2、编写RC522流程函数代码3、调试RC522阅读卡片速度能力4、与系统软件进行合成(合并)调试。
STM8 RC522 读写IC卡程序
#include "stm8s.h"#include "uart.h"void Delay(u32 nCount);extern u8 RxBuffer[RxBufferSize];extern u8 UART_RX_NUM;unsigned char CT[2];//卡类型unsigned char SN[4]; //卡号unsigned char write[16] ={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10}; unsigned char read[16] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; unsigned char key[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};#define countof(a) (sizeof(a) / sizeof(*(a)))#define BufferSize (countof(Tx_Buffer)-1)u8 Tx_Buffer[] = "STM8S RFID TEST";u8 Rx_Buffer[BufferSize];u32 FLASH_ID ;void cardNo2String(u8 *cardNo, u8 *str);void main(void){unsigned char status;/*设置内部时钟16M为主时钟*/CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);status = memcmp(read,write,16);GPIO_DeInit(GPIOA);GPIO_DeInit(GPIOC);Uart_Init();GPIO_Init( GPIOA, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST);InitRc522();UART2_SendString(Tx_Buffer,BufferSize);while(1){status = PcdRequest(PICC_REQALL,CT); /*扫描卡*/status = PcdAnticoll(SN); /*防冲撞*/if (status==MI_OK){GPIO_LOW(GPIOA, GPIO_PIN_4); //寻卡成功UART2_SendString(Tx_Buffer, 17);Reset_RC522();}else{GPIO_HIGH(GPIOA, GPIO_PIN_4);}}}void Delay(u32 nCount){while (nCount != 0){nCount--;}}void Hex2String(u8 hex,u8 *str){str[0] = (hex / 100) + '0';str[1] = (hex % 100 / 10) + '0';str[2] = (hex % 10) + '0';}void cardNo2String(u8 *cardNo, u8 *str){u8 Count = 0;for(Count = 0; Count < 4; Count++){Hex2String(cardNo[Count], str + Count * 4);if(Count == 3){str[15] = '\n';}else{str[Count * 4 + 3] = ':';}}}void delay_ns(u32 ns)for(i=0;i<ns;i++){asm("nop");asm("nop");asm("nop");}}u8 SPIWriteByte(u8 Byte){u8 tmp;while (SPI_GetFlagStatus( SPI_FLAG_TXE) == RESET);SPI_SendData(Byte);if (SPI_GetFlagStatus(SPI_FLAG_RXNE)){tmp = SPI_ReceiveData();}return tmp;}void SPI2_Init(void){SPI_DeInit();SPI_Init(SPI_FIRSTBIT_MSB, //帧模式,先发送MSB还是LSBSPI_BAUDRATEPRESCALER_8, //波特率分频值SPI_MODE_MASTER, //模式,主从模式SPI_CLOCKPOLARITY_LOW, //时钟极性,空闲时SCK为高/空闲时SCK为低SPI_CLOCKPHASE_1EDGE, //数据采样的边沿选择SPI_DATADIRECTION_2LINES_FULLDUPLEX, //双线单向数据模式,使用C6/C7两条线,数据传输方向位单向SPI_NSS_SOFT, //软件从设备0x07);SPI_Cmd(ENABLE);}void InitRc522(void){SPI2_Init();PcdReset();PcdAntennaOff();PcdAntennaOn();M500PcdConfigISOType( 'A' );}{PcdReset();PcdAntennaOff();PcdAntennaOn();}///////////////////////////////////////////////////////////////////////功能:寻卡//参数说明: req_code[IN]:寻卡方式// 0x52 = 寻感应区内所有符合14443A标准的卡// 0x26 = 寻未进入休眠状态的卡// pTagType[OUT]:卡片类型代码// 0x4400 = Mifare_UltraLight// 0x0400 = Mifare_One(S50)// 0x0200 = Mifare_One(S70)// 0x0800 = Mifare_Pro(X)// 0x4403 = Mifare_DESFire//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdRequest(u8 req_code,u8 *pTagType){char status;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ClearBitMask(Status2Reg,0x08);WriteRawRC(BitFramingReg,0x07);SetBitMask(TxControlReg,0x03);ucComMF522Buf[0] = req_code;status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x10)){*pTagType = ucComMF522Buf[0];*(pTagType+1) = ucComMF522Buf[1];}else{ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:防冲撞//参数说明: pSnr[OUT]:卡片序列号,4字节char PcdAnticoll(u8 *pSnr){char status;u8 i,snr_check=0;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ClearBitMask(Status2Reg,0x08);WriteRawRC(BitFramingReg,0x00);ClearBitMask(CollReg,0x80);ucComMF522Buf[0] = PICC_ANTICOLL1;ucComMF522Buf[1] = 0x20;status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);if (status == MI_OK){for (i=0; i<4; i++){*(pSnr+i) = ucComMF522Buf[i];snr_check ^= ucComMF522Buf[i];}if (snr_check != ucComMF522Buf[i]){ status = MI_ERR; }}SetBitMask(CollReg,0x80);return status;}///////////////////////////////////////////////////////////////////////功能:选定卡片//参数说明: pSnr[IN]:卡片序列号,4字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdSelect(u8 *pSnr){char status;u8 i;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_ANTICOLL1;ucComMF522Buf[1] = 0x70;ucComMF522Buf[6] = 0;ucComMF522Buf[i+2] = *(pSnr+i);ucComMF522Buf[6] ^= *(pSnr+i);}CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);ClearBitMask(Status2Reg,0x08);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x18)){ status = MI_OK; }else{ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:验证卡片密码//参数说明: auth_mode[IN]: 密码验证模式// 0x60 = 验证A密钥// 0x61 = 验证B密钥// addr[IN]:块地址// pKey[IN]:密码// pSnr[IN]:卡片序列号,4字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdAuthState(u8 auth_mode,u8 addr,u8 *pKey,u8 *pSnr){char status;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = auth_mode;ucComMF522Buf[1] = addr;memcpy(&ucComMF522Buf[2], pKey, 6);memcpy(&ucComMF522Buf[8], pSnr, 4);status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08))){ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:读取M1卡一块数据//参数说明: addr[IN]:块地址// p [OUT]:读出的数据,16字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char status;u8 unLen;u8 i,ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_READ;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x90)){for (i=0; i<16; i++){ *(p +i) = ucComMF522Buf[i]; }}else{ status = MI_ERR; }return status;}///////////////////////////////////////////////////////////////////////功能:写数据到M1卡一块//参数说明: addr[IN]:块地址// p [IN]:写入的数据,16字节//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdWrite(u8 addr,u8 *p ){char status;u8 unLen;u8 i,ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_WRITE;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){ status = MI_ERR; }if (status == MI_OK){for (i=0; i<16; i++){ucComMF522Buf[i] = *(p +i);}status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){ status = MI_ERR; }}return status;}///////////////////////////////////////////////////////////////////////功能:命令卡片进入休眠状态//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdHalt(void){u8 status;u8 unLen;u8 ucComMF522Buf[MAXRLEN];ucComMF522Buf[0] = PICC_HALT;ucComMF522Buf[1] = 0;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);return MI_OK;}///////////////////////////////////////////////////////////////////////用MF522计算CRC16函数/////////////////////////////////////////////////////////////////////void CalulateCRC(u8 *pIn ,u8 len,u8 *pOut ){u8 i,n;ClearBitMask(DivIrqReg,0x04);WriteRawRC(CommandReg,PCD_IDLE);SetBitMask(FIFOLevelReg,0x80);for (i=0; i<len; i++){ WriteRawRC(FIFODataReg, *(pIn +i)); }WriteRawRC(CommandReg, PCD_CALCCRC);i = 0xFF;do{n = ReadRawRC(DivIrqReg);i--;}while ((i!=0) && !(n&0x04));pOut [0] = ReadRawRC(CRCResultRegL);///////////////////////////////////////////////////////////////////////功能:复位RC522//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdReset(void){GPIO_HIGH(RC522RST_GPIO_PORT,RC522RST_GPIO_PIN);delay_ns(10);GPIO_LOW(RC522RST_GPIO_PORT,RC522RST_GPIO_PIN);delay_ns(10);GPIO_HIGH(RC522RST_GPIO_PORT,RC522RST_GPIO_PIN);delay_ns(10);WriteRawRC(CommandReg,PCD_RESETPHASE);delay_ns(10);WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363 WriteRawRC(TReloadRegL,30);WriteRawRC(TReloadRegH,0);WriteRawRC(TModeReg,0x8D);WriteRawRC(TPrescalerReg,0x3E);WriteRawRC(TxAutoReg,0x40);//必须要return MI_OK;}////////////////////////////////////////////////////////////////////////设置RC632的工作方式//////////////////////////////////////////////////////////////////////char M500PcdConfigISOType(u8 type){if (type == 'A') //ISO14443_A{ClearBitMask(Status2Reg,0x08);WriteRawRC(ModeReg,0x3D);WriteRawRC(RxSelReg,0x86);WriteRawRC(RFCfgReg,0x7F);WriteRawRC(TReloadRegL,30);WriteRawRC(TReloadRegH,0);WriteRawRC(TModeReg,0x8D);WriteRawRC(TPrescalerReg,0x3E);delay_ns(1000);else{return 1;}return MI_OK;}///////////////////////////////////////////////////////////////////////功能:读RC632寄存器//参数说明:Address[IN]:寄存器地址//返回:读出的值/////////////////////////////////////////////////////////////////////u8 ReadRawRC(u8 Address){u8 ucAddr;u8 ucResult=0;GPIO_LOW(RC522NSS_GPIO_PORT,RC522NSS_GPIO_PIN);ucAddr = ((Address<<1)&0x7E)|0x80;SPIWriteByte(ucAddr);ucResult=SPIReadByte();GPIO_HIGH(RC522NSS_GPIO_PORT,RC522NSS_GPIO_PIN);return ucResult;}///////////////////////////////////////////////////////////////////////功能:写RC632寄存器//参数说明:Address[IN]:寄存器地址// value[IN]:写入的值/////////////////////////////////////////////////////////////////////void WriteRawRC(u8 Address, u8 value){u8 ucAddr;GPIO_LOW(RC522NSS_GPIO_PORT,RC522NSS_GPIO_PIN);ucAddr = ((Address<<1)&0x7E);SPIWriteByte(ucAddr);SPIWriteByte(value);GPIO_HIGH(RC522NSS_GPIO_PORT,RC522NSS_GPIO_PIN);}///////////////////////////////////////////////////////////////////////功能:置RC522寄存器位//参数说明:reg[IN]:寄存器地址// mask[IN]:置位值{char tmp = 0x0;tmp = ReadRawRC(reg);WriteRawRC(reg,tmp | mask); // set bit mask}///////////////////////////////////////////////////////////////////////功能:清RC522寄存器位//参数说明:reg[IN]:寄存器地址// mask[IN]:清位值/////////////////////////////////////////////////////////////////////void ClearBitMask(u8 reg,u8 mask){char tmp = 0x0;tmp = ReadRawRC(reg);WriteRawRC(reg, tmp & ~mask); // clear bit mask }///////////////////////////////////////////////////////////////////////功能:通过RC522和ISO14443卡通讯//参数说明:Command[IN]:RC522命令字// pIn [IN]:通过RC522发送到卡片的数据// InLenByte[IN]:发送数据的字节长度// pOut [OUT]:接收到的卡片返回数据// *pOutLenBit[OUT]:返回数据的位长度/////////////////////////////////////////////////////////////////////char PcdComMF522(u8 Command,u8 *pIn ,u8 InLenByte,u8 *pOut ,u8 *pOutLenBit){char status = MI_ERR;u8 irqEn = 0x00;u8 waitFor = 0x00;u8 lastBits;u8 n;u16 i;switch (Command){case PCD_AUTHENT:irqEn = 0x12;waitFor = 0x10;break;case PCD_TRANSCEIVE:irqEn = 0x77;waitFor = 0x30;break;default:break;}WriteRawRC(ComIEnReg,irqEn|0x80);ClearBitMask(ComIrqReg,0x80); //清所有中断位WriteRawRC(CommandReg,PCD_IDLE);SetBitMask(FIFOLevelReg,0x80); //清FIFO缓存for (i=0; i<InLenByte; i++){WriteRawRC(FIFODataReg, pIn [i]);}WriteRawRC(CommandReg, Command);// n = ReadRawRC(CommandReg);if (Command == PCD_TRANSCEIVE){SetBitMask(BitFramingReg,0x80); //开始传送}//i = 600;//根据时钟频率调整,操作M1卡最大等待时间25msi = 10000;do{n = ReadRawRC(ComIrqReg);i--;}while ((i!=0) && !(n&0x01) && !(n&waitFor));ClearBitMask(BitFramingReg,0x80);if (i!=0){if(!(ReadRawRC(ErrorReg)&0x1B)){status = MI_OK;if (n & irqEn & 0x01){status = MI_NOTAGERR;}if (Command == PCD_TRANSCEIVE){n = ReadRawRC(FIFOLevelReg);lastBits = ReadRawRC(ControlReg) & 0x07;if (lastBits){*pOutLenBit = (n-1)*8 + lastBits;}else{*pOutLenBit = n*8;}if (n == 0){n = 1;}if (n > MAXRLEN){n = MAXRLEN;}for (i=0; i<n; i++){pOut[i] = ReadRawRC(FIFODataReg);}}}else{status = MI_ERR;}}SetBitMask(ControlReg,0x80); // stop timer now WriteRawRC(CommandReg,PCD_IDLE);return status;}///////////////////////////////////////////////////////////////////////开启天线//每次启动或关闭天险发射之间应至少有1ms的间隔/////////////////////////////////////////////////////////////////////void PcdAntennaOn(void){u8 i;i = ReadRawRC(TxControlReg);if (!(i & 0x03)){SetBitMask(TxControlReg, 0x03);}}///////////////////////////////////////////////////////////////////////关闭天线/////////////////////////////////////////////////////////////////////void PcdAntennaOff(void){ClearBitMask(TxControlReg, 0x03);}///////////////////////////////////////////////////////////////////////功能:扣款和充值//参数说明: dd_mode[IN]:命令字// 0xC0 = 扣款// 0xC1 = 充值// addr[IN]:钱包地址// pValue[IN]:4字节增(减)值,低位在前//返回: 成功返回MI_OK/////////////////////////////////////////////////////////////////////char PcdValue(u8 dd_mode,u8 addr,u8 *pValue){char status;u8 unLen;u8 ucComMF522Buf[MAXRLEN];//u8 i;ucComMF522Buf[0] = dd_mode;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){status = MI_ERR;}if (status == MI_OK){memcpy(ucComMF522Buf, pValue, 4);//for (i=0; i<16; i++)//{ ucComMF522Buf[i] = *(pValue+i); }CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]);unLen = 0;status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen);if (status != MI_ERR){ status = MI_OK; }}if (status == MI_OK){ucComMF522Buf[0] = PICC_TRANSFER;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){ status = MI_ERR; }}return status;}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
TJDZ-RC522 RFID读卡模块
用户操作手册
Ver_1.0_20121101
RC522 RFID读卡模块使用说明
(以MSP430F149处理器为例)
第一步:将RFID模块与MSP430F149最小系统板采用杜邦线连接;
第二步:程序通过BSL下载到MSP430F149中;
第三步:将串口线USB-RS232连接计算机与开发板;
第四步:打开串口调试手(正确设置波特率以及串口号);
第五步:按MSP430F149最小系统板上的复位键,则串口调试手出现如下画面:
第六步:在串口发送区,输入A点击发送,为自动寻卡模式;若输入F点击发送则为单次寻卡模式;
第七步:将卡片放到读卡模块上,则可以看到读出卡的ID号。
测试完毕。