【MM32F5270开发板试用】+RFID门禁
本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:理想三旬
本次使用RFID-RC522模块与之前的1.8寸TFT实现门禁,通过主控循环检测RFID模块的信息,当接收到刷卡信息且核对通过后指示灯会闪,同时也开始计时,到5秒后自动关,同时将信息显示到屏幕上(拍照的时候拍不到屏幕上的信息)。
一、硬件设计
1.屏幕,这是使用的就是开发板的接口,使用I/O模拟的方式,将屏幕点亮。
2.RFID-RC522模块,这里使用的也是模拟的时序与模块通信,具体接线如下所示:
3.舵机,这里直接使用了开发板的接口,使用过的引脚是PA8,这里的电源需要外接,USB的电源不能直接作为舵机接口的电源。
4.LED,这里使用LED作为状态显示,显示读卡状态以及上锁状态
二、软件设计
1.timer1,这里使用了定时器1的基本功能,实现一个1s中断一次的效果,用来计时,当读到卡5s后自动关。
#include "Timer1.h"#include "board_init.h"#include "Lcd_Driver.h"#define APP_TIM_UPDATE_PERIOD 2000uunsigned char Nm[5]={0,1,2,3,4};unsigned char time=0;/* Setup the timer. */void app_tim_init(void){ /* Set the counter counting step. */ TIM_Init_Type tim_init; tim_init.ClockFreqHz = BOARD_TIM_FREQ; tim_init.StepFreqHz = APP_TIM_UPDATE_PERIOD; /* 1s. */ tim_init.Period = APP_TIM_UPDATE_PERIOD - 1u; tim_init.EnablePreloadPeriod = false; tim_init.PeriodMode = TIM_PeriodMode_Continuous; tim_init.CountMode = TIM_CountMode_Increasing; TIM_Init(BOARD_TIM_PORT, &tim_init); /* Enable interrupt. */ NVIC_EnableIRQ(BOARD_TIM_IRQn); TIM_EnableInterrupts(BOARD_TIM_PORT, TIM_INT_UPDATE_PERIOD, true); /* Start the counter. */ TIM_Start(BOARD_TIM_PORT);}/* TIM_BASIC Period timeout ISR. */void BOARD_TIM_IRQHandler(void){ uint32_t flags = TIM_GetInterruptStatus(BOARD_TIM_PORT); if ( 0u != (flags & TIM_STATUS_UPDATE_PERIOD ) ) /* Check update status. */ { time++; if(time>4) { time=0; GPIO_WriteBit(GPIOI, GPIO_PIN_0, 1); Gui_DrawFont_GBK16(20,50,BLACK,GRAY0,"Close door..."); SG90_angle(0); } switch(time) { case 0: Gui_DrawFont_GBK16(70,30,BLACK,GRAY0,"0");break; case 1: Gui_DrawFont_GBK16(70,30,BLACK,GRAY0,"1");break; case 2: Gui_DrawFont_GBK16(70,30,BLACK,GRAY0,"2");break; case 3: Gui_DrawFont_GBK16(70,30,BLACK,GRAY0,"3");break; case 4: Gui_DrawFont_GBK16(70,30,BLACK,GRAY0,"4");break; } } TIM_ClearInterruptStatus(BOARD_TIM_PORT, flags);}
2.RFID.C
#include "RC522.h"#define MAXRLEN 18void RC522_Init(void){ GPIO_Init_Type gpio_init; //RCC522 gpio_init.Pins = GPIO_PIN_1|GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_4; gpio_init.PinMode = GPIO_PinMode_Out_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOF, &gpio_init); GPIO_SetBits(GPIOF,GPIO_PIN_1|GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_4); //拉高 gpio_init.Pins = GPIO_PIN_3; gpio_init.PinMode = GPIO_PinMode_In_PullUp; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOF, &gpio_init);}///功 能:寻卡//参数说明: 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]; 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(unsigned char *pSnr){ char status; unsigned char i,snr_check=0; 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 (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(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 (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(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 (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]:块地址// 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 (i=0; i<16; i++) { *(pData+i) = 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 (i=0; i<16; i++) { ucComMF522Buf[i] = *(pData+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;}///功 能:扣款和充值//参数说明: dd_mode[IN]:命令字// 0xC0 = 扣款// 0xC1 = 充值// addr[IN]:钱包地址// pValue[IN]:4字节增(减)值,低位在前//返 回: 成功返回MI_OK/ char PcdValue(unsigned char dd_mode,unsigned char addr,unsigned char *pValue){ char status; unsigned int unLen; unsigned char i,ucComMF522Buf[MAXRLEN]; 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(unsigned char sourceaddr, unsigned char goaladdr){ char status; unsigned int unLen; unsigned char 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;}///功 能:命令卡片进入休眠状态//返 回: 成功返回MI_OK/char PcdHalt(void){ char status; unsigned int unLen; unsigned char 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(unsigned char *pIndata,unsigned char len,unsigned char *pOutData){ unsigned char i,n; ClearBitMask(DivIrqReg,0x04); WriteRawRC(CommandReg,PCD_IDLE); SetBitMask(FIFOLevelReg,0x80); for (i=0; i<len; i++) { WriteRawRC(FIFODataReg, *(pIndata+i)); } WriteRawRC(CommandReg, PCD_CALCCRC); i = 0xFF; do { n = ReadRawRC(DivIrqReg); i--; } while ((i!=0) && !(n&0x04)); pOutData[0] = ReadRawRC(CRCResultRegL); pOutData[1] = ReadRawRC(CRCResultRegM);}///功 能:复位RC522//返 回: 成功返回MI_OK/char PcdReset(void){ //unsigned char i; MF522_RST_HIGH; delay_us(10); MF522_RST_LOW; delay_us(10); MF522_RST_HIGH; delay_us(10); WriteRawRC(CommandReg,PCD_RESETPHASE); delay_us(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寄存器//参数说明:Address[IN]:寄存器地址//返 回:读出的值/unsigned char ReadRawRC(unsigned char Address){ unsigned char i, ucAddr; unsigned char ucResult=0; unsigned char MF522_SI; MF522_SCK_LOW; MF522_NSS_LOW; ucAddr = ((Address<0;i--) { MF522_SI = ((ucAddr&0x80)==0x80); if(MF522_SI==0) { MF522_SI_LOW; } if(MF522_SI==1) { MF522_SI_HIGH; } MF522_SCK_HIGH; ucAddr <0;i--) { MF522_SCK_HIGH; ucResult <<= 1; ucResult|=MF522_SO; MF522_SCK_LOW; delay_us(10); //STM32需要多加的延时时间。51的不需要加 } MF522_NSS_HIGH; MF522_SCK_HIGH; return ucResult;}///功 能:写RC632寄存器//参数说明:Address[IN]:寄存器地址// value[IN]:写入的值/void WriteRawRC(unsigned char Address, unsigned char value){ unsigned char i, ucAddr; unsigned char MF522_SI; MF522_SCK_LOW; MF522_NSS_LOW; ucAddr = ((Address<0;i--) { MF522_SI = ((ucAddr&0x80)==0x80); if(MF522_SI==0) { MF522_SI_LOW; } if(MF522_SI==1) { MF522_SI_HIGH; } MF522_SCK_HIGH; ucAddr <0;i--) { MF522_SI = ((value&0x80)==0x80); if(MF522_SI==0) { MF522_SI_LOW; } if(MF522_SI==1) { MF522_SI_HIGH; } MF522_SCK_HIGH; value <<= 1; MF522_SCK_LOW; delay_us(10); //STM32需要多加的延时时间。51的不需要加 } MF522_NSS_HIGH; MF522_SCK_HIGH;}///功 能:置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 (i=0; i MAXRLEN) { n = MAXRLEN; } for (i=0; i<n; i++) { pOutData[i] = ReadRawRC(FIFODataReg); } } } else { status = MI_ERR; } } SetBitMask(ControlReg,0x80); // stop timer now WriteRawRC(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);}
3.RFID.H
#ifndef _RC522_H#define _RC522_H#include "board_init.h"#include "delay.h"///MF522命令字/#define PCD_IDLE0x00 //取消当前命令#define PCD_AUTHENT 0x0E //验证密钥#define PCD_RECEIVE 0x08 //接收数据#define PCD_TRANSMIT 0x04 //发送数据#define PCD_TRANSCEIVE 0x0C //发送并接收数据#define PCD_RESETPHASE 0x0F //复位#define PCD_CALCCRC 0x03 //CRC计算///Mifare_One卡片命令字/#define PICC_REQIDL 0x26 //寻天线区内未进入休眠状态#define PICC_REQALL 0x52 //寻天线区内全部卡#define PICC_ANTICOLL1 0x93 //防冲撞#define PICC_ANTICOLL2 0x95 //防冲撞#define PICC_AUTHENT1A 0x60 //验证A密钥#define PICC_AUTHENT1B 0x61 //验证B密钥#define PICC_READ 0x30 //读块#define PICC_WRITE 0xA0 //写块#define PICC_DECREMENT 0xC0 //扣款#define PICC_INCREMENT 0xC1 //充值#define PICC_RESTORE 0xC2 //调块数据到缓冲区#define PICC_TRANSFER 0xB0 //保存缓冲区中数据#define PICC_HALT 0x50 //休眠///MF522 FIFO长度定义/#define DEF_FIFO_LENGTH64 //FIFO size=64byte///MF522寄存器定义/// PAGE 0#define RFU00 0x00 #define CommandReg 0x01 #define ComIEnReg 0x02 #define DivlEnReg 0x03 #define ComIrqReg 0x04 #define DivIrqReg 0x05#define ErrorReg0x06 #define Status1Reg 0x07 #define Status2Reg 0x08 #define FIFODataReg 0x09#define FIFOLevelReg 0x0A#define WaterLevelReg 0x0B#define ControlReg 0x0C#define BitFramingReg 0x0D#define CollReg 0x0E#define RFU0F 0x0F// PAGE 1 #define RFU10 0x10#define ModeReg 0x11#define TxModeReg 0x12#define RxModeReg 0x13#define TxControlReg 0x14#define TxAutoReg 0x15#define TxSelReg0x16#define RxSelReg0x17#define RxThresholdReg 0x18#define DemodReg0x19#define RFU1A 0x1A#define RFU1B 0x1B#define MifareReg 0x1C#define RFU1D 0x1D#define RFU1E 0x1E#define SerialSpeedReg 0x1F// PAGE 2 #define RFU20 0x20 #define CRCResultRegM 0x21#define CRCResultRegL 0x22#define RFU23 0x23#define ModWidthReg 0x24#define RFU25 0x25#define RFCfgReg0x26#define GsNReg 0x27#define CWGsCfgReg 0x28#define ModGsCfgReg 0x29#define TModeReg0x2A#define TPrescalerReg 0x2B#define TReloadRegH 0x2C#define TReloadRegL 0x2D#define TCounterValueRegH 0x2E#define TCounterValueRegL 0x2F// PAGE 3 #define RFU30 0x30#define TestSel1Reg 0x31#define TestSel2Reg 0x32#define TestPinEnReg 0x33#define TestPinValueReg0x34#define TestBusReg 0x35#define AutoTestReg 0x36#define VersionReg 0x37#define AnalogTestReg 0x38#define TestDAC1Reg 0x39 #define TestDAC2Reg 0x3A #define TestADCReg 0x3B #define RFU3C 0x3C #define RFU3D 0x3D #define RFU3E 0x3E #define RFU3F 0x3F///和MF522通讯时返回的错误代码/#define MI_OK 0#define MI_NOTAGERR (-1)#define MI_ERR (-2)#define MF522_NSS_HIGH GPIO_WriteBit(GPIOF, GPIO_PIN_0, 1)#define MF522_SCK_HIGH GPIO_WriteBit(GPIOF, GPIO_PIN_1, 1)#define MF522_SI_HIGH GPIO_WriteBit(GPIOF, GPIO_PIN_2, 1)#define MF522_RST_HIGH GPIO_WriteBit(GPIOF, GPIO_PIN_4, 1)#define MF522_SO GPIO_ReadInDataBit(GPIOF, GPIO_PIN_3)#define MF522_NSS_LOW GPIO_WriteBit(GPIOF, GPIO_PIN_0, 0)#define MF522_SCK_LOW GPIO_WriteBit(GPIOF, GPIO_PIN_1, 0)#define MF522_SI_LOW GPIO_WriteBit(GPIOF, GPIO_PIN_2, 0)#define MF522_RST_LOW GPIO_WriteBit(GPIOF, GPIO_PIN_4, 0)///函数原型/char PcdReset(void);void PcdAntennaOn(void);void PcdAntennaOff(void);char PcdRequest(unsigned char req_code,unsigned char *pTagType); char PcdAnticoll(unsigned char *pSnr);char PcdSelect(unsigned char *pSnr); char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr); char PcdRead(unsigned char addr,unsigned char *pData); char PcdWrite(unsigned char addr,unsigned char *pData); char PcdValue(unsigned char dd_mode,unsigned char addr,unsigned char *pValue); char PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr); char PcdHalt(void);char PcdComMF522(unsigned char Command, unsigned char *pInData, unsigned char InLenByte, unsigned char *pOutData, unsigned int *pOutLenBit);void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData);void WriteRawRC(unsigned char Address,unsigned char value);unsigned char ReadRawRC(unsigned char Address); void SetBitMask(unsigned char reg,unsigned char mask); void ClearBitMask(unsigned char reg,unsigned char mask); void RC522_Init(void);#endif
4.主函数
#include #include #include "board_init.h"#include "QDTFT_demo.h"#include "delay.h"#include "GUI.h"#include "Picture.h"#include "Lcd_Driver.h"#include "RC522.h"#include "Timer1.h"unsigned char data1[16] = {0x12,0x34,0x56,0x78,0xED,0xCB,0xA9,0x87,0x12,0x34,0x56,0x78,0x01,0xFE,0x01,0xFE};//M1卡的某一块写为如下格式,则该块为钱包,可接收扣款和充值命令//4字节金额(低字节在前)+4字节金额取反+4字节金额+1字节块地址+1字节块地址取反+1字节块地址+1字节块地址取反 unsigned char data2[4] = {0,0,0,0x01};unsigned char DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; unsigned char g_ucTempbuf[20];extern unsigned char time;int main(void){ unsigned char status,i; unsigned int temp; delay_init(); BOARD_Init(); Lcd_Init(); LCD_LED_SET;//通过IO控制背光亮 Lcd_Clear(GRAY0); RC522_Init(); PcdReset(); PcdAntennaOff(); delay_ms(10); PcdAntennaOn(); delay_ms(10); app_tim_init(); Gui_DrawFont_GBK16(20,10,BLACK,GRAY0,"RC522 Test"); Gui_DrawFont_GBK16(20,30,BLACK,GRAY0,"Times: s"); while(1) {status = PcdRequest(PICC_REQALL, g_ucTempbuf);//寻卡 if (status != MI_OK) { PcdReset(); PcdAntennaOff();PcdAntennaOn(); continue; } printf("卡的类型:"); for(i=0;i<2;i++) { temp=g_ucTempbuf[i]; printf("%X",temp); } status = PcdAnticoll(g_ucTempbuf);//防冲撞 if(status != MI_OK) { continue; } 以下为超级终端打印出的内容 printf("卡序列号:"); //超级终端显示, for(i=0;i<4;i++) { temp=g_ucTempbuf[i]; printf("%X",temp); } //97379A8A if(g_ucTempbuf[0]==0x97&&g_ucTempbuf[1]==0x37&&g_ucTempbuf[2]==0x9a&&g_ucTempbuf[3]==0x8a) { led(); GPIO_WriteBit(GPIOI, GPIO_PIN_0, 0);// printf("oped door\r\n"); Gui_DrawFont_GBK16(20,50,BLACK,GRAY0,"Open door..."); time=0; SG90_angle(45); } else { GPIO_WriteBit(GPIOI, GPIO_PIN_0, 1); Gui_DrawFont_GBK16(20,30,BLACK,GRAY0," "); } /// status = PcdSelect(g_ucTempbuf);//选定卡片 if (status != MI_OK) { continue; } status = PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, g_ucTempbuf);//验证卡片密码 if (status != MI_OK) { continue; } status = PcdWrite(1, data1);//写块 if (status != MI_OK) { continue; } } }
三、实现结果
1.没有用卡识别时
2.用卡识别时,五秒后显示close door
四、总结
打算用ETH这个模块,不过发现官方只在用户手册中写了这部分,在mindsdk以及库函数中都没有这部分。希望官方后续能支持。