最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

STM8RC522读写IC卡程序

IT圈 admin 34浏览 0评论

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;

}

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论