标题:
stm32 rc522射频模块程序
[打印本页]
作者:
优吧大神
时间:
2016-4-16 13:07
标题:
stm32 rc522射频模块程序
射频模块程序:
RFID_RC522.zip
(7.22 MB, 下载次数: 149)
2016-4-16 13:06 上传
点击文件名下载附件
下载积分: 黑币 -5
程序预览:
#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((SPI2->SR&0X02)==0); //等待发送区空
SPI2->DR=Byte; //发送一个byte
while((SPI2->SR&0X01)==0); //等待接收完一个byte
return SPI2->DR; //返回收到的数据
}
//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最近接收的数据
}
//SPI 速度设置函数
//SpeedSet:
//SPI_BaudRatePrescaler_2 2分频
//SPI_BaudRatePrescaler_8 8分频
//SPI_BaudRatePrescaler_16 16分频
//SPI_BaudRatePrescaler_256 256分频
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
SPI2->CR1&=0XFFC7;
SPI2->CR1|=SPI_BaudRatePrescaler; //设置SPI2速度
SPI_Cmd(SPI2,ENABLE);
}
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、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_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化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_256; //定义波特率预分频的值:波特率预分频值为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);//启动传输
}
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);//3F
WriteRawRC(RxSelReg,0x86);//84
WriteRawRC(RFCfgReg,0x7F); //4F
WriteRawRC(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);
ucResult=SPIReadByte();
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);
SPIWriteByte(value);
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卡最大等待时间25ms
i = 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;
}*/
/////////////////////////////////////////////////////////////////////
//功 能:备份钱包
//参数说明: sourceaddr[IN]:源地址
// goaladdr[IN]:目标地址
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
/*char PcdBakValue(u8 sourceaddr, u8 goaladdr)
{
char status;
u8 unLen;
u8 ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_RESTORE;
ucComMF522Buf[1] = sourceaddr;
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)
{
ucComMF522Buf[0] = 0;
ucComMF522Buf[1] = 0;
ucComMF522Buf[2] = 0;
ucComMF522Buf[3] = 0;
CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]);
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen);
if (status != MI_ERR)
{ status = MI_OK; }
}
if (status != MI_OK)
{ return MI_ERR; }
ucComMF522Buf[0] = PICC_TRANSFER;
ucComMF522Buf[1] = goaladdr;
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;
}*/
复制代码
main.c
#include "output.h"
#include "delay.h"
#include "sys.h"
#include "rc522.h"
#include "lcd.h" //显示模块
#include "key.h" //矩阵键盘模块
#include "usart.h"
#include "string.h"
//////////////////////////////////////////////////////////
//M1卡分為16個扇區,每個扇區由4塊(塊0、塊1、塊2、塊3)組成
//我們也將16個扇區的64個塊按絕對地址編號0~63
//第0扇區的塊0(即絕對地址0塊),他用於存放廠商代碼,已經固化,不可更改
//每個扇區的塊0、塊1、塊2為數據塊,可用於存放數據
//每個扇區的塊3為控制塊(絕對地址塊3、7、11....),包括了密碼A,存取控制、密碼B。
/*******************************
*连线说明:
*1--SS <----->PF0
*2--SCK <----->PB13
*3--MOSI<----->PB15
*4--MISO<----->PB14
*5--悬空
*6--GND <----->GND
*7--RST <----->PF1
*8--VCC <----->VCC
************************************/
/*全局变量*/
unsigned char CT[2];//卡类型
unsigned char SN[4]; //卡号
unsigned char RFID[16]; //存放RFID
unsigned char lxl_bit=0;
unsigned char card1_bit=0;
unsigned char card2_bit=0;
unsigned char card3_bit=0;
unsigned char card4_bit=0;
unsigned char total=0;
unsigned char lxl[4]={6,109,250,186};
unsigned char card_1[4]={66,193,88,0};
unsigned char card_2[4]={66,191,104,0};
unsigned char card_3[4]={62,84,28,11};
unsigned char card_4[4]={126,252,248,12};
u8 KEY[6]={0xff,0xff,0xff,0xff,0xff,0xff};
unsigned char RFID1[16]={0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x07,0x80,0x29,0xff,0xff,0xff,0xff,0xff,0xff};
/*函数声明*/
void ShowID(u16 x,u16 y, u8 *p, u16 charColor, u16 bkColor); //显示卡的卡号,以十六进制显示
void PutNum(u16 x,u16 y, u32 n1,u8 n0, u16 charColor, u16 bkColor); //显示余额函数
void Store(u8 *p,u8 store,u8 cash);//最重要的一个函数
int main(void)
{
unsigned char status;
unsigned char s=0x08;
//u8 Data[16];
//u8 i;
u8 t,key;
//u8 k;//读写错误重试次数
u8 j;
delay_init(); //延时函数初始化
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
OUTPUT_Init(); //输出模块初始化
uart_init(9600);
LCD_Init();
KEY_Init();
InitRc522(); //初始化射频卡模块
//sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。
LEDA=1;
while(1)
{ key=KEY_Scan(0);
if(key==1){s++;LCD_ShowNum(0,272,s,3,16);}
else if(key==3) {s--;LCD_ShowNum(0,272,s,3,16);}
status = PcdRequest(PICC_REQALL,CT);/*尋卡*/
if(status==MI_OK)//尋卡成功
{
LCD_ShowString(0,30,200,16,16,"PcdRequest_MI_OK");
status=MI_ERR;
status = PcdAnticoll(SN);/*防冲撞*/
}
if (status==MI_OK)//防衝撞成功
{
LCD_ShowString(150,30,200,16,16,"PcdAnticoll_MI_OK");
status=MI_ERR;
LEDA=1;
LEDB=1;
ShowID(0,200,SN,BLUE,WHITE); //在液晶屏上显示卡的ID号
//printf("ID:%02x %02x %02x %02x\n",SN[0],SN[1],SN[2],SN[3]);//发送卡号
LCD_ShowString(0,100,200,16,16,"The Card ID is:");
for(j=0;j<4;j++)
{
LCD_ShowNum(0,116+j*16,SN[j],3,16);
}
if((SN[0]==lxl[0])&&(SN[1]==lxl[1])&&(SN[2]==lxl[2])&&(SN[3]==lxl[3]))
{
lxl_bit=1;
LCD_ShowString(0,0,200,16,16,"The User is:lxl");
}
if((SN[0]==card_1[0])&&(SN[1]==card_1[1])&&(SN[2]==card_1[2])&&(SN[3]==card_1[3]))
{
card1_bit=1;
LCD_ShowString(0,0,200,16,16,"The User is:card_1");
}
if((SN[0]==card_2[0])&&(SN[1]==card_2[1])&&(SN[2]==card_2[2])&&(SN[3]==card_2[3]))
{
card2_bit=1;
LCD_ShowString(0,0,200,16,16,"The User is:card_2");
}
if((SN[0]==card_3[0])&&(SN[1]==card_3[1])&&(SN[2]==card_3[2])&&(SN[3]==card_3[3]))
{
card3_bit=1;
LCD_ShowString(0,0,200,16,16,"The User is:card_3");
}
if((SN[0]==card_4[0])&&(SN[1]==card_4[1])&&(SN[2]==card_4[2])&&(SN[3]==card_4[3]))
{
card4_bit=1;
LCD_ShowString(0,0,200,16,16,"The User is:card_4");
}
total=card1_bit+card2_bit+card3_bit+card4_bit+lxl_bit;
LCD_ShowString(0,16,200,16,16,"total:");
LCD_ShowNum(46,16,total,2,16);
status =PcdSelect(SN);
//Reset_RC522();
}
else
{
LEDA=0;//只点亮led0
LEDB=1;
}
if(status==MI_OK)//選卡成功
{
//LCD_ShowString(0,50,200,16,16,"PcdAnticoll_MI_OK");
LCD_ShowString(0,48,200,16,16,"PcdSelect_MI_OK ");
status=MI_ERR;
status =PcdAuthState(0x60,0x09,KEY,SN);
}
if(status==MI_OK)//驗證成功
{
LCD_ShowString(0,64,200,16,16,"PcdAuthState_MI_OK ");
status=MI_ERR;
status=PcdRead(s,RFID);
//status=PcdWrite(s,RFID1);
}
if(status==MI_OK)//讀卡成功
{
LCD_ShowString(0,80,200,16,16,"READ_MI_OK");
status=MI_ERR;
delay_ms(100);
}
if(key==2)
{
for(t=0;t<16;t++) //开启射频模块
{
USART_ClearFlag(USART1,USART_FLAG_TC); //读取USART_SR
USART_SendData(USART1,RFID[t]); //向串口2发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET); //等待发送结束
}
}
//else LCD_ShowString(0,80,200,16,16,"READ_MI_ERR ");
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*if(status==MI_OK)
{
LCD_ShowString(120,80,200,16,16,"WRITE_MI_OK");
status=MI_ERR;
}*/
//else LCD_ShowString(120,80,200,16,16,"WRITE_MI_ERR");
//Reset_RC522();
}
//////////////////////////////
}
/*************************************
*函数功能:显示卡的卡号,以十六进制显示
*参数:x,y 坐标
* p 卡号的地址
* charcolor 字符的颜色
* bkcolor 背景的颜色
***************************************/
void ShowID(u16 x,u16 y, u8 *p, u16 charColor, u16 bkColor) //显示卡的卡号,以十六进制显示
{
u8 num[9];
u8 i;
for(i=0;i<4;i++)
{
num[i*2]=p[i]/16;
num[i*2]>9?(num[i*2]+='7'):(num[i*2]+='0');
num[i*2+1]=p[i]%16;
num[i*2+1]>9?(num[i*2+1]+='7'):(num[i*2+1]+='0');
}
num[8]=0;
POINT_COLOR=RED;
LCD_ShowString(x,y,200,16,16,"The Card ID is:");
//DisplayString(x,y+16,num,charColor,bkColor);
for(i=0;i<8;i++)
{
LCD_ShowNum(x+16*i,y+16,num[i],2,16);
//LCD_ShowNum(x,y+32,num[1],2,16);
// LCD_ShowNum(x,y+48,num[2],2,16);
// LCD_ShowNum(x,y+64,num[3],2,16);
// LCD_ShowNum(x,y+80,num[4],2,16);
// LCD_ShowNum(x,y+96,num[5],2,16);
// LCD_ShowNum(x,y+16*7,num[6],2,16);
// LCD_ShowNum(x,y+16*8,num[7],2,16);
// LCD_ShowNum(x,y+16*9,num[8],2,16);
// LCD_ShowNum(x,y+16*10,num[9],2,16);
}
}
/********************************
*函数功能:求p的n次幂
*/
int power(u8 p,u8 n)
{
int pow=1;
u8 i;
for(i=0;i<n;i++)
{
pow*=p;
}
return pow;
}
u8 ReadData(u8 addr,u8 *pKey,u8 *pSnr,u8 *dataout)
{
u8 status,k;
status=0x02;//
k=5;
do
{
status=PcdAuthState(PICC_AUTHENT1A,addr,pKey,pSnr);
k--;
//printf("AuthState is wrong\n");
}while(status!=MI_OK && k>0);
status=0x02;//
k=5;
do
{
status=PcdRead(addr,dataout);
k--;
//printf("ReadData is wrong\n");
}while(status!=MI_OK && k>0);
return status;
}
u8 WriteData(u8 addr,u8 *pKey,u8 *pSnr,u8 *datain)
{
u8 status,k;
status=0x02;//
k=5;
do
{
status=PcdAuthState(PICC_AUTHENT1A,addr,pKey,pSnr);
k--;
//printf("AuthState is wrong\n");
}while(status!=MI_OK && k>0);
status=0x02;//
k=5;
do
{
status=PcdWrite(addr,datain);
k--;
//printf("ReadData is wrong\n");
}while(status!=MI_OK && k>0);
return status;
}
void PutNum(u16 x,u16 y, u32 n1,u8 n0, u16 charColor, u16 bkColor)
{
// u8 tmp[13];
// u8 i;
//LCD_SetRegion(0,0,239,319,FALSE);
// tmp[0]=n1/1000000000+'0';
// for(i=1;i<10;i++)
// {
/// tmp[i]=n1/(1000000000/power(10,i))%10+'0';
// }
// tmp[10]='.';
// tmp[11]=n0+'0';
// tmp[12]=0;
//DisplayString(x,y,tmp,charColor,bkColor);
//LCD_ShowString(x,y,)
}
void Store(u8 *p,u8 store,u8 cash)
{
}
复制代码
作者:
raim8888
时间:
2016-5-10 09:56
不错谢谢
作者:
zlo007
时间:
2016-5-19 15:49
不错谢谢
作者:
51lry521
时间:
2016-5-20 17:42
不错的资料,谢谢分享
作者:
robinxiong
时间:
2016-7-19 14:02
供应13.56M非接芯片,兼容CV520,RC522,RC523,FM17520,FM17522.具有绝对成本优势。有意者可加QQ458231727
作者:
nagelan
时间:
2016-9-2 22:52
不错谢谢
作者:
IF_YOU
时间:
2017-4-3 20:54
流弊!不过我想要51的!
作者:
yanwenhao111
时间:
2017-4-25 00:20
谢谢分享!!!!
作者:
羿羽锋
时间:
2017-10-13 12:27
请问楼主
工作方式那里是RC632的 RC522的能用么
作者:
huangany
时间:
2017-12-18 17:29
初学者,路过看看
作者:
yinwuqing
时间:
2022-3-23 14:39
void Store(u8 *p,u8 store,u8 cash);//最重要的一个函数 怎么没有分享出来呢??
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1