RC522通过SPI方式读写M1卡Word格式.docx
《RC522通过SPI方式读写M1卡Word格式.docx》由会员分享,可在线阅读,更多相关《RC522通过SPI方式读写M1卡Word格式.docx(30页珍藏版)》请在冰豆网上搜索。
#defineDEF_FIFO_LENGTH64//FIFOsize=64byte
#defineMAXRLEN18
//MF522寄存器定义
//PAGE0
#defineRFU000x00
#defineCommandReg0x01
#defineComIEnReg0x02
#defineDivlEnReg0x03
#defineComIrqReg0x04
#defineDivIrqReg0x05
#defineErrorReg0x06
#defineStatus1Reg0x07
#defineStatus2Reg0x08
#defineFIFODataReg0x09
#defineFIFOLevelReg0x0A
#defineWaterLevelReg0x0B
#defineControlReg0x0C
#defineBitFramingReg0x0D
#defineCollReg0x0E
#defineRFU0F0x0F
//PAGE1
#defineRFU100x10
#defineModeReg0x11
#defineTxModeReg0x12
#defineRxModeReg0x13
#defineTxControlReg0x14
#defineTxAutoReg0x15
#defineTxSelReg0x16
#defineRxSelReg0x17
#defineRxThresholdReg0x18
#defineDemodReg0x19
#defineRFU1A0x1A
#defineRFU1B0x1B
#defineMifareReg0x1C
#defineRFU1D0x1D
#defineRFU1E0x1E
#defineSerialSpeedReg0x1F
//PAGE2
#defineRFU200x20
#defineCRCResultRegM0x21
#defineCRCResultRegL0x22
#defineRFU230x23
#defineModWidthReg0x24
#defineRFU250x25
#defineRFCfgReg0x26
#defineGsNReg0x27
#defineCWGsCfgReg0x28
#defineModGsCfgReg0x29
#defineTModeReg0x2A
#defineTPrescalerReg0x2B
#defineTReloadRegH0x2C
#defineTReloadRegL0x2D
#defineTCounterValueRegH0x2E
#defineTCounterValueRegL0x2F
//PAGE3
#defineRFU300x30
#defineTestSel1Reg0x31
#defineTestSel2Reg0x32
#defineTestPinEnReg0x33
#defineTestPinValueReg0x34
#defineTestBusReg0x35
#defineAutoTestReg0x36
#defineVersionReg0x37
#defineAnalogTestReg0x38
#defineTestDAC1Reg0x39
#defineTestDAC2Reg0x3A
#defineTestADCReg0x3B
#defineRFU3C0x3C
#defineRFU3D0x3D
#defineRFU3E0x3E
#defineRFU3F0x3F
//和MF522通讯时返回的错误代码
#defineMI_OK0
#defineMI_NOTAGERR
(1)
#defineMI_ERR
(2)
#defineSHAQU10X01
#defineKUAI40X04
#defineKUAI70X07
#defineREGCARD0xa1
#defineCONSUME0xa2
#defineREADCARD0xa3
#defineADDMONEY0xa4
#defineSPIReadByte()SPIWriteByte(0)
u8SPIWriteByte(u8byte);
voidSPI2_Init(void);
#defineSET_SPI_CSGPIO_SetBits(GPIOF,GPIO_Pin_0);
#defineCLR_SPI_CSGPIO_ResetBits(GPIOF,GPIO_Pin_0)
#defineSET_RC522RSTGPIO_SetBits(GPIOF,GPIO_Pin_1);
#defineCLR_RC522RSTGPIO_ResetBits(GPIOF,GPIO_Pin_1)
voidInitRc522(void);
voidUsart1_Send_String(unsignedchar*str);
voidClearBitMask(u8reg,u8mask);
voidWriteRawRC(u8Address,u8value);
voidSetBitMask(u8reg,u8mask);
charPcdComMF522(u8Command,
u8*pIn,
u8InLenByte,
u8*pOut,
u8*pOutLenBit);
voidCalulateCRC(u8*pIn,u8len,u8*pOut);
u8ReadRawRC(u8Address);
voidPcdAntennaOn(void);
charPcdReset(void);
charPcdRequest(unsignedcharreq_code,unsignedchar*pTagType);
voidPcdAntennaOff(void);
charM500PcdConfigISOType(unsignedchartype);
charPcdAnticoll(unsignedchar*pSnr);
charPcdSelect(unsignedchar*pSnr);
charPcdAuthState(unsignedcharauth_mode,unsignedcharaddr,unsignedchar*pKey,unsignedchar*pSnr);
charPcdWrite(unsignedcharaddr,unsignedchar*pData);
charPcdRead(unsignedcharaddr,unsignedchar*pData);
charPcdHalt(void);
voidReset_RC522(void);
charPcdValue(u8dd_mode,u8addr,u8*pValue);
//////////////////////////////////////////////////////////////////////////////////////////////////////
rc522.c:
rc522.h"
delay.h"
voiddelay_ns(u32ns)
{
u32i;
for(i=0;
i<
ns;
i++)
{
__nop();
}
}
u8SPIWriteByte(u8Byte)
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);
returnSPI_I2S_ReceiveData(SPI2);
//SPIx读写一个字节
//TxData:
要写入的字节
//返回值:
读取到的字节
u8SPI2_ReadWriteByte(u8TxData)
{
u8retry=0;
while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET)//检查指定的SPI标志位设置与否:
发送缓存空标志位
{
retry++;
if(retry>
200)return0;
}
SPI_I2S_SendData(SPI2,TxData);
//通过外设SPIx发送一个数据
retry=0;
while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==RESET)//检查指定的SPI标志位设置与否:
接受缓存非空标志位
}
//返回通过SPIx最近接收的数据
voidSPI2_Init(void)
GPIO_InitTypeDefGPIO_InitStructure;
SPI_InitTypeDefSPI_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、PF1
GPIO_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_Init(GPIOB,&
//初始化GPIOB
GPIO_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工作模式:
设置为主SPI
SPI_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;
//定义波特率预分频的值:
波特率预分频值为256
SPI_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);
//启动传输
voidInitRc522(void)
SPI2_Init();
PcdReset();
PcdAntennaOff();
delay_ms
(2);
PcdAntennaOn();
M500PcdConfigISOType('
A'
);
voidReset_RC522(void)
}
//功能:
寻卡
//参数说明:
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
charPcdRequest(u8req_code,u8*pTagType)
charstatus;
u8unLen;
u8ucComMF522Buf[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;
returnstatus;
防冲撞
pSnr[OUT]:
卡片序列号,4字节
/////////////////////////////////////////////////////////////////////
charPcdAnticoll(u8*pSnr)
u8i,snr_check=0;
WriteRawRC(BitFramingReg,0x00);
ClearBitMask(CollReg,0x80);
ucComMF522Buf[0]=PICC_ANTICOLL1;
ucComMF522Buf[1]=0x20;
status=PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&
if(status==MI_OK)
for(i=0;
i<
4;
i++)
*(pSnr+i)=ucComMF522Buf[i];
snr_check^=ucComMF522Buf[i];
if(snr_check!
=ucComMF522Buf[i])
SetBitMask(CollReg,0x80);
选定卡片
pSnr[IN]:
charPcdSelect(u8*pSnr)
u8i;
ucComMF522Buf[1]=0x70;
ucComMF522Buf[6]=0;
for(i=0;
ucComMF522Buf[i+2]=*(pSnr+