標(biāo)題:
stm32 rc522射頻模塊程序
[打印本頁]
作者:
優(yōu)吧大神
時(shí)間:
2016-4-16 13:07
標(biāo)題:
stm32 rc522射頻模塊程序
射頻模塊程序:
RFID_RC522.zip
(7.22 MB, 下載次數(shù): 149)
2016-4-16 13:06 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
程序預(yù)覽:
#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); //等待發(fā)送區(qū)空
SPI2->DR=Byte; //發(fā)送一個(gè)byte
while((SPI2->SR&0X01)==0); //等待接收完一個(gè)byte
return SPI2->DR; //返回收到的數(shù)據(jù)
}
//SPIx 讀寫一個(gè)字節(jié)
//TxData:要寫入的字節(jié)
//返回值:讀取到的字節(jié)
u8 SPI2_ReadWriteByte(u8 TxData)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //檢查指定的SPI標(biāo)志位設(shè)置與否:發(fā)送緩存空標(biāo)志位
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI2, TxData); //通過外設(shè)SPIx發(fā)送一個(gè)數(shù)據(jù)
retry=0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //檢查指定的SPI標(biāo)志位設(shè)置與否:接受緩存非空標(biāo)志位
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI2); //返回通過SPIx最近接收的數(shù)據(jù)
}
//SPI 速度設(shè)置函數(shù)
//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; //設(shè)置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時(shí)鐘使能
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );//SPI2時(shí)鐘使能
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); //根據(jù)設(shè)定參數(shù)初始化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復(fù)用推挽輸出
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; //設(shè)置SPI單向或者雙向的數(shù)據(jù)模式:SPI設(shè)置為雙線雙向全雙工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //設(shè)置SPI工作模式:設(shè)置為主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //設(shè)置SPI的數(shù)據(jù)大小:SPI發(fā)送接收8位幀結(jié)構(gòu)
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行同步時(shí)鐘的空閑狀態(tài)為低電平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //串行同步時(shí)鐘的第一個(gè)跳變沿(上升或下降)數(shù)據(jù)被采樣
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信號由硬件(NSS管腳)還是軟件(使用SSI位)管理:內(nèi)部NSS信號有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定義波特率預(yù)分頻的值:波特率預(yù)分頻值為256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定數(shù)據(jù)傳輸從MSB位還是LSB位開始:數(shù)據(jù)傳輸從MSB位開始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值計(jì)算的多項(xiàng)式
SPI_Init(SPI2, &SPI_InitStructure); //根據(jù)SPI_InitStruct中指定的參數(shù)初始化外設(shè)SPIx寄存器
SPI_Cmd(SPI2, ENABLE); //使能SPI外設(shè)
//SPI2_ReadWriteByte(0xff);//啟動(dòng)傳輸
}
void InitRc522(void)
{
SPI2_Init();
PcdReset();
PcdAntennaOff();
delay_ms(2);
PcdAntennaOn();
M500PcdConfigISOType( 'A' );
}
void Reset_RC522(void)
{
PcdReset();
PcdAntennaOff();
delay_ms(2);
PcdAntennaOn();
}
/////////////////////////////////////////////////////////////////////
//功 能:尋卡
//參數(shù)說明: req_code[IN]:尋卡方式
// 0x52 = 尋感應(yīng)區(qū)內(nèi)所有符合14443A標(biāo)準(zhǔn)的卡
// 0x26 = 尋未進(jìn)入休眠狀態(tài)的卡
// 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;
}
/////////////////////////////////////////////////////////////////////
//功 能:防沖撞
//參數(shù)說明: pSnr[OUT]:卡片序列號,4字節(jié)
//返 回: 成功返回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;
}
/////////////////////////////////////////////////////////////////////
//功 能:選定卡片
//參數(shù)說明: pSnr[IN]:卡片序列號,4字節(jié)
//返 回: 成功返回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;
}
/////////////////////////////////////////////////////////////////////
//功 能:驗(yàn)證卡片密碼
//參數(shù)說明: auth_mode[IN]: 密碼驗(yàn)證模式
// 0x60 = 驗(yàn)證A密鑰
// 0x61 = 驗(yàn)證B密鑰
// addr[IN]:塊地址
// pKey[IN]:密碼
// pSnr[IN]:卡片序列號,4字節(jié)
//返 回: 成功返回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卡一塊數(shù)據(jù)
//參數(shù)說明: addr[IN]:塊地址
// p [OUT]:讀出的數(shù)據(jù),16字節(jié)
//返 回: 成功返回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;
}
/////////////////////////////////////////////////////////////////////
//功 能:寫數(shù)據(jù)到M1卡一塊
//參數(shù)說明: addr[IN]:塊地址
// p [IN]:寫入的數(shù)據(jù),16字節(jié)
//返 回: 成功返回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;
}
/////////////////////////////////////////////////////////////////////
//功 能:命令卡片進(jìn)入休眠狀態(tài)
//返 回: 成功返回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計(jì)算CRC16函數(shù)
/////////////////////////////////////////////////////////////////////
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);
}
/////////////////////////////////////////////////////////////////////
//功 能:復(fù)位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;
}
//////////////////////////////////////////////////////////////////////
//設(shè)置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寄存器
//參數(shù)說明: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寄存器
//參數(shù)說明: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寄存器位
//參數(shù)說明:reg[IN]:寄存器地址
// mask[IN]:置位值
/////////////////////////////////////////////////////////////////////
void SetBitMask(u8 reg,u8 mask)
{
char tmp = 0x0;
tmp = ReadRawRC(reg);
WriteRawRC(reg,tmp | mask); // set bit mask
}
/////////////////////////////////////////////////////////////////////
//功 能:清RC522寄存器位
//參數(shù)說明: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卡通訊
//參數(shù)說明:Command[IN]:RC522命令字
// pIn [IN]:通過RC522發(fā)送到卡片的數(shù)據(jù)
// InLenByte[IN]:發(fā)送數(shù)據(jù)的字節(jié)長度
// pOut [OUT]:接收到的卡片返回?cái)?shù)據(jù)
// *pOutLenBit[OUT]:返回?cái)?shù)據(jù)的位長度
/////////////////////////////////////////////////////////////////////
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;//根據(jù)時(shí)鐘頻率調(diào)整,操作M1卡最大等待時(shí)間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;
}
/////////////////////////////////////////////////////////////////////
//開啟天線
//每次啟動(dòng)或關(guān)閉天險(xiǎn)發(fā)射之間應(yīng)至少有1ms的間隔
/////////////////////////////////////////////////////////////////////
void PcdAntennaOn(void)
{
u8 i;
i = ReadRawRC(TxControlReg);
if (!(i & 0x03))
{
SetBitMask(TxControlReg, 0x03);
}
}
/////////////////////////////////////////////////////////////////////
//關(guān)閉天線
/////////////////////////////////////////////////////////////////////
void PcdAntennaOff(void)
{
ClearBitMask(TxControlReg, 0x03);
}
/////////////////////////////////////////////////////////////////////
//功 能:扣款和充值
//參數(shù)說明: dd_mode[IN]:命令字
// 0xC0 = 扣款
// 0xC1 = 充值
// addr[IN]:錢包地址
// pValue[IN]:4字節(jié)增(減)值,低位在前
//返 回: 成功返回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;
}*/
/////////////////////////////////////////////////////////////////////
//功 能:備份錢包
//參數(shù)說明: sourceaddr[IN]:源地址
// goaladdr[IN]:目標(biāo)地址
//返 回: 成功返回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;
}*/
復(fù)制代碼
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個(gè)扇區(qū),每個(gè)扇區(qū)由4塊(塊0、塊1、塊2、塊3)組成
//我們也將16個(gè)扇區(qū)的64個(gè)塊按絕對地址編號0~63
//第0扇區(qū)的塊0(即絕對地址0塊),他用於存放廠商代碼,已經(jīng)固化,不可更改
//每個(gè)扇區(qū)的塊0、塊1、塊2為數(shù)據(jù)塊,可用於存放數(shù)據(jù)
//每個(gè)扇區(qū)的塊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};
/*函數(shù)聲明*/
void ShowID(u16 x,u16 y, u8 *p, u16 charColor, u16 bkColor); //顯示卡的卡號,以十六進(jìn)制顯示
void PutNum(u16 x,u16 y, u32 n1,u8 n0, u16 charColor, u16 bkColor); //顯示余額函數(shù)
void Store(u8 *p,u8 store,u8 cash);//最重要的一個(gè)函數(shù)
int main(void)
{
unsigned char status;
unsigned char s=0x08;
//u8 Data[16];
//u8 i;
u8 t,key;
//u8 k;//讀寫錯(cuò)誤重試次數(shù)
u8 j;
delay_init(); //延時(shí)函數(shù)初始化
NVIC_Configuration(); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級,2位響應(yīng)優(yōu)先級
OUTPUT_Init(); //輸出模塊初始化
uart_init(9600);
LCD_Init();
KEY_Init();
InitRc522(); //初始化射頻卡模塊
//sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//將LCD ID打印到lcd_id數(shù)組。
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]);//發(fā)送卡號
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;//只點(diǎn)亮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)//驗(yàn)證成功
{
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發(fā)送數(shù)據(jù)
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET); //等待發(fā)送結(jié)束
}
}
//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();
}
//////////////////////////////
}
/*************************************
*函數(shù)功能:顯示卡的卡號,以十六進(jìn)制顯示
*參數(shù):x,y 坐標(biāo)
* p 卡號的地址
* charcolor 字符的顏色
* bkcolor 背景的顏色
***************************************/
void ShowID(u16 x,u16 y, u8 *p, u16 charColor, u16 bkColor) //顯示卡的卡號,以十六進(jìn)制顯示
{
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);
}
}
/********************************
*函數(shù)功能:求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)
{
}
復(fù)制代碼
作者:
raim8888
時(shí)間:
2016-5-10 09:56
不錯(cuò)謝謝
作者:
zlo007
時(shí)間:
2016-5-19 15:49
不錯(cuò)謝謝
作者:
51lry521
時(shí)間:
2016-5-20 17:42
不錯(cuò)的資料,謝謝分享
作者:
robinxiong
時(shí)間:
2016-7-19 14:02
供應(yīng)13.56M非接芯片,兼容CV520,RC522,RC523,F(xiàn)M17520,F(xiàn)M17522.具有絕對成本優(yōu)勢。有意者可加QQ458231727
作者:
nagelan
時(shí)間:
2016-9-2 22:52
不錯(cuò)謝謝
作者:
IF_YOU
時(shí)間:
2017-4-3 20:54
流弊!不過我想要51的!
作者:
yanwenhao111
時(shí)間:
2017-4-25 00:20
謝謝分享。。!
作者:
羿羽鋒
時(shí)間:
2017-10-13 12:27
請問樓主
工作方式那里是RC632的 RC522的能用么
作者:
huangany
時(shí)間:
2017-12-18 17:29
初學(xué)者,路過看看
作者:
yinwuqing
時(shí)間:
2022-3-23 14:39
void Store(u8 *p,u8 store,u8 cash);//最重要的一個(gè)函數(shù) 怎么沒有分享出來呢??
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1