赞
踩
目录
STM32
| RC522 |
PB12 |
SDA
|
PB13
|
SCK
|
PB14
|
MOSI
|
PB15
|
MISO
|
悬空
|
IRQ
|
GND |
GND
|
PB1
|
RST
|
VCC
|
VCC
|
- #ifndef _RC522_H
- #define _RC522_H
-
- #include "stm32f1xx_hal.h"
-
- /* CS/NSS/SDA均表示片选 */
- #define RC522_RST_Pin GPIO_PIN_1
- #define RC522_RST_GPIO_Port GPIOB
- #define RC522_CS_Pin GPIO_PIN_12
- #define RC522_CS_GPIO_Port GPIOB
-
- #define osDelay HAL_Delay
- #define RS522_RST(x) do{ x ? \
- HAL_GPIO_WritePin(RC522_RST_GPIO_Port, RC522_RST_Pin, GPIO_PIN_SET) :\
- HAL_GPIO_WritePin(RC522_RST_GPIO_Port, RC522_RST_Pin, GPIO_PIN_RESET);\
- }while(0)
- #define RS522_NSS(x) do{ x ? \
- HAL_GPIO_WritePin(RC522_CS_GPIO_Port, RC522_CS_Pin, GPIO_PIN_SET) :\
- HAL_GPIO_WritePin(RC522_CS_GPIO_Port, RC522_CS_Pin, GPIO_PIN_RESET);\
- }while(0)
- /***********************************************************************************
- * 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);
- void Cardcompare(void); //自行定义函数
-
- #endif
-
-
- #include "stm32f1xx_hal.h"
- #include "./BSP/RC522/rc522.h"
- #include "stdio.h"
- #include "./SYSTEM/usart/usart.h"
- #include <string.h>
-
-
-
- extern SPI_HandleTypeDef hspi2;
-
- /**************************************************************************************
- * 函数名称:MFRC_Init
- * 功能描述:MFRC初始化
- * 入口参数:无
- * 出口参数:无
- * 返 回 值:无
- * 说 明:MFRC的SPI接口速率为0~10Mbps
- ***************************************************************************************/
- void MFRC_Init(void)
- {
- RS522_NSS(1);
- RS522_RST(1);
- }
-
-
- /**************************************************************************************
- * 函数名称: SPI_RW_Byte
- * 功能描述: 模拟SPI读写一个字节
- * 入口参数: -byte:要发送的数据
- * 出口参数: -byte:接收到的数据
- ***************************************************************************************/
- static uint8_t ret; //这些函数是HAL与标准库不同的地方【读写函数】
- uint8_t SPI2_RW_Byte(uint8_t byte)
- {
- HAL_SPI_TransmitReceive(&hspi2, &byte, &ret, 1, 10);//把byte 写入,并读出一个值,把它存入ret
- return ret;//入口是byte 的地址,读取时用的也是ret地址,一次只写入一个值10
- }
-
-
- /**************************************************************************************
- * 函数名称:MFRC_WriteReg
- * 功能描述:写一个寄存器
- * 入口参数:-addr:待写的寄存器地址
- * -data:待写的寄存器数据
- * 出口参数:无
- * 返 回 值:无
- * 说 明:无
- ***************************************************************************************/
- void MFRC_WriteReg(uint8_t addr, uint8_t data)
- {
- uint8_t AddrByte;
- AddrByte = (addr << 1 ) & 0x7E; //求出地址字节
- RS522_NSS(0); //NSS拉低
- SPI2_RW_Byte(AddrByte); //写地址字节
- SPI2_RW_Byte(data); //写数据
- RS522_NSS(1); //NSS拉高
- }
-
-
- /**************************************************************************************
- * 函数名称: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); //处理过的数据再写入寄存器
- }
-
-
- /**************************************************************************************
- * 函数名称:MFRC_CalulateCRC
- * 功能描述:用MFRC计算CRC结果
- * 入口参数:-pInData:带进行CRC计算的数据
- * -len:带进行CRC计算的数据长度
- * -pOutData:CRC计算结果
- * 出口参数:-pOutData:CRC计算结果
- * 返 回 值:无
- * 说 明:无
- ***************************************************************************************/
- void MFRC_CalulateCRC(uint8_t *pInData, uint8_t len, uint8_t *pOutData)
- {
- //0xc1 1 2 pInData[2]
- uint8_t temp;
- uint32_t i;
- MFRC_ClrBitMask(MFRC_DivIrqReg, 0x04); //使能CRC中断
- MFRC_WriteReg(MFRC_CommandReg, MFRC_IDLE); //取消当前命令的执行
- MFRC_SetBitMask(MFRC_FIFOLevelReg, 0x80); //清除FIFO及其标志位
- for(i = 0; i < len; i++) //将待CRC计算的数据写入FIFO
- {
- MFRC_WriteReg(MFRC_FIFODataReg, *(pInData + i));
- }
- MFRC_WriteReg(MFRC_CommandReg, MFRC_CALCCRC); //执行CRC计算
- i = 100000;
- do
- {
- temp = MFRC_ReadReg(MFRC_DivIrqReg); //读取DivIrqReg寄存器的值
- i--;
- }
- while((i != 0) && !(temp & 0x04)); //等待CRC计算完成
- pOutData[0] = MFRC_ReadReg(MFRC_CRCResultRegL); //读取CRC计算结果
- pOutData[1] = MFRC_ReadReg(MFRC_CRCResultRegM);
- }
-
-
- /**************************************************************************************
- * 函数名称: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;
- }
-
-
- /**************************************************************************************
- * 函数名称: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(); //开天线
-
- printf("初始化完成\n");
-
- }
-
-
- /**************************************************************************************
- * 函数名称: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);
- }
-
-
- /***************************************************************************************
- * 函数名称:PCD_Init
- * 功能描述:读写器初始化
- * 入口参数:无
- * 出口参数:无
- * 返 回 值:无
- * 说 明:无
- ***************************************************************************************/
- void PCD_Init(void)
- {
- MFRC_Init(); //MFRC管脚配置
- PCD_Reset(); //PCD复位 并初始化配置
- PCD_AntennaOff(); //关闭天线
- PCD_AntennaOn(); //开启天线
- }
-
-
- /***************************************************************************************
- * 函数名称: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;
- }
- }
-
- MFRC_SetBitMask(MFRC_CollReg, 0x80);
- return status;
- }
-
-
- /***************************************************************************************
- * 函数名称:PCD_Select
- * 功能描述:选卡
- * 入口参数:-pSnr:卡片序列号,4字节
- * 出口参数:无
- * 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
- * 说 明:无
- ***************************************************************************************/
- char PCD_Select(uint8_t *pSnr)
- {
- char status;
- uint8_t i;
- uint16_t unLen;
- uint8_t CmdFrameBuf[MFRC_MAXRLEN];
-
- CmdFrameBuf[0] = PICC_ANTICOLL1;
- CmdFrameBuf[1] = 0x70;
- CmdFrameBuf[6] = 0;
- for(i = 0; i < 4; i++)
- {
- CmdFrameBuf[i + 2] = *(pSnr + i);
- CmdFrameBuf[6] ^= *(pSnr + i);
- }
- MFRC_CalulateCRC(CmdFrameBuf, 7, &CmdFrameBuf[7]);
-
- MFRC_ClrBitMask(MFRC_Status2Reg, 0x08);
-
- status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 9, CmdFrameBuf, &unLen);
-
- if((status == PCD_OK) && (unLen == 0x18))
- {
- status = PCD_OK;
- }
- else
- {
- status = PCD_ERR;
- }
- return status;
- }
-
-
- /***************************************************************************************
- * 函数名称:PCD_AuthState
- * 功能描述:验证卡片密码
- * 入口参数:-AuthMode:验证模式
- * PICC_AUTHENT1A:验证A密码
- * PICC_AUTHENT1B:验证B密码
- * -BlockAddr:块地址(0~63)
- * -pKey:密码
- * -pSnr:卡片序列号,4字节
- * 出口参数:无
- * 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
- * 说 明:验证密码时,以扇区为单位,BlockAddr参数可以是同一个扇区的任意块
- ***************************************************************************************/
- char PCD_AuthState(uint8_t AuthMode, uint8_t BlockAddr, uint8_t *pKey, uint8_t *pSnr)
- {
- char status;
- uint16_t unLen;
- uint8_t i, CmdFrameBuf[MFRC_MAXRLEN];
- CmdFrameBuf[0] = AuthMode;
- CmdFrameBuf[1] = BlockAddr;
- for(i = 0; i < 6; i++)
- {
- CmdFrameBuf[i + 2] = *(pKey + i);
- }
- for(i = 0; i < 4; i++)
- {
- CmdFrameBuf[i + 8] = *(pSnr + i);
- }
-
- status = MFRC_CmdFrame(MFRC_AUTHENT, CmdFrameBuf, 12, CmdFrameBuf, &unLen);
- if((status != PCD_OK) || (!(MFRC_ReadReg(MFRC_Status2Reg) & 0x08)))
- {
- status = PCD_ERR;
- }
-
- return status;
- }
-
-
- /***************************************************************************************
- * 函数名称:PCD_WriteBlock
- * 功能描述:读MF1卡数据块
- * 入口参数:-BlockAddr:块地址
- * -pData: 用于保存待写入的数据,16字节
- * 出口参数:无
- * 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
- * 说 明:无
- ***************************************************************************************/
- char PCD_WriteBlock(uint8_t BlockAddr, uint8_t *pData)
- {
- char status;
- uint16_t unLen;
- uint8_t i, CmdFrameBuf[MFRC_MAXRLEN];
-
- CmdFrameBuf[0] = PICC_WRITE;
- CmdFrameBuf[1] = BlockAddr;
- MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
-
- status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
-
- if((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
- {
- status = PCD_ERR;
- }
-
- if(status == PCD_OK)
- {
- for(i = 0; i < 16; i++)
- {
- CmdFrameBuf[i] = *(pData + i);
- }
- MFRC_CalulateCRC(CmdFrameBuf, 16, &CmdFrameBuf[16]);
-
- status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 18, CmdFrameBuf, &unLen);
-
- if((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
- {
- status = PCD_ERR;
- }
- }
-
- return status;
- }
-
-
- /***************************************************************************************
- * 函数名称:PCD_ReadBlock
- * 功能描述:读MF1卡数据块
- * 入口参数:-BlockAddr:块地址
- * -pData: 用于保存读出的数据,16字节
- * 出口参数:-pData: 用于保存读出的数据,16字节
- * 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
- * 说 明:无
- ***************************************************************************************/
- char PCD_ReadBlock(uint8_t BlockAddr, uint8_t *pData)
- {
- char status;
- uint16_t unLen;
- uint8_t i, CmdFrameBuf[MFRC_MAXRLEN];
-
- CmdFrameBuf[0] = PICC_READ;
- CmdFrameBuf[1] = BlockAddr;
- MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
-
- status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
- if((status == PCD_OK) && (unLen == 0x90))
- {
- for(i = 0; i < 16; i++)
- {
- *(pData + i) = CmdFrameBuf[i];
- }
- }
- else
- {
- status = PCD_ERR;
- }
-
- return status;
- }
-
-
- /***************************************************************************************
- * 函数名称:PCD_Value
- * 功能描述:对MF1卡数据块增减值操作
- * 入口参数:
- * -BlockAddr:块地址
- * -pValue:四字节增值的值,低位在前
- * -mode:数值块操作模式
- * PICC_INCREMENT:增值
- * PICC_DECREMENT:减值
- * 出口参数:无
- * 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
- * 说 明:无
- ***************************************************************************************/
- char PCD_Value(uint8_t mode, uint8_t BlockAddr, uint8_t *pValue)
- {
- //0XC1 1 Increment[4]={0x03, 0x01, 0x01, 0x01};
- char status;
- uint16_t unLen;
- uint8_t i, CmdFrameBuf[MFRC_MAXRLEN];
-
- CmdFrameBuf[0] = mode;
- CmdFrameBuf[1] = BlockAddr;
- MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
-
- status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
-
- if((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
- {
- status = PCD_ERR;
- }
-
- if(status == PCD_OK)
- {
- for(i = 0; i < 16; i++)
- {
- CmdFrameBuf[i] = *(pValue + i);
- }
- MFRC_CalulateCRC(CmdFrameBuf, 4, &CmdFrameBuf[4]);
- unLen = 0;
- status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 6, CmdFrameBuf, &unLen);
- if(status != PCD_ERR)
- {
- status = PCD_OK;
- }
- }
-
- if(status == PCD_OK)
- {
- CmdFrameBuf[0] = PICC_TRANSFER;
- CmdFrameBuf[1] = BlockAddr;
- MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
-
- status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
-
- if((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
- {
- status = PCD_ERR;
- }
- }
- return status;
- }
-
-
- /***************************************************************************************
- * 函数名称:PCD_BakValue
- * 功能描述:备份钱包(块转存)
- * 入口参数:-sourceBlockAddr:源块地址
- * -goalBlockAddr :目标块地址
- * 出口参数:无
- * 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
- * 说 明:只能在同一个扇区内转存
- ***************************************************************************************/
- char PCD_BakValue(uint8_t sourceBlockAddr, uint8_t goalBlockAddr)
- {
- char status;
- uint16_t unLen;
- uint8_t CmdFrameBuf[MFRC_MAXRLEN];
-
- CmdFrameBuf[0] = PICC_RESTORE;
- CmdFrameBuf[1] = sourceBlockAddr;
- MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
- status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
- if((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
- {
- status = PCD_ERR;
- }
-
- if(status == PCD_OK)
- {
- CmdFrameBuf[0] = 0;
- CmdFrameBuf[1] = 0;
- CmdFrameBuf[2] = 0;
- CmdFrameBuf[3] = 0;
- MFRC_CalulateCRC(CmdFrameBuf, 4, &CmdFrameBuf[4]);
- status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 6, CmdFrameBuf, &unLen);
- if(status != PCD_ERR)
- {
- status = PCD_OK;
- }
- }
-
- if(status != PCD_OK)
- {
- return PCD_ERR;
- }
-
- CmdFrameBuf[0] = PICC_TRANSFER;
- CmdFrameBuf[1] = goalBlockAddr;
- MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
- status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
- if((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
- {
- status = PCD_ERR;
- }
-
- return status;
- }
-
-
- /***************************************************************************************
- * 函数名称:PCD_Halt
- * 功能描述:命令卡片进入休眠状态
- * 入口参数:无
- * 出口参数:无
- * 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
- * 说 明:无
- ***************************************************************************************/
- char PCD_Halt(void)
- {
- char status;
- uint16_t unLen;
- uint8_t CmdFrameBuf[MFRC_MAXRLEN];
-
- CmdFrameBuf[0] = PICC_HALT;
- CmdFrameBuf[1] = 0;
- MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
-
- status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
-
- return status;
- }
-
- uint8_t readUid[5]; //卡号
- uint8_t CT[3]; //卡类型
- uint8_t DATA[16]; //存放数据
-
- uint8_t KEY_A[6]= {0xff,0xff,0xff,0xff,0xff,0xff};
- uint8_t KEY_B[6]= {0xff,0xff,0xff,0xff,0xff,0xff};
- unsigned char buf[16]={0x01,0x02,0x03,0x04,0x05,0x06,0xff
- ,0x07,0x80,0x69,0x18,0x17,0x16,0x15,0x14,0x13};
-
- uint8_t status;
- uint8_t addr = 0x01*4 + 0x03; // 总共16个扇区。一个扇区4个块,从0开始算,表示第一扇区第三块
-
- void Cardcompare(void)
- {
- uint8_t i;
- //status = PCD_WriteBlock(addr, buf);
- status = PCD_Request(0x52, CT); //找到卡返回0
- if(!status) //寻卡成功
- {
- status = PCD_ERR;
- status = PCD_Anticoll(readUid); //防冲撞
- }
-
- if(!status) //防冲撞成功
- {
- status = PCD_ERR;
- printf("卡的类型为:%x%x%x\r\n",CT[0],CT[1],CT[2]); /* 读取卡的类型 */
- printf("卡号:%x-%x-%x-%x\r\n",readUid[0],readUid[1],readUid[2],readUid[3]);
- HAL_Delay(1000);
- status=PCD_Select(readUid); /* 选卡 */
- }
-
- if(!status) //选卡成功
- {
- status = PCD_ERR;
- // 验证A密钥 块地址 密码 SN
- status = PCD_AuthState(PICC_AUTHENT1A, addr, KEY_A, readUid);
- if(status == PCD_OK)//验证A成功
- {
- printf("A密钥验证成功\r\n");
- HAL_Delay(1000);
- }
- else
- {
- printf("A密钥验证失败\r\n");
- HAL_Delay(1000);
- }
-
- // 验证B密钥 块地址 密码 SN
- status = PCD_AuthState(PICC_AUTHENT1B, addr, KEY_B, readUid);
- if(status == PCD_OK)//验证B成功
- {
- printf("B密钥验证成功\r\n");
- }
- else
- {
- printf("B密钥验证失败\r\n");
- }
- HAL_Delay(1000);
- }
-
- if(status == PCD_OK)//验证密码成功,接着读取3块
- {
- status = PCD_ERR;
- status = PCD_ReadBlock(addr, DATA);
-
- if(status == PCD_OK)//读卡成功
- {
- printf("1扇区3块DATA:");
- for(i = 0; i < 16; i++)
- {
- printf("%02x", DATA[i]);
- }
- printf("\r\n");
-
- }
- else
- {
- printf("读卡失败\r\n");
- }
- HAL_Delay(1000);
- }
-
- }
- #ifndef __SPI_H
- #define __SPI_H
-
- #include "stm32f1xx_hal.h"
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- extern SPI_HandleTypeDef hspi2;
-
-
- void MX_SPI2_Init(void);
-
-
- #ifdef __cplusplus
- }
- #endif
- #endif
- #include "./BSP/SPI/spi.h"
- #include "main.h"
-
- SPI_HandleTypeDef hspi2;
-
- /* SPI2 init function */
- void MX_SPI2_Init(void)
- {
-
- hspi2.Instance = SPI2;
- hspi2.Init.Mode = SPI_MODE_MASTER;
- hspi2.Init.Direction = SPI_DIRECTION_2LINES;
- hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
- hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
- hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
- hspi2.Init.NSS = SPI_NSS_SOFT;
- hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
- hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
- hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
- hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
- hspi2.Init.CRCPolynomial = 10;
- if (HAL_SPI_Init(&hspi2) != HAL_OK)
- {
- Error_Handler();
- }
-
- }
-
- void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
- {
-
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- if(spiHandle->Instance==SPI2)
- {
- /* USER CODE BEGIN SPI2_MspInit 0 */
-
- /* USER CODE END SPI2_MspInit 0 */
- /* SPI2 clock enable */
- __HAL_RCC_SPI2_CLK_ENABLE();
-
- __HAL_RCC_GPIOB_CLK_ENABLE();
- /**SPI2 GPIO Configuration
- PB13 ------> SPI2_SCK
- PB14 ------> SPI2_MISO
- PB15 ------> SPI2_MOSI
- */
- GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_15;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
-
- GPIO_InitStruct.Pin = GPIO_PIN_14;
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
- GPIO_InitTypeDef GPIO_InitStruct = {0};
-
- /*
- PB12为片选引脚(CS/NSS/SDA)
- PB1为RST引脚
- */
- /*Configure GPIO pins : PB12 PB4 */
- GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_1;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
-
- /*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_1, GPIO_PIN_SET); /* 必须要拉高 */
-
- }
- }
- #include "./SYSTEM/sys/sys.h"
- #include "./SYSTEM/usart/usart.h"
- #include "./SYSTEM/delay/delay.h"
- #include "./BSP/LED/led.h"
- #include "./BSP/KEY/key.h"
- #include "./BSP/OLED/OLED.h"
- #include "./BSP/SPI/spi.h"
- #include "./BSP/RC522/rc522.h"
- #include "main.h"
-
-
- void SystemClock_Config(void);
-
-
- int main(void)
- {
- SystemClock_Config(); /* 系统时钟初始化 */
-
- HAL_Init(); /* 初始化HAL库 */
- sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
- delay_init(72); /* 延时初始化 */
- usart_init(115200); /* 初始化串口 */
- led_init(); /* led初始化 */
- key_init(); /* 按键初始化 */
- OLED_Init(); /* oled显示初始化 */
- MX_SPI2_Init(); /* spi初始化 */
-
- MFRC_Init(); /* MFRC522初始化 */
- PCD_Reset(); /* MFRC522重置 */
-
-
- while (1)
- {
- Cardcompare();
- }
-
- }
-
- /**
- * @brief System Clock Configuration
- * @retval None
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
-
- /** Initializes the RCC Oscillators according to the specified parameters
- * in the RCC_OscInitTypeDef structure.
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
-
- /** Initializes the CPU, AHB and APB buses clocks
- */
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
-
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
- {
- Error_Handler();
- }
- }
-
-
- /* USER CODE BEGIN 4 */
-
- /* USER CODE END 4 */
-
- /**
- * @brief This function is executed in case of error occurrence.
- * @retval None
- */
- void Error_Handler(void)
- {
- /* USER CODE BEGIN Error_Handler_Debug */
- /* User can add his own implementation to report the HAL error return state */
- __disable_irq();
- while (1)
- {
- }
- /* USER CODE END Error_Handler_Debug */
- }
-
-
- #ifdef USE_FULL_ASSERT
- /**
- * @brief Reports the name of the source file and the source line number
- * where the assert_param error has occurred.
- * @param file: pointer to the source file name
- * @param line: assert_param error line source number
- * @retval None
- */
- void assert_failed(uint8_t *file, uint32_t line)
- {
- /* USER CODE BEGIN 6 */
- /* User can add his own implementation to report the file name and line number,
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- /* USER CODE END 6 */
- }
- #endif /* USE_FULL_ASSERT */
至于main.h主要是声明Error_Handler();函数,其他main.c中如系统时钟初始化等函数均是由cumax所自动生成。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。