的实现STM32下实现NFC门禁模块(RC522)的应用

文章目录

  • 1. 前言(包括一些个人理解)
  • 2. RC522门禁工作过程
  • 3. CubeMx配置
  • 3.1 SPI通讯的配置
  • 3.2 SDA和REST引脚的配置
  • 4. 外设代码函数编写
  • 4.1 主函数能调用的接口函数
  • 4.2 二级内部调用函数
  • 4.3 第三级最底层函数
  • 4.4 头文件
  • 5. 使用教程
  • 1. 前言(包括一些个人理解)

    (2021/11/1编辑)
    在项目需要做一个NFC门禁功能的时候,突然发现有个RC522丢在我的桌面,甚至不知道它上面的引脚什么意思(还不会SPI通讯),搜索关键词“RC522”去看博客搜索资料,发现了很多都在说扇区,块,S50(M1)卡,然后就给代码,一开始我还以为S50是内嵌在这个模块里面的一个存储器,然后越看越怪,后面去淘宝搜索S50,才发现S50其实是我们的门禁卡,RC522是用来感应和判断的。
    为了认清楚什么是S50,和RC522的关系
    (2021/11/5编辑)

  • PCD是接近式卡。PICC是接近式耦合设备。
  • 在通信过程中实际上是使用PCD命令控制RC522发出PICC命令与卡进行交互。
  • 2. RC522门禁工作过程

    RC522工作流程图

  • 过程:寻卡->防冲突->选卡->操作卡
  • PCD命令
  • /*MFRC522命令集,中文手册P59*/
    #define MFRC_IDLE              		0x00	//取消当前命令的执行
    #define MFRC_TRANSMIT          		0x04    //发送FIFO缓冲区内容
    #define MFRC_RECEIVE           		0x08    //激活接收器接收数据
    #define MFRC_TRANSCEIVE        		0x0C    //发送并接收数据
    #define MFRC_AUTHENT           		0x0E    //执行Mifare认证(验证密钥)
    #define MFRC_RESETPHASE        		0x0F    //复位MFRC522
    #define MFRC_CALCCRC           		0x03    //激活CRC计算
    #define MFRC_NOCMDCHANGE            0x07	//无命令改变
    
  • PICC命令
  • /*Mifare1卡片命令字*/
    #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_TRANSFER         	0xB0        //转存(传送)
    #define PICC_RESTORE          	0xC2        //恢复(重储)
    #define PICC_HALT             	0x50        //休眠
    

    3. CubeMx配置

    3.1 SPI通讯的配置

    SPI配置
    打开SPI模式设置为:Full-Duplex Master(全双工主机模式)

  • 分频设置为8~256都行,这样随之波特率也会改变,波特率越小通信速度越快
  • Clock Phase (CPHA) 设置为第一个上升沿这里一定要1Edge
  • 不开启CRC检测
  • 3.2 SDA和REST引脚的配置


    随后再定义两个普通的OUTPUT输出的引脚作为复位和使能引脚

    4. 外设代码函数编写

    4.1 主函数能调用的接口函数

  • 初始化
  • /***************************************************************************************
    * 函数名称:PCD_Init
    * 功能描述:读写器初始化
    * 入口参数:无
    * 出口参数:无
    * 返 回 值:无
    * 说    明:无
    ***************************************************************************************/
    void PCD_Init(void)
    {
        MFRC_Init();      //MFRC管脚配置
        PCD_Reset();      //PCD复位  并初始化配置
        PCD_AntennaOff(); //关闭天线
        PCD_AntennaOn();   //开启天线
        PCD_Reset();
    }
    
  • 寻卡
  • /***************************************************************************************
    * 函数名称:PCD_Request
    * 功能描述:寻卡
    * 入口参数: -RequestMode:寻卡方式
    *                 PICC_REQIDL:寻天线区内未进入休眠状态
    *                 PICC_REQALL:寻天线区内全部卡
    *             -pCardType:用于保存卡片类型
    * 出口参数:-pCardType:卡片类型
    *                       0x4400:Mifare_UltraLight
    *                       0x0400:Mifare_One(S50)
    *                       0x0200:Mifare_One(S70)
    *                       0x0800:Mifare_Pro(X)
    *                       0x4403:Mifare_DESFire
    * 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
    * 说    明:无
    ***************************************************************************************/
    char PCD_Request(uint8_t RequestMode, uint8_t *pCardType)
    {
        int status;
        uint16_t unLen;
        uint8_t CmdFrameBuf[MFRC_MAXRLEN];
    
        MFRC_ClrBitMask(MFRC_Status2Reg, 0x08);//关内部温度传感器
        MFRC_WriteReg(MFRC_BitFramingReg, 0x07); //存储模式,发送模式,是否启动发送等
        MFRC_SetBitMask(MFRC_TxControlReg, 0x03);//配置调制信号13.56MHZ
    
        CmdFrameBuf[0] = RequestMode;
    
        status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 1, CmdFrameBuf, &unLen);
    
        if((status == PCD_OK) && (unLen == 0x10))
        {
            *pCardType = CmdFrameBuf[0];
            *(pCardType + 1) = CmdFrameBuf[1];
        }
    
        return status;
    }
    
  • 防冲撞
  • /***************************************************************************************
    * 函数名称:PCD_Anticoll
    * 功能描述:防冲突,获取卡号
    * 入口参数:-pSnr:用于保存卡片序列号,4字节
    * 出口参数:-pSnr:卡片序列号,4字节
    * 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
    * 说    明:无
    ***************************************************************************************/
    char PCD_Anticoll(uint8_t *pSnr)
    {
        char status;
        uint8_t i, snr_check = 0;
        uint16_t  unLen;
        uint8_t CmdFrameBuf[MFRC_MAXRLEN];
    
        MFRC_ClrBitMask(MFRC_Status2Reg, 0x08);
        MFRC_WriteReg(MFRC_BitFramingReg, 0x00);
        MFRC_ClrBitMask(MFRC_CollReg, 0x80);
    
        CmdFrameBuf[0] = PICC_ANTICOLL1;
        CmdFrameBuf[1] = 0x20;
    
        status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 2, CmdFrameBuf, &unLen);
        if(status == PCD_OK)
        {
            for(i = 0; i < 4; i++)
            {
                *(pSnr + i)  = CmdFrameBuf[i];
                snr_check ^= CmdFrameBuf[i];
            }
            if(snr_check != CmdFrameBuf[i])
            {
                status = PCD_ERR;
            }
        }
    		switch (status)
    		{
    			case PCD_OK:					
                    printf("寻卡OK\r\n");break;
    			case PCD_ERR:					
                    printf("寻卡ERROR\r\n");break;
    			case PCD_NOTAGERR:		
                    printf("无卡\r\n");break;
    		}
    
        MFRC_SetBitMask(MFRC_CollReg, 0x80);
        return status;
    }
    

    4.2 二级内部调用函数

  • 宏定义
  • //三目运算符true取前面那个
    #define RS522_RST(N) HAL_GPIO_WritePin(RC522_RST_GPIO_Port, RC522_RST_Pin, N==1?GPIO_PIN_SET:GPIO_PIN_RESET)
    #define RS522_NSS(N) HAL_GPIO_WritePin(RC522_CS_GPIO_Port, RC522_CS_Pin, N==1?GPIO_PIN_SET:GPIO_PIN_RESET)
    #define osDelay HAL_Delay
    
  • MFRC管脚配置
  • /**************************************************************************************
    * 函数名称:MFRC_Init
    * 功能描述:MFRC初始化
    * 入口参数:无
    * 出口参数:无
    * 返 回 值:无
    * 说    明:MFRC的SPI接口速率为0~10Mbps
    ***************************************************************************************/
    void MFRC_Init(void)
    {
        RS522_NSS(1);
        RS522_RST(1);
    }
    
  • PCD复位 并初始化配置
  • /**************************************************************************************
    * 函数名称:PCD_Reset
    * 功能描述:PCD复位
    * 入口参数:无
    * 出口参数:无
    * 返 回 值:无
    * 说    明:无
    ***************************************************************************************/
    void PCD_Reset(void)
    {
        /*硬复位*/
        RS522_RST(1);//用到我们的复位引脚
        osDelay(2);
        RS522_RST(0);
        osDelay(2);
        RS522_RST(1);
        osDelay(2);
    
        /*软复位*/
        MFRC_WriteReg(MFRC_CommandReg, MFRC_RESETPHASE);
        osDelay(2);
    
        /*复位后的初始化配置*/
        MFRC_WriteReg(MFRC_ModeReg, 0x3D);              //CRC初始值0x6363
        MFRC_WriteReg(MFRC_TReloadRegL, 30);            //定时器重装值
        MFRC_WriteReg(MFRC_TReloadRegH, 0);
        MFRC_WriteReg(MFRC_TModeReg, 0x8D);             //定时器设置
        MFRC_WriteReg(MFRC_TPrescalerReg, 0x3E);        //定时器预分频值
        MFRC_WriteReg(MFRC_TxAutoReg, 0x40);            //100%ASK
    
        PCD_AntennaOff();                               //关天线
        osDelay(2);
        PCD_AntennaOn();                                //开天线
    }
    
  • 关闭天线
  • /**************************************************************************************
    * 函数名称:PCD_AntennaOn
    * 功能描述:开启天线,使能PCD发送能量载波信号
    * 入口参数:无
    * 出口参数:无
    * 返 回 值:无
    * 说    明:每次开启或关闭天线之间应至少有1ms的间隔
    ***************************************************************************************/
    void PCD_AntennaOn(void)
    {
        uint8_t temp;
        temp = MFRC_ReadReg(MFRC_TxControlReg);
        if (!(temp & 0x03))
        {
            MFRC_SetBitMask(MFRC_TxControlReg, 0x03);
        }
    }
    
  • 开启天线
  • /**************************************************************************************
    * 函数名称:PCD_AntennaOff
    * 功能描述:关闭天线,失能PCD发送能量载波信号
    * 入口参数:无
    * 出口参数:无
    * 返 回 值:无
    * 说    明:每次开启或关闭天线之间应至少有1ms的间隔
    ***************************************************************************************/
    void PCD_AntennaOff(void)
    {
        MFRC_ClrBitMask(MFRC_TxControlReg, 0x03);
    }
    
  • RC与M1卡通讯帧函数
  • /**************************************************************************************
    * 函数名称:MFRC_CmdFrame
    * 功能描述:MFRC522和ISO14443A卡通讯的命令帧函数
    * 入口参数:-cmd:MFRC522命令字
    *           -pIndata:MFRC522发送给MF1卡的数据的缓冲区首地址
    *           -InLenByte:发送数据的字节长度
    *           -pOutdata:用于接收MF1卡片返回数据的缓冲区首地址
    *           -pOutLenBit:MF1卡返回数据的位长度
    * 出口参数:-pOutdata:用于接收MF1卡片返回数据的缓冲区首地址
    *           -pOutLenBit:用于MF1卡返回数据位长度的首地址
    * 返 回 值:-status:错误代码(MFRC_OK、MFRC_NOTAGERR、MFRC_ERR)
    * 说    明:无
    ***************************************************************************************/
    char MFRC_CmdFrame(uint8_t cmd, uint8_t *pInData, uint8_t InLenByte, uint8_t *pOutData, uint16_t *pOutLenBit)
    {
        uint8_t lastBits;
        uint8_t n;
        uint32_t i;
        char status = MFRC_ERR;
        uint8_t irqEn   = 0x00;
        uint8_t waitFor = 0x00;
    
        /*根据命令设置标志位*/
        switch(cmd)
        {
            case MFRC_AUTHENT:                  //Mifare认证
                irqEn = 0x12;
                waitFor = 0x10;                 //idleIRq中断标志
                break;
            case MFRC_TRANSCEIVE:               //发送并接收数据
                irqEn = 0x77;
                waitFor = 0x30;                 //RxIRq和idleIRq中断标志
                break;
        }
    
        /*发送命令帧前准备*/
        MFRC_WriteReg(MFRC_ComIEnReg, irqEn | 0x80);    //开中断
        MFRC_ClrBitMask(MFRC_ComIrqReg, 0x80);          //清除中断标志位SET1
        MFRC_WriteReg(MFRC_CommandReg, MFRC_IDLE);      //取消当前命令的执行
        MFRC_SetBitMask(MFRC_FIFOLevelReg, 0x80);       //清除FIFO缓冲区及其标志位
    
        /*发送命令帧*/
        for(i = 0; i < InLenByte; i++)                  //写入命令参数
        {
            MFRC_WriteReg(MFRC_FIFODataReg, pInData[i]);
        }
        MFRC_WriteReg(MFRC_CommandReg, cmd);            //执行命令
        if(cmd == MFRC_TRANSCEIVE)
        {
            MFRC_SetBitMask(MFRC_BitFramingReg, 0x80);  //启动发送
        }
        i = 300000;                                     //根据时钟频率调整,操作M1卡最大等待时间25ms
        do
        {
            n = MFRC_ReadReg(MFRC_ComIrqReg);
            i--;
        }
        while((i != 0) && !(n & 0x01) && !(n & waitFor));     //等待命令完成
        MFRC_ClrBitMask(MFRC_BitFramingReg, 0x80);          //停止发送
    
        /*处理接收的数据*/
        if(i != 0)
        {
            if(!(MFRC_ReadReg(MFRC_ErrorReg) & 0x1B))
            {
                status = MFRC_OK;
                if(n & irqEn & 0x01)
                {
                    status = MFRC_NOTAGERR;
                }
                if(cmd == MFRC_TRANSCEIVE)
                {
                    n = MFRC_ReadReg(MFRC_FIFOLevelReg);
                    lastBits = MFRC_ReadReg(MFRC_ControlReg) & 0x07;
                    if (lastBits)
                    {
                        *pOutLenBit = (n - 1) * 8 + lastBits;
                    }
                    else
                    {
                        *pOutLenBit = n * 8;
                    }
                    if(n == 0)
                    {
                        n = 1;
                    }
                    if(n > MFRC_MAXRLEN)
                    {
                        n = MFRC_MAXRLEN;
                    }
                    for(i = 0; i < n; i++)
                    {
                        pOutData[i] = MFRC_ReadReg(MFRC_FIFODataReg);
                    }
                }
            }
            else
            {
                status = MFRC_ERR;
            }
        }
    
        MFRC_SetBitMask(MFRC_ControlReg, 0x80);               //停止定时器运行
        MFRC_WriteReg(MFRC_CommandReg, MFRC_IDLE);            //取消当前命令的执行
    
        return status;
    }
    

    4.3 第三级最底层函数

  • 读一个寄存器
  • /**************************************************************************************
    * 函数名称:MFRC_ReadReg
    * 功能描述:读一个寄存器
    * 入口参数:-addr:待读的寄存器地址
    * 出口参数:无
    * 返 回 值:-data:读到寄存器的数据
    * 说    明:无
    ***************************************************************************************/
    uint8_t MFRC_ReadReg(uint8_t addr)
    {
        uint8_t AddrByte, data;
        AddrByte = ((addr << 1 ) & 0x7E ) | 0x80;   //求出地址字节
        RS522_NSS(0);                               //NSS拉低
        SPI2_RW_Byte(AddrByte);                     //写地址字节
        data = SPI2_RW_Byte(0x00);                  //读数据
        RS522_NSS(1);                               //NSS拉高
        return data;
    }
    
  • 设置寄存器的位
  • /**************************************************************************************
    * 函数名称:MFRC_SetBitMask
    * 功能描述:设置寄存器的位
    * 入口参数:-addr:待设置的寄存器地址
    *           -mask:待设置寄存器的位(可同时设置多个bit)
    * 出口参数:无
    * 返 回 值:无
    * 说    明:无
    ***************************************************************************************/
    void MFRC_SetBitMask(uint8_t addr, uint8_t mask)
    {
        uint8_t temp;
        temp = MFRC_ReadReg(addr);                  //先读回寄存器的值
        MFRC_WriteReg(addr, temp | mask);           //处理过的数据再写入寄存器
    }
    
  • 清除寄存器的位
  • /**************************************************************************************
    * 函数名称:MFRC_ClrBitMask
    * 功能描述:清除寄存器的位
    * 入口参数:-addr:待清除的寄存器地址
    *           -mask:待清除寄存器的位(可同时清除多个bit)
    * 出口参数:无
    * 返 回 值:无
    * 说    明:无
    ***************************************************************************************/
    void MFRC_ClrBitMask(uint8_t addr, uint8_t mask)
    {
        uint8_t temp;
        temp = MFRC_ReadReg(addr);                  //先读回寄存器的值
        MFRC_WriteReg(addr, temp & ~mask);          //处理过的数据再写入寄存器
    }
    

    4.4 头文件

    #ifndef _RC522_H
    #define _RC522_H
    
    //头文件
    //************************************************
    #include "gpio.h"//要一些引脚上的宏定义
    #include "spi.h"//硬件SPI的定义
    #include "printf.h"
    #include "main.h"//Laber User上的宏定义
    //************************************************
    
    //MFRC522驱动程序
    //************************************************
    
    /*MFRC522寄存器定义*/
    //PAGE0
    #define MFRC_RFU00              	0x00    
    #define MFRC_CommandReg         	0x01    
    #define MFRC_ComIEnReg             	0x02    
    #define MFRC_DivlEnReg             	0x03    
    #define MFRC_ComIrqReg             	0x04    
    #define MFRC_DivIrqReg             	0x05
    #define MFRC_ErrorReg              	0x06    
    #define MFRC_Status1Reg            	0x07    
    #define MFRC_Status2Reg            	0x08    
    #define MFRC_FIFODataReg           	0x09
    #define MFRC_FIFOLevelReg          	0x0A
    #define MFRC_WaterLevelReg         	0x0B
    #define MFRC_ControlReg            	0x0C
    #define MFRC_BitFramingReg         	0x0D
    #define MFRC_CollReg               	0x0E
    #define MFRC_RFU0F                 	0x0F
    //PAGE1     
    #define MFRC_RFU10                 	0x10
    #define MFRC_ModeReg               	0x11
    #define MFRC_TxModeReg             	0x12
    #define MFRC_RxModeReg             	0x13
    #define MFRC_TxControlReg          	0x14
    #define MFRC_TxAutoReg             	0x15 //中文手册有误
    #define MFRC_TxSelReg              	0x16
    #define MFRC_RxSelReg              	0x17
    #define MFRC_RxThresholdReg        	0x18
    #define MFRC_DemodReg              	0x19
    #define MFRC_RFU1A                 	0x1A
    #define MFRC_RFU1B                 	0x1B
    #define MFRC_MifareReg             	0x1C
    #define MFRC_RFU1D                 	0x1D
    #define MFRC_RFU1E                 	0x1E
    #define MFRC_SerialSpeedReg        	0x1F
    //PAGE2    
    #define MFRC_RFU20                 	0x20  
    #define MFRC_CRCResultRegM         	0x21
    #define MFRC_CRCResultRegL         	0x22
    #define MFRC_RFU23                 	0x23
    #define MFRC_ModWidthReg           	0x24
    #define MFRC_RFU25                 	0x25
    #define MFRC_RFCfgReg              	0x26
    #define MFRC_GsNReg                	0x27
    #define MFRC_CWGsCfgReg            	0x28
    #define MFRC_ModGsCfgReg           	0x29
    #define MFRC_TModeReg              	0x2A
    #define MFRC_TPrescalerReg         	0x2B
    #define MFRC_TReloadRegH           	0x2C
    #define MFRC_TReloadRegL           	0x2D
    #define MFRC_TCounterValueRegH     	0x2E
    #define MFRC_TCounterValueRegL     	0x2F
    //PAGE3      
    #define MFRC_RFU30                 	0x30
    #define MFRC_TestSel1Reg           	0x31
    #define MFRC_TestSel2Reg           	0x32
    #define MFRC_TestPinEnReg          	0x33
    #define MFRC_TestPinValueReg       	0x34
    #define MFRC_TestBusReg            	0x35
    #define MFRC_AutoTestReg           	0x36
    #define MFRC_VersionReg            	0x37
    #define MFRC_AnalogTestReg         	0x38
    #define MFRC_TestDAC1Reg           	0x39  
    #define MFRC_TestDAC2Reg           	0x3A   
    #define MFRC_TestADCReg            	0x3B   
    #define MFRC_RFU3C                 	0x3C   
    #define MFRC_RFU3D                 	0x3D   
    #define MFRC_RFU3E                 	0x3E   
    #define MFRC_RFU3F                 	0x3F
    
    /*MFRC522的FIFO长度定义*/
    #define MFRC_FIFO_LENGTH       		64 
    
    /*MFRC522传输的帧长定义*/
    #define MFRC_MAXRLEN                18                
    
    /*MFRC522命令集,中文手册P59*/
    #define MFRC_IDLE              		0x00	//取消当前命令的执行
    #define MFRC_CALCCRC           		0x03    //激活CRC计算
    #define MFRC_TRANSMIT          		0x04    //发送FIFO缓冲区内容
    #define MFRC_NOCMDCHANGE            0x07	//无命令改变
    #define MFRC_RECEIVE           		0x08    //激活接收器接收数据
    #define MFRC_TRANSCEIVE        		0x0C    //发送并接收数据
    #define MFRC_AUTHENT           		0x0E    //执行Mifare认证(验证密钥)
    #define MFRC_RESETPHASE        		0x0F    //复位MFRC522
    
    /*MFRC522通讯时返回的错误代码*/
    #define MFRC_OK                 	(char)(0)
    #define MFRC_NOTAGERR            	(char)(-1)
    #define MFRC_ERR                	(char)(-2)
    
    /*MFRC522函数声明*/
    void MFRC_Init(void);
    void MFRC_WriteReg(uint8_t addr, uint8_t data);
    uint8_t MFRC_ReadReg(uint8_t addr);
    void MFRC_SetBitMask(uint8_t addr, uint8_t mask);
    void MFRC_ClrBitMask(uint8_t addr, uint8_t mask);
    void MFRC_CalulateCRC(uint8_t *pInData, uint8_t len, uint8_t *pOutData);
    char MFRC_CmdFrame(uint8_t cmd, uint8_t *pInData, uint8_t InLenByte, uint8_t *pOutData, uint16_t *pOutLenBit);
    //********************************************************************
    
    //MFRC552与MF1卡通讯接口程序
    //*********************************************************************
    /*Mifare1卡片命令字*/
    #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_TRANSFER         	0xB0               	//转存(传送)
    #define PICC_RESTORE          	0xC2               	//恢复(重储)
    #define PICC_HALT             	0x50               	//休眠
    
    /*PCD通讯时返回的错误代码*/
    #define PCD_OK                 	(char)0				//成功
    #define PCD_NOTAGERR            (char)(-1)			//无卡
    #define PCD_ERR                	(char)(-2)			//出错
    
    /*PCD函数声明*/
    void PCD_Init(void);//读写器初始化
    void PCD_Reset(void);
    void PCD_AntennaOn(void);
    void PCD_AntennaOff(void);
    char PCD_Request(uint8_t RequestMode, uint8_t *pCardType);  //寻卡,并返回卡的类型
    char PCD_Anticoll(uint8_t *pSnr);                           //防冲突,返回卡号
    char PCD_Select(uint8_t *pSnr);                             //选卡
    char PCD_AuthState(uint8_t AuthMode, uint8_t BlockAddr, uint8_t *pKey, uint8_t *pSnr); //验证密码(密码A和密码B)   
    char PCD_WriteBlock(uint8_t BlockAddr, uint8_t *pData);   //写数据
    char PCD_ReadBlock(uint8_t BlockAddr, uint8_t *pData);    //读数据
    char PCD_Value(uint8_t mode, uint8_t BlockAddr, uint8_t *pValue);   
    char PCD_BakValue(uint8_t sourceBlockAddr, uint8_t goalBlockAddr);                                 
    char PCD_Halt(void);
    //******************************************************************************************
    
    #endif
    

    5. 使用教程

    //先用CubeMx初始化
    PCD_Init();//RC522初始化
    /*
    * 函数功能:验证刷卡人,以及发送上位机刷卡人身份
    * 参    数:无
    * 返 回 值:无
    * 注    意:无
    * 作    者:苏释州
    */
    void NFC(void)
    {
    	//寻卡
    	if (PCD_Request(PICC_REQALL, RxBuffer)!=0)//返回值为0,代表寻卡成功;并把卡类型存入RxBuffer中)
    	{
    		/*果然这里要清空一下不然就会乱,会有一些RxBuffer没用的在那里占位*/
    		memset(RxBuffer, 0, sizeof(RxBuffer));//清空字符串
    		return;//如果不加这个判断的话,则会无论寻卡是否成功都会有值000
    	}
    	//防冲撞
    	if (PCD_Anticoll(RxBuffer)!=0)//防冲撞,完成这部就可以简单地 读取卡号
    	{
    		memset(RxBuffer, 0, sizeof(RxBuffer));//清空字符串
    		return;//如果不加这个判断的话,则会无论寻卡是否成功都会扰乱卡号
    	}
    	//处理卡号数据
    	sprintf(Card_ID,"%x%x%x%x",RxBuffer[0],RxBuffer[1],RxBuffer[2],RxBuffer[3]);
    	//对卡号进行权限的判断
    	if(strcmp(Card_ID,"b59dfcaa")==0)//卖家配的卡
        {
    		DoorControl(1);//开门
    		HAL_TIM_Base_Start_IT(&htim5);//开门的时候开启定时器5的中断,进入关门计时
    		memset(RxBuffer, 0, sizeof(RxBuffer));//清空字符串,这里要清除RxBuffer才行,否则Card_ID又会被组起来
        }
    	else if(strcmp(Card_ID,"e1eff3cc")==0)//刘骏帆手机本科生证
    	{
    		DoorControl(1);//开门
    		HAL_TIM_Base_Start_IT(&htim5);//开启定时器5的中断
    		memset(RxBuffer, 0, sizeof(RxBuffer));//清空字符串,这里要清除RxBuffer才行,否则Card_ID又会被组起来
    	}
        else
        {
    		DoorControl(1);//开门
    		HAL_TIM_Base_Start_IT(&htim5);//开启定时器5的中断
    		memset(RxBuffer, 0, sizeof(RxBuffer));//清空字符串
        }
        HAL_Delay(100);
    	return;
    }
    
    
    物联沃分享整理
    物联沃-IOTWORD物联网 » 的实现STM32下实现NFC门禁模块(RC522)的应用

    发表评论