当前位置:网站首页>STM32+MFRC522完成IC卡号读取、密码修改、数据读写
STM32+MFRC522完成IC卡号读取、密码修改、数据读写
2022-07-06 10:17:00 【华为云】
一、环境介绍
MCU: STM32F103ZET6
开发软件: Keil5
非接触式读写卡模块: MFRC522
二、功能介绍
使用MFRC522模块完成对IC卡卡号读取、卡类型区分、IC卡扇区密码修改、扇区数据读写等功能;底层采用SPI模拟时序,可以很方便的移植到其他设备,完成项目开发。 现在很多嵌入式方向的作业设计经常使用到该模块,比如: 校园一卡通设计、水卡充值消费设计、公交卡充值消费设计等。
三、MFR522介绍
MF RC522 是应用于13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员。是NXP 公司针对“三表”应用推出的一款低电压、低成本、体积小的非接触式读写卡芯片,是智能仪表和便携式手持设备研发的较好选择。
MF RC522 利用了先进的调制和解调概念,完全集成了在13.56MHz 下所有类型的被动非接触式通信方式和协议。支持 ISO14443A 的多层应用。其内部发送器部分可驱动读写器天线与ISO 14443A/MIFARE卡和应答机的通信,无需其它的电路。接收器部分提供一个坚固而有效的解调和解码电路,用于处理ISO14443A 兼容的应答器信号。数字部分处理ISO14443A 帧和错误检测(奇偶 &CRC)。此外,它还支持快速CRYPTO1 加密算法,用于验证MIFARE 系列产品。MFRC522 支持MIFARE?更高速的非接触式通信,双向数据传输速率高达424kbit/s。
作为13.56MHz 高集成度读写卡系列芯片家族的新成员,MF RC522 与MF RC500和 MF RC530 有不少相似之处,同时也具备诸多特点和差异。它与主机间的通信采用连线较少的串行通信,且可根据不同的用户需求,选取SPI、I2C 或串行UART(类似RS232)模式之一,有利于减少连线,缩小PCB 板体积,降低成本。
四、IC卡介绍
非接触式IC卡又称射频卡,由IC芯片、感应天线组成,封装在一个标准的PVC卡片内,芯片及天线无任何外露部分。是世界上最近几年发展起来的一项新技术,它成功的将射频识别技术和IC卡技术结合起来,结束了无源(卡中无电源)和免接触这一难题,是电子器件领域的一大突破。卡片在一定距离范围(通常为5—10cm)靠近读写器表面,通过无线电波的传递来完成数据的读写操作。
射频读写器向IC卡发一组固定频率的电磁波,卡片内有一个LC串联谐振电路,其频率与读写器发射的频率相同,这样在电磁波激励下,LC谐振电路产生共振,从而使电容内有了电荷;在这个电荷的另一端,接有一个单向导通的电子泵,将电容内的电荷送到另一个电容内存储,当所积累的电荷达到2V时,此电容可作为电源为其它电路提供工作电压,将卡内数据发射出去或接受读写器的数据。
非接触性IC卡与读卡器之间通过无线电波来完成读写操作。二者之间的通讯频率为13.56MHZ。非接触性IC卡本身是无源卡,当读写器对卡进行读写操作时,读写器发出的信号由两部分叠加组成:一部分是电源信号,该信号由卡接收后,与本身的L/C产生一个瞬间能量来供给芯片工作。另一部分则是指令和数据信号,指挥芯片完成数据的读取、修改、储存等,并返回信号给读写器,完成一次读写操作。读写器则一般由单片机,专用智能模块和天线组成,并配有与PC的通讯接口,打印口,I/O口等,以便应用于不同的领域。
M1卡详细指标
M1卡是指M1芯片,是指菲利浦下属子公司恩智浦出品的芯片缩写,全称为NXP Mifare1系列,常用的有S50及S70两种型号。
M1(S50)卡详细规格:
- 芯片类型:PhilipsMifare1ICS50
- 存储容量:8Kbit,16个分区,每分区两组密码;
- 工作频率:13.56?MHz;
- 通讯速率:106KBoud;
- 读写距离:2.5~10cm;
- 读写时间:1~2ms;
- 工作温度:-20℃~55℃;
- 擦写寿命:>100,000次;
- 数据保存:>10年;
- 外形尺寸:ISO标准卡85.6x54x0.82;
- 封装材料:PVC、PET、PETG、0.13mm铜线;
Mifare S50和Mifare S70又常被称为Mifare Standard、Mifare Classic、MF1,是遵守ISO14443A标准的卡片中应用最为广、影响力最大的的一员。而Mifare S70的容量是S50的4倍,S50的容量是1K字节,S70的容量为4K字节。
读写器对卡片的操作时序和操作命令,二者完全一致。 Mifare S50和Mifare S70的每张卡片都有一个4字节的全球唯一序列号,卡上数据保存期为10年,可改写10万次,读无限次。一般的应用中,不用考虑卡片是否会被读坏写坏的问题,
当然暴力硬损坏除外。 Mifare S50和Mifare S70的区别主要有两个方面。一是读写器对卡片发出请求命令,二者应答返回的卡类型(ATQA)字节不同。Mifare S50的卡类型(ATQA)是0004H,Mifare S70的卡类型(ATQA)是0002H。另一个区别就是二者的容量和内存结构不同。
M1卡分为16个扇区,每个扇区由4块(0、1、2、3)组成。实际操作时,将16个扇区分为64个块,按绝对地址编号为0-63。
结构如下:
- 第0个扇区用于存放厂商代码,意见固话,不可更改。
- 每个扇区的块0、块1、块2为数据块,可以用于存储数据。数据块可以进行读写操作。
- 每个扇区的块3为控制块,包括了密码A、存储控制、密码B。具体结构如下:
- 每个扇区的密码和控制位都是独立的,可以根据实际需求设定各自的密码及存取控制。存取控制为4个字节,共32位,扇区中的每个块(包括数据和控制块)存取条件是由密码和存取控制共同决定的,在存取控制中每个块都有一个相应的三个控制位。定义如下:
Mifare 1 S50 白卡读写时一般步骤: 寻卡–>下载块密码–> 读写块数据。控制块也是一样。
数据块的访问权限设置表格:(根据自己需要的权限,完成上图字节6、7、8的填充即可)
控制块的读写权限设置:(包含了对密码A**、控制权限、密码的读写权限**)
7 6 5 4 3 2 1 0
字节6 1 1 1 1 1 1 1 1
字节7 0 0 0 0 1 1 1 1
字节8 0 0 0 0 0 0 0 0
字节9
设置的控制权限如下:0xFF 0x0F 0x00 0x00
代表数据块的权限: 验证密码A或者密码B都可以对数据块进行读写操作或者加值键值操作。
- 代表控制块的权限
(1) 验证A密码之后可以写A/B密码,不能读密码。
可以读控制字节(4个),无法写控制字节 可以读写B密码
(2) 验证B密码之后,可以读写A/B密码,也可读控制字节,但无法写控制字节。
五、核心代码
5.1 rc522.c
#include "sys.h"#include "RFID_RC522.h"#include "delay.h"#include "string.h"#include "usart.h"/*函数功能:移植接口--SPI时序读写一个字节函数参数:data:要写入的数据返 回 值:读到的数据*/u8 RC522_SPI_ReadWriteOneByte(u8 tx_data){ u8 rx_data=0; u8 i; for(i=0;i<8;i++) { RC522_SCLK=0; if(tx_data&0x80){RC522_OUTPUT=1;} else {RC522_OUTPUT=0;} tx_data<<=1; RC522_SCLK=1; rx_data<<=1; if(RC522_INPUT)rx_data|=0x01; } return rx_data; }/*函数功能:初始化RC522的IO口 */void RC522_IO_Init(void){ RCC->APB2ENR|=1<<2; //PA时钟使能 RCC->APB2ENR|=1<<7; //PF时钟使能 //PA5 时钟 RC522_SCLK //PA6 输入 RC522_INPUT //PA7 输出 RC522_OUTPUT GPIOA->CRL&=0x000FFFFF; GPIOA->CRL|=0x38300000; GPIOA->ODR|=0x3<<5; //RC522_RST <----->PF1--复位脚 //RC522_SDA <----->PF0--片选脚 GPIOF->CRL&=0xFFFFFF00; GPIOF->CRL|=0x00000033; GPIOF->ODR|=0x3<<0;} /*功能描述:选卡读取卡存储器容量输入参数:serNum 传入卡序列号返 回 值:成功返回卡容量*/u8 RC522_MFRC522_SelectTag(u8 *serNum) //读取卡存储器容量{ u8 i; u8 status; u8 size; u8 recvBits; u8 buffer[9]; buffer[0]=PICC_ANTICOLL1; //防撞码1 buffer[1]=0x70; buffer[6]=0x00; for(i=0;i<4;i++) { buffer[i+2]=*(serNum+i); //buffer[2]-buffer[5]为卡序列号 buffer[6]^=*(serNum+i); //卡校验码 } RC522_CalulateCRC(buffer,7,&buffer[7]); //buffer[7]-buffer[8]为RCR校验码 RC522_ClearBitMask(Status2Reg,0x08); status=RC522_PcdComMF522(PCD_TRANSCEIVE,buffer,9,buffer,&recvBits); if((status==MI_OK)&&(recvBits==0x18)) size=buffer[0]; else size=0; return size; }/*延时函数,纳秒级*/void RC522_Delay(u32 ns){ u32 i; for(i=0;i<ns;i++) { __nop(); __nop(); __nop(); }}/*函数功能:RC522芯片初始化*/void RC522_Init(void){ RC522_IO_Init(); //RC522初始化 RC522_PcdReset(); //复位RC522 RC522_PcdAntennaOff(); //关闭天线 DelayMs(2); //延时2毫秒 RC522_PcdAntennaOn(); //开启天线 M500PcdConfigISOType('A'); //设置RC632的工作方式}/*函数功能:复位RC522*/void RC522_Reset(void){ RC522_PcdReset(); //复位RC522 RC522_PcdAntennaOff(); //关闭天线 DelayMs(2); //延时2毫秒 RC522_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 RC522_PcdRequest(u8 req_code,u8 *pTagType){ char status; u8 unLen; u8 ucComMF522Buf[MAXRLEN]; // MAXRLEN 18 RC522_ClearBitMask(Status2Reg,0x08); //清RC522寄存器位,/接收数据命令 RC522_WriteRawRC(BitFramingReg,0x07); //写RC632寄存器 RC522_SetBitMask(TxControlReg,0x03); //置RC522寄存器位 ucComMF522Buf[0]=req_code; //寻卡方式 status=RC522_PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen); //通过RC522和ISO14443卡通讯 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 RC522_PcdAnticoll(u8 *pSnr){ char status; u8 i,snr_check=0; u8 unLen; u8 ucComMF522Buf[MAXRLEN]; RC522_ClearBitMask(Status2Reg,0x08); //清RC522寄存器位 RC522_WriteRawRC(BitFramingReg,0x00); //写 RC522_ClearBitMask(CollReg,0x80); //清 ucComMF522Buf[0]=PICC_ANTICOLL1; //PICC_ANTICOLL1 = 0x93 ucComMF522Buf[1]=0x20; status=RC522_PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen); //0x0c,通过RC522和ISO14443卡通讯 //PCD_TRANSCEIVE =发送并接收数据 //2:写入卡里的数据字节长度 //ucComMF522Buf:存放数据的地址 //unLen:从卡里读出的数据长度 if(status==MI_OK) { for(i=0;i<4;i++) { *(pSnr+i)=ucComMF522Buf[i]; //把读到的卡号赋值给pSnr snr_check^=ucComMF522Buf[i]; } if(snr_check!=ucComMF522Buf[i]) { status = MI_ERR; } } RC522_SetBitMask(CollReg,0x80); return status;}/*功 能:选定卡片参数说明:pSnr[IN]:卡片序列号,4字节返 回:成功返回MI_OK*/char RC522_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); } RC522_CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]); //用MF522计算CRC16函数,校验数据 RC522_ClearBitMask(Status2Reg,0x08); //清RC522寄存器位 status=RC522_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 RC522_PcdAuthState(u8 auth_mode,u8 addr,u8 *pKey,u8 *pSnr){ char status; u8 unLen; u8 ucComMF522Buf[MAXRLEN]; //MAXRLEN 18(数组的大小) //验证模式+块地址+扇区密码+卡序列号 ucComMF522Buf[0]=auth_mode; ucComMF522Buf[1]=addr; memcpy(&ucComMF522Buf[2],pKey,6); //拷贝,复制 memcpy(&ucComMF522Buf[8],pSnr,4); status=RC522_PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen); if((status!= MI_OK)||(!(RC522_ReadRawRC(Status2Reg)&0x08)))status = MI_ERR; return status;}/*功 能:读取M1卡一块数据参数说明: addr:块地址 p :读出的块数据,16字节返 回:成功返回MI_OK*/ char RC522_PcdRead(u8 addr,u8 *p){ char status; u8 unLen; u8 i,ucComMF522Buf[MAXRLEN]; //18 ucComMF522Buf[0]=PICC_READ; ucComMF522Buf[1]=addr; RC522_CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); status=RC522_PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);//通过RC522和ISO14443卡通讯 if((status==MI_OK&&(unLen==0x90))) { for(i=0;i<16;i++) { *(p +i)=ucComMF522Buf[i]; } } else { status=MI_ERR; } return status;}/*功 能:写数据到M1卡指定块参数说明:addr:块地址 p :向块写入的数据,16字节返 回:成功返回MI_OK*/ char RC522_PcdWrite(u8 addr,u8 *p){ char status; u8 unLen; u8 i,ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0]=PICC_WRITE;// 0xA0 //写块 ucComMF522Buf[1]=addr; //块地址 RC522_CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); status=RC522_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++)//向FIFO写16Byte数据 { ucComMF522Buf[i]=*(p +i); } RC522_CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]); status = RC522_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 RC522_PcdHalt(void){ u8 status; u8 unLen; u8 ucComMF522Buf[MAXRLEN]; //MAXRLEN==18 status=status; ucComMF522Buf[0]=PICC_HALT; ucComMF522Buf[1]=0; RC522_CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); status=RC522_PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen); return MI_OK;}/*功 能:用MF522计算CRC16函数参 数: *pIn :要读数CRC的数据 len:-数据长度 *pOut:计算的CRC结果*/void RC522_CalulateCRC(u8 *pIn ,u8 len,u8 *pOut ){ u8 i,n; RC522_ClearBitMask(DivIrqReg,0x04); //CRCIrq = 0 RC522_WriteRawRC(CommandReg,PCD_IDLE); RC522_SetBitMask(FIFOLevelReg,0x80); //清FIFO指针 //向FIFO中写入数据 for(i=0;i<len;i++) { RC522_WriteRawRC(FIFODataReg,*(pIn +i)); //开始RCR计算 } RC522_WriteRawRC(CommandReg,PCD_CALCCRC); //等待CRC计算完成 i=0xFF; do { n=RC522_ReadRawRC(DivIrqReg); i--; } while((i!=0)&&!(n&0x04));//CRCIrq = 1 //读取CRC计算结果 pOut[0]=RC522_ReadRawRC(CRCResultRegL); pOut[1]=RC522_ReadRawRC(CRCResultRegM);}/*功 能:复位RC522返 回:成功返回MI_OK*/char RC522_PcdReset(void){ RC522_RST=1; //PF1写1 RC522_Delay(10); RC522_RST=0; //PF1清0 RC522_Delay(10); RC522_RST=1; //PF1写1 RC522_Delay(10); RC522_WriteRawRC(CommandReg,PCD_RESETPHASE); //写RC632寄存器,复位 RC522_WriteRawRC(CommandReg,PCD_RESETPHASE); //写RC632寄存器,复位 RC522_Delay(10); RC522_WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363 RC522_WriteRawRC(TReloadRegL,30); //写RC632寄存器 RC522_WriteRawRC(TReloadRegH,0); RC522_WriteRawRC(TModeReg,0x8D); RC522_WriteRawRC(TPrescalerReg,0x3E); RC522_WriteRawRC(TxAutoReg,0x40);//必须要 return MI_OK;}/*函数功能:设置RC632的工作方式 */char M500PcdConfigISOType(u8 type){ if(type=='A') //ISO14443_A { RC522_ClearBitMask(Status2Reg,0x08); //清RC522寄存器位 RC522_WriteRawRC(ModeReg,0x3D); //3F//CRC初始值0x6363 RC522_WriteRawRC(RxSelReg,0x86); //84 RC522_WriteRawRC(RFCfgReg,0x7F); //4F //调整卡的感应距离//RxGain = 48dB调节卡感应距离 RC522_WriteRawRC(TReloadRegL,30); //tmoLength);// TReloadVal = 'h6a =tmoLength(dec) RC522_WriteRawRC(TReloadRegH,0); RC522_WriteRawRC(TModeReg,0x8D); RC522_WriteRawRC(TPrescalerReg,0x3E); RC522_Delay(1000); RC522_PcdAntennaOn(); //开启天线 } else return 1; //失败,返回1 return MI_OK; //成功返回0}/*功 能:读RC632寄存器参数说明:Address[IN]:寄存器地址返 回:读出的值*/u8 RC522_ReadRawRC(u8 Address){ u8 ucAddr; u8 ucResult=0; RC522_CS=0; //片选选中RC522 ucAddr=((Address<<1)&0x7E)|0x80; RC522_SPI_ReadWriteOneByte(ucAddr); //发送命令 ucResult=RC522_SPI_ReadWriteOneByte(0); //读取RC522返回的数据 RC522_CS=1; //释放片选线(PF0) return ucResult; //返回读到的数据}/*功 能:写RC632寄存器参数说明:Address[IN]:寄存器地址 value[IN] :写入的值*/void RC522_WriteRawRC(u8 Address,u8 value){ u8 ucAddr; RC522_CS=0; //PF0写 0 (SDA)(SPI1片选线,低电平有效) ucAddr=((Address<<1)&0x7E); RC522_SPI_ReadWriteOneByte(ucAddr); //SPI1发送一个字节 RC522_SPI_ReadWriteOneByte(value); //SPI1发送一个字节 RC522_CS=1; //PF1写1(SDA)(SPI1片选线)}/*功 能:置RC522寄存器位参数说明:reg[IN]:寄存器地址 mask[IN]:置位值*/void RC522_SetBitMask(u8 reg,u8 mask) { char tmp=0x0; tmp=RC522_ReadRawRC(reg); //读RC632寄存器 RC522_WriteRawRC(reg,tmp|mask); //写RC632寄存器}/*功 能:清RC522寄存器位参数说明:reg[IN]:寄存器地址 mask[IN]:清位值*/void RC522_ClearBitMask(u8 reg,u8 mask) { char tmp=0x0; tmp=RC522_ReadRawRC(reg); //读RC632寄存器 RC522_WriteRawRC(reg,tmp&~mask); // clear bit mask} /*功 能:通过RC522和ISO14443卡通讯参数说明:Command[IN]:RC522命令字 pIn [IN]:通过RC522发送到卡片的数据 InLenByte[IN]:发送数据的字节长度 pOut [OUT]:接收到的卡片返回数据 *pOutLenBit[OUT]:返回数据的位长度*/char RC522_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; } RC522_WriteRawRC(ComIEnReg,irqEn|0x80); RC522_ClearBitMask(ComIrqReg,0x80); //清所有中断位 RC522_WriteRawRC(CommandReg,PCD_IDLE); RC522_SetBitMask(FIFOLevelReg,0x80); //清FIFO缓存 for(i=0;i<InLenByte;i++) { RC522_WriteRawRC(FIFODataReg,pIn[i]); } RC522_WriteRawRC(CommandReg,Command); if(Command==PCD_TRANSCEIVE) { RC522_SetBitMask(BitFramingReg,0x80); //开始传送 } //有问题,下面的循环 //i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms i=2000; do { n=RC522_ReadRawRC(ComIrqReg); i--; } while((i!=0)&&!(n&0x01)&&!(n&waitFor)); RC522_ClearBitMask(BitFramingReg,0x80); if(i!=0) { if(!(RC522_ReadRawRC(ErrorReg)&0x1B)) { status=MI_OK; if(n&irqEn&0x01) { status=MI_NOTAGERR; } if(Command==PCD_TRANSCEIVE) { n=RC522_ReadRawRC(FIFOLevelReg); lastBits=RC522_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]=RC522_ReadRawRC(FIFODataReg); } } } else { status=MI_ERR; } } RC522_SetBitMask(ControlReg,0x80);// stop timer now RC522_WriteRawRC(CommandReg,PCD_IDLE); return status;}/*函数功能:开启天线 参 数:每次启动或关闭天险发射之间应至少有1ms的间隔*/void RC522_PcdAntennaOn(void){ u8 i; i=RC522_ReadRawRC(TxControlReg); if(!(i&0x03)) { RC522_SetBitMask(TxControlReg,0x03); }}/*函数功能:关闭天线 参 数:每次启动或关闭天险发射之间应至少有1ms的间隔*/void RC522_PcdAntennaOff(void){ RC522_ClearBitMask(TxControlReg,0x03); //清RC522寄存器位}
5.2 rc522.h
#ifndef RFID_RC522_H#define RFID_RC522_H#include "sys.h"/*RC522射频模块外部的接口: *1--SDA <----->PF0--片选脚*2--SCK <----->PA5--时钟线*3--MOSI<----->PA7--输出*4--MISO<----->PA6--输入*5--悬空*6--GND <----->GND*7--RST <----->PF1--复位脚*8--VCC <----->VCC*/#define RC522_OUTPUT PAout(7)#define RC522_INPUT PAin(6)#define RC522_SCLK PAout(5)#define RC522_CS PFout(0)#define RC522_RST PFout(1)//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/* RC522各种驱动函数*/u8 RC522_SPI_ReadWriteOneByte(u8 tx_data);void RC522_IO_Init(void);u8 RC522_MFRC522_SelectTag(u8 *serNum);void RC522_Delay(u32 ns);void RC522_Init(void);void RC522_Reset(void);char RC522_PcdRequest(u8 req_code,u8 *pTagType);char RC522_PcdAnticoll(u8 *pSnr);char RC522_PcdSelect(u8 *pSnr);char RC522_PcdAuthState(u8 auth_mode,u8 addr,u8 *pKey,u8 *pSnr);char RC522_PcdRead(u8 addr,u8 *p);char RC522_PcdWrite(u8 addr,u8 *p);char RC522_PcdHalt(void);void RC522_CalulateCRC(u8 *pIn ,u8 len,u8 *pOut );char RC522_PcdReset(void);char M500PcdConfigISOType(u8 type);char M500PcdConfigISOType(u8 type);u8 RC522_ReadRawRC(u8 Address);void RC522_WriteRawRC(u8 Address,u8 value);void RC522_SetBitMask(u8 reg,u8 mask) ;void RC522_ClearBitMask(u8 reg,u8 mask);char RC522_PcdComMF522(u8 Command,u8 *pIn,u8 InLenByte,u8 *pOut,u8 *pOutLenBit);void RC522_PcdAntennaOn(void);void RC522_PcdAntennaOff(void);#endif
边栏推荐
- std::true_ Type and std:: false_ type
- Today in history: the mother of Google was born; Two Turing Award pioneers born on the same day
- 2022 Summer Project Training (III)
- Jerry is the custom background specified by the currently used dial enable [chapter]
- F200——搭载基于模型设计的国产开源飞控系统无人机
- 2022暑期项目实训(三)
- TOP命令详解
- Distiller les connaissances du modèle interactif! L'Université de technologie de Chine & meituan propose Virt, qui a à la fois l'efficacité du modèle à deux tours et la performance du modèle interacti
- SQL优化问题的简述
- STM32按键状态机2——状态简化与增加长按功能
猜你喜欢
递归的方式
On time and parameter selection of asemi rectifier bridge db207
1700C - Helping the Nature
FMT open source self driving instrument | FMT middleware: a high real-time distributed log module Mlog
QT中Model-View-Delegate委托代理机制用法介绍
带你穿越古罗马,元宇宙巴士来啦 #Invisible Cities
Comparative examples of C language pointers *p++, * (p++), * ++p, * (++p), (*p) + +, +(*p)
Appium automated test scroll and drag_ and_ Drop slides according to element position
Prophet模型的简介以及案例分析
node の SQLite
随机推荐
推荐好用的后台管理脚手架,人人开源
Codeforces Round #803 (Div. 2)
RB157-ASEMI整流桥RB157
Declval of template in generic programming
Heavy! Ant open source trusted privacy computing framework "argot", flexible assembly of mainstream technologies, developer friendly layered design
模板于泛型编程之declval
2022暑期项目实训(三)
Redis的五种数据结构
HMS Core 机器学习服务打造同传翻译新“声”态,AI让国际交流更顺畅
從交互模型中蒸餾知識!中科大&美團提出VIRT,兼具雙塔模型的效率和交互模型的性能,在文本匹配上實現性能和效率的平衡!...
Pytest learning ----- pytest operation mode and pre post packaging of interface automation testing
2019 Alibaba cluster dataset Usage Summary
Video fusion cloud platform easycvr adds multi-level grouping, which can flexibly manage access devices
Fleet tutorial 13 basic introduction to listview's most commonly used scroll controls (tutorial includes source code)
Compilation Principle -- C language implementation of prediction table
adb常用命令
Nodejs developer roadmap 2022 zero foundation Learning Guide
C语言自动预订飞机票问题
ASEMI整流桥DB207的导通时间与参数选择
从交互模型中蒸馏知识!中科大&美团提出VIRT,兼具双塔模型的效率和交互模型的性能,在文本匹配上实现性能和效率的平衡!...