长业建设网站,上海网站建设网页制,wordpress 公司建站,seo专员有前途吗STM32使用RFID读卡器
RFID卡片 ID卡#xff08;身份标识#xff09;#xff1a;作用就是比如你要输入学号#xff0c;你刷卡直接就相当于输入学号#xff0c;省去了输入的过程 IC卡#xff1a;集成电路卡#xff0c;是将一种微电子芯片嵌入卡片之中
RFID的操作
1、…STM32使用RFID读卡器
RFID卡片 ID卡身份标识作用就是比如你要输入学号你刷卡直接就相当于输入学号省去了输入的过程 IC卡集成电路卡是将一种微电子芯片嵌入卡片之中
RFID的操作
1、初始化
(1)请求卡—寻找附近所有信号的卡
(2)防碰撞—选择一张信号最强的卡得到卡的ID
(3)选卡—选择一张要通信的卡
(4)密钥验证—验证身份
(5)读写卡片—数据读写 2、接线引脚表
RFIDSTM32SDAPA4SPI1_NSSSCKPA5SPI1_SCKMOSIPA7SPI1_MOSIMISOPA6SPI1_MISOIRQ悬空GNDGNDRSTPA123V33.3v
3、代码 厂家给的测试代码改写 #include stm32f10x_gpio.h
#include stm32f10x_rcc.h
#include mfrc522.h
#include ZigBee.h
#include relay.h#define MAXRLEN 18void MFRC522_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;/* Enable the GPIO Clock */RCC_APB2PeriphClockCmd(MF522_RST_CLK, ENABLE);/* Configure the GPIO pin */GPIO_InitStructure.GPIO_Pin MF522_RST_PIN;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed GPIO_Speed_2MHz;GPIO_Init(MF522_RST_PORT, GPIO_InitStructure);/* Enable the GPIO Clock */RCC_APB2PeriphClockCmd(MF522_MISO_CLK, ENABLE);/* Configure the GPIO pin */GPIO_InitStructure.GPIO_Pin MF522_MISO_PIN;GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed GPIO_Speed_2MHz;GPIO_Init(MF522_MISO_PORT, GPIO_InitStructure);/* Enable the GPIO Clock */RCC_APB2PeriphClockCmd(MF522_MOSI_CLK, ENABLE);/* Configure the GPIO pin */GPIO_InitStructure.GPIO_Pin MF522_MOSI_PIN;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed GPIO_Speed_2MHz;GPIO_Init(MF522_MOSI_PORT, GPIO_InitStructure);/* Enable the GPIO Clock */RCC_APB2PeriphClockCmd(MF522_SCK_CLK, ENABLE);/* Configure the GPIO pin */GPIO_InitStructure.GPIO_Pin MF522_SCK_PIN;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed GPIO_Speed_2MHz;GPIO_Init(MF522_SCK_PORT, GPIO_InitStructure);/* Enable the GPIO Clock */RCC_APB2PeriphClockCmd(MF522_NSS_CLK, ENABLE);/* Configure the GPIO pin */GPIO_InitStructure.GPIO_Pin MF522_NSS_PIN;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed GPIO_Speed_2MHz;GPIO_Init(MF522_NSS_PORT, GPIO_InitStructure);/* Enable the GPIO Clock */RCC_APB2PeriphClockCmd(LED_CLK, ENABLE);PcdReset();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(unsigned char req_code,unsigned char *pTagType)
{char status; unsigned int unLen;unsigned char ucComMF522Buf[MAXRLEN];
// unsigned char xTest ;ClearBitMask(Status2Reg,0x08);WriteRawRC(BitFramingReg,0x07);// xTest ReadRawRC(BitFramingReg);
// if(xTest 0x07 )// { LED_GREEN 0 ;}// else {LED_GREEN 1 ;while(1){}}SetBitMask(TxControlReg,0x03);ucComMF522Buf[0] req_code;status PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,unLen);
// if(status MI_OK )
// { LED_GREEN 0 ;}
// else {LED_GREEN 1 ;}if ((status MI_OK) (unLen 0x10)){ *pTagType ucComMF522Buf[0];*(pTagType1) ucComMF522Buf[1];}else{ status MI_ERR; }return status;
}/
//功 能防冲撞
//参数说明: pSnr[OUT]:卡片序列号4字节
//返 回: 成功返回MI_OK
/
char PcdAnticoll(unsigned char *pSnr)
{char status;unsigned char i,snr_check0;unsigned int unLen;unsigned char 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 (i0; i4; i){ *(pSnri) 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(unsigned char *pSnr)
{char status;unsigned char i;unsigned int unLen;unsigned char ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] PICC_ANTICOLL1;ucComMF522Buf[1] 0x70;ucComMF522Buf[6] 0;for (i0; i4; i){ucComMF522Buf[i2] *(pSnri);ucComMF522Buf[6] ^ *(pSnri);}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(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr)
{char status;unsigned int unLen;unsigned char i,ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] auth_mode;ucComMF522Buf[1] addr;for (i0; i6; i){ ucComMF522Buf[i2] *(pKeyi); }for (i0; i6; i){ ucComMF522Buf[i8] *(pSnri); }// 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]块地址
// pData[OUT]读出的数据16字节
//返 回: 成功返回MI_OK
/
char PcdRead(unsigned char addr,unsigned char *pData)
{char status;unsigned int unLen;unsigned char 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(pData, ucComMF522Buf, 16); }{for (i0; i16; i){ *(pDatai) ucComMF522Buf[i]; }}else{ status MI_ERR; }return status;
}/
//功 能写数据到M1卡一块
//参数说明: addr[IN]块地址
// pData[IN]写入的数据16字节
//返 回: 成功返回MI_OK
/
char PcdWrite(unsigned char addr,unsigned char *pData)
{char status;unsigned int unLen;unsigned char 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, pData, 16);for (i0; i16; i){ ucComMF522Buf[i] *(pDatai); }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)
{unsigned int unLen;unsigned char ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] PICC_HALT;ucComMF522Buf[1] 0;CalulateCRC(ucComMF522Buf,2,ucComMF522Buf[2]);PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,unLen);return MI_OK;
}/
//用MF522计算CRC16函数
/
void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData)
{unsigned char i,n;ClearBitMask(DivIrqReg,0x04);WriteRawRC(CommandReg,PCD_IDLE);SetBitMask(FIFOLevelReg,0x80);for (i0; ilen; i){ WriteRawRC(FIFODataReg, *(pIndatai)); }WriteRawRC(CommandReg, PCD_CALCCRC);i 0xFF;do {n ReadRawRC(DivIrqReg);i--;}while ((i!0) !(n0x04));pOutData[0] ReadRawRC(CRCResultRegL);pOutData[1] ReadRawRC(CRCResultRegM);
}/
//功 能复位RC522
//返 回: 成功返回MI_OK
/
char PcdReset(void)
{RST_H;delay_10ms(1);RST_L;delay_10ms(1);RST_H;delay_10ms(10);// if(ReadRawRC(0x02) 0x80)
// {
// LED_ON;
// delay_10ms(10);
// LED_OFF;
// delay_10ms(10);
// LED_ON;
// delay_10ms(10);
// LED_OFF;
// delay_10ms(10);
// }WriteRawRC(CommandReg,PCD_RESETPHASE);WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯CRC初始值0x6363WriteRawRC(TReloadRegL,30); WriteRawRC(TReloadRegH,0);WriteRawRC(TModeReg,0x8D);WriteRawRC(TPrescalerReg,0x3E);WriteRawRC(TxAutoReg,0x40); return MI_OK;
}
//
//设置RC632的工作方式
//
char M500PcdConfigISOType(unsigned char type)
{if (type A) //ISO14443_A{ ClearBitMask(Status2Reg,0x08);/* WriteRawRC(CommandReg,0x20); //as default WriteRawRC(ComIEnReg,0x80); //as defaultWriteRawRC(DivlEnReg,0x0); //as defaultWriteRawRC(ComIrqReg,0x04); //as defaultWriteRawRC(DivIrqReg,0x0); //as defaultWriteRawRC(Status2Reg,0x0);//80 //trun off temperature sensorWriteRawRC(WaterLevelReg,0x08); //as defaultWriteRawRC(ControlReg,0x20); //as defaultWriteRawRC(CollReg,0x80); //as default
*/WriteRawRC(ModeReg,0x3D);//3F
/* WriteRawRC(TxModeReg,0x0); //as default???WriteRawRC(RxModeReg,0x0); //as default???WriteRawRC(TxControlReg,0x80); //as default???WriteRawRC(TxSelReg,0x10); //as default???*/WriteRawRC(RxSelReg,0x86);//84// WriteRawRC(RxThresholdReg,0x84);//as default// WriteRawRC(DemodReg,0x4D); //as default// WriteRawRC(ModWidthReg,0x13);//26WriteRawRC(RFCfgReg,0x7F); //4F/* WriteRawRC(GsNReg,0x88); //as default???WriteRawRC(CWGsCfgReg,0x20); //as default???WriteRawRC(ModGsCfgReg,0x20); //as default???
*/WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal h6a tmoLength(dec) WriteRawRC(TReloadRegH,0);WriteRawRC(TModeReg,0x8D);WriteRawRC(TPrescalerReg,0x3E);// PcdSetTmo(106);delay_10ms(1);PcdAntennaOn();}else{ return (char)-1; }return MI_OK;
}
/
//功 能读RC632寄存器
//参数说明Address[IN]:寄存器地址
//返 回读出的值
/
unsigned char ReadRawRC(unsigned char Address)
{unsigned char i, ucAddr;unsigned char ucResult0;NSS_L;ucAddr ((Address1)0x7E)|0x80;for(i8;i0;i--){SCK_L;if(ucAddr0x80)MOSI_H;elseMOSI_L;SCK_H;ucAddr 1;}for(i8;i0;i--){SCK_L;ucResult 1;SCK_H;if(READ_MISO 1)ucResult | 1;}NSS_H;SCK_H;return ucResult;
}/
//功 能写RC632寄存器
//参数说明Address[IN]:寄存器地址
// value[IN]:写入的值
/
void WriteRawRC(unsigned char Address, unsigned char value)
{ unsigned char i, ucAddr;SCK_L;NSS_L;ucAddr ((Address1)0x7E);for(i8;i0;i--){if(ucAddr0x80)MOSI_H;elseMOSI_L;SCK_H;ucAddr 1;SCK_L;}for(i8;i0;i--){if(value0x80)MOSI_H;elseMOSI_L;SCK_H;value 1;SCK_L;}NSS_H;SCK_H;
}/
//功 能置RC522寄存器位
//参数说明reg[IN]:寄存器地址
// mask[IN]:置位值
/
void SetBitMask(unsigned char reg,unsigned char mask)
{char tmp 0x0;tmp ReadRawRC(reg);WriteRawRC(reg,tmp | mask); // set bit mask
}/
//功 能清RC522寄存器位
//参数说明reg[IN]:寄存器地址
// mask[IN]:清位值
/
void ClearBitMask(unsigned char reg,unsigned char mask)
{char tmp 0x0;tmp ReadRawRC(reg);WriteRawRC(reg, tmp ~mask); // clear bit mask
} /
//功 能通过RC522和ISO14443卡通讯
//参数说明Command[IN]:RC522命令字
// pInData[IN]:通过RC522发送到卡片的数据
// InLenByte[IN]:发送数据的字节长度
// pOutData[OUT]:接收到的卡片返回数据
// *pOutLenBit[OUT]:返回数据的位长度
/
char PcdComMF522(unsigned char Command, unsigned char *pInData, unsigned char InLenByte,unsigned char *pOutData, unsigned int *pOutLenBit)
{char status MI_ERR;unsigned char irqEn 0x00;unsigned char waitFor 0x00;unsigned char lastBits;unsigned char n;unsigned int 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);for (i0; iInLenByte; i){ WriteRawRC(FIFODataReg, pInData[i]); }WriteRawRC(CommandReg, Command);if (Command PCD_TRANSCEIVE){ SetBitMask(BitFramingReg,0x80); }// i 600;//根据时钟频率调整操作M1卡最大等待时间25msi 2000;do {n ReadRawRC(ComIrqReg);i--;}while ((i!0) !(n0x01) !(nwaitFor));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 (i0; in; i){ pOutData[i] ReadRawRC(FIFODataReg); }}}else{ status MI_ERR; }}SetBitMask(ControlReg,0x80); // stop timer nowWriteRawRC(CommandReg,PCD_IDLE); return status;
}/
//开启天线
//每次启动或关闭天险发射之间应至少有1ms的间隔
/
void PcdAntennaOn()
{unsigned char i;i ReadRawRC(TxControlReg);if (!(i 0x03)){SetBitMask(TxControlReg, 0x03);}
}/
//关闭天线
/
void PcdAntennaOff()
{ClearBitMask(TxControlReg, 0x03);
}//等待卡离开
void WaitCardOff(void)
{char status;unsigned char TagType[2];while(1){status PcdRequest(REQ_ALL, TagType);if(status){status PcdRequest(REQ_ALL, TagType);if(status){status PcdRequest(REQ_ALL, TagType);if(status){return;}}}delay_10ms(100);}
}void MFRC522_Judge(void) {char status;unsigned char snr, buf[16], TagType[2], SelectedSnr[4], DefaultKey[6] {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; status PcdRequest(REQ_ALL,TagType); // 寻卡if(!status){status PcdAnticoll(SelectedSnr); // 防碰撞if(!status){statusPcdSelect(SelectedSnr); // 选卡if(!status){snr 1; //扇区号1status PcdAuthState(KEYA, (snr*43), DefaultKey, SelectedSnr);// 验证卡片密码 校验1扇区密码密码位于每一扇区第3块{if(!status){status PcdRead((snr*40), buf); // 读卡读取1扇区0块数据到buf[0]-buf[16] //status PcdWrite((snr*40), 12345678); // 写卡将buf[0]-buf[16]写入1扇区0块if(strcmp((char *)buf, 12345678) 0){printf(\r\n密码正确... \r\n);}else {printf(\r\n密码错误... \r\n);}if(!status) WaitCardOff(); //等待卡离开}}}}} }