2024年10月3日发(作者:丙雁凡)
#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,0
x0E,0x0F,0x10}; unsigned char read[16] =
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0
x00,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 { 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还是LSB SPI_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 { 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]:置位值 /////////////////////////////////////////////////////////////////// // { 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 { WriteRawRC(FIFODataReg, pIn [i]); } WriteRawRC(CommandReg, Command); // n = ReadRawRC(CommandReg); if (Command == PCD_TRANSCEIVE) { SetBitMask(BitFramingReg,0x80); //开始传送 } //i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms i = 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 { 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; } 2024年10月3日发(作者:丙雁凡) #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,0 x0E,0x0F,0x10}; unsigned char read[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x00,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 { 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还是LSB SPI_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 { 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]:置位值 /////////////////////////////////////////////////////////////////// // { 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 { WriteRawRC(FIFODataReg, pIn [i]); } WriteRawRC(CommandReg, Command); // n = ReadRawRC(CommandReg); if (Command == PCD_TRANSCEIVE) { SetBitMask(BitFramingReg,0x80); //开始传送 } //i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms i = 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 { 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; }