STM32驱动RC522-RFID模块

简介:STM32F103C8T6驱动RC522-RFID模块源码介绍。

开发平台:KEIL ARM

MCU型号:STM32F103C8T6

传感器型号:RC522-RFID

特别提示:驱动内可能使用了某些其他组件,比如delay等,在文末外设模板下载地址内有。

1积分源码下载地址在文末!!!

接口图:

使用举例:

#include <stdio.h>
#include "SPI.h"
#include "RC522.h"

int main()
{
	uint8_t cardID[4] = {0};
	SPIClass.SPI1_Init(); // SPI初始化
	MFRC522_Init(); // RC522初始化
	while(1) {
		if(!RC522_cardScan(cardID)) {
			printf("card scan success, id:0x%02X%02X%02X%02X\n", cardID[0], cardID[1], cardID[2], cardID[3]);
		} else {
			printf("card scan failure\n");
		}
	}
}

驱动源码:

SPI.c

#include "main.h"

static void SPI1_Init(void);
static void SPI2_Init(void);
static uint8_t SPI_WriteRead(SPI_TypeDef* SPIx, uint8_t data, uint32_t timeout);
static void SPI_CS_WritePin(SPI_TypeDef* SPIx, BitAction bitVal);

SPIClassStruct SPIClass = {
	.SPI1_Init = SPI1_Init,
	.SPI2_Init = SPI2_Init,
	.WriteRead = SPI_WriteRead,
	.WriteCSPin = SPI_CS_WritePin
};
// SPI1 CS
#define SPI1_CS_GPIO_PORT    		GPIOB
#define SPI1_CS_GPIO_CLK 	    	RCC_APB2Periph_GPIOB
#define SPI1_CS_GPIO_PIN			GPIO_Pin_0
// SPI2 CS
#define SPI2_CS_GPIO_PORT    		GPIOA
#define SPI2_CS_GPIO_CLK 	    	RCC_APB2Periph_GPIOA
#define SPI2_CS_GPIO_PIN			GPIO_Pin_0

/**
  * @brief  SPI1初始化
  * @param  None
  * @retval None
  */
static void SPI1_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	SPI_InitTypeDef  SPI_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	// SPI1 SCK-PA5  MOSI-PA7
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	// SPI1 MISO-PA6
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	// software CS user write
	RCC_APB2PeriphClockCmd(SPI1_CS_GPIO_CLK, ENABLE);
	GPIO_InitStructure.GPIO_Pin = SPI1_CS_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(SPI1_CS_GPIO_PORT, &GPIO_InitStructure);
	GPIO_WriteBit(SPI1_CS_GPIO_PORT, SPI1_CS_GPIO_PIN, Bit_SET); // 拉高片选引脚
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // SPI1时钟使能

	SPI_Cmd(SPI1, DISABLE);
	SPI_I2S_DeInit(SPI1);
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // SPI设置为双线全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 设置SPI为主模式
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // SPI时钟空闲时为低电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 第一个时钟沿开始采样数据
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // CS信号由软件管理
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // SPI波特率预分频值 72M / Prescaler
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式

	SPI_Init(SPI1, &SPI_InitStructure); // 根据SPI_InitStruct中指定的参数初始化外设SPI寄存器
	SPI_Cmd(SPI1, ENABLE); // 使能SPI
}

/**
  * @brief  SPI2初始化
  * @param  None
  * @retval None
  */
static void SPI2_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	SPI_InitTypeDef  SPI_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	// SPI1 SCK-PB13  MOSI-PB15
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	// SPI1 MISO-PB14
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	// software CS user write
	RCC_APB2PeriphClockCmd(SPI2_CS_GPIO_CLK, ENABLE);
	GPIO_InitStructure.GPIO_Pin = SPI2_CS_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(SPI2_CS_GPIO_PORT, &GPIO_InitStructure);
	GPIO_WriteBit(SPI2_CS_GPIO_PORT, SPI2_CS_GPIO_PIN, Bit_SET); // 拉高片选引脚
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); // SPI2时钟使能

	SPI_Cmd(SPI2, DISABLE);
	SPI_I2S_DeInit(SPI2);
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // SPI设置为双线全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 设置SPI为主模式
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // SPI时钟空闲时为低电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 第一个时钟沿开始采样数据
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // CS信号由软件管理
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; // SPI波特率预分频值 36M / Prescaler
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式

	SPI_Init(SPI2, &SPI_InitStructure); // 根据SPI_InitStruct中指定的参数初始化外设SPI寄存器
	SPI_Cmd(SPI2, ENABLE); // 使能SPI
}
/**
  * @brief  SPI读写函数
  * @param  None
  * @retval 0-超时 
  */
static uint8_t SPI_WriteRead(SPI_TypeDef* SPIx, uint8_t data, uint32_t timeout)
{
	uint32_t retry = 0;				 	
	/* Loop while DR register in not emplty */
	while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET) // 发送缓存标志位为空
	{
		retry++;
		if(retry > timeout) return 0;
	}			  
	SPI_I2S_SendData(SPIx, data); // 通过外设SPI2发送一个数据
	retry = 0;
	/* Wait to receive a byte */
	while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET) // 接收缓存标志位不为空
	{
		retry++;
		if(retry > timeout) return 0;
	}	  						    
	/* Return the byte read from the SPI bus */
	return SPI_I2S_ReceiveData(SPIx); // 通过SPI2返回接收数据	
}
/**
  * @brief  SPI读写函数
  * @param  None
  * @retval 0-成功
  */
static void SPI_CS_WritePin(SPI_TypeDef* SPIx, BitAction bitVal)
{
	if(SPIx == SPI1) {
		GPIO_WriteBit(SPI1_CS_GPIO_PORT, SPI1_CS_GPIO_PIN, bitVal);
	} else if(SPIx == SPI2) {
		GPIO_WriteBit(SPI2_CS_GPIO_PORT, SPI2_CS_GPIO_PIN, bitVal);
	}
}

SPI.h

#ifndef __SPI_AS_H
#define __SPI_AS_H

#include "main.h"

typedef struct {
	void (* SPI1_Init)(void);
	void (* SPI2_Init)(void);
	uint8_t (* WriteRead)(SPI_TypeDef *, uint8_t, uint32_t);
	void (* WriteCSPin)(SPI_TypeDef *, BitAction);
} SPIClassStruct;

extern SPIClassStruct SPIClass;

#endif

RC522.c

// Mifare RC522 RFID Card reader 13.56 MHz

// MFRC522		STM32F103		DESCRIPTION
// CS (SDA)		PB0				SPI1_NSS	Chip select for SPI
// SCK			PA5				SPI1_SCK	Serial Clock for SPI
// MOSI			PA7 			SPI1_MOSI	Master In Slave Out for SPI
// MISO			PA6				SPI1_MISO	Master Out Slave In for SPI
// IRQ			-				Irq
// GND			GND				Ground
// RST			3.3V			Reset pin (3.3V)
// VCC			3.3V			3.3V power
#include "RC522.h"

/******template******/
// 0-255数字转换为字符  0xFF--"FF"
void char_to_hex(uint8_t data, uint8_t *retStr) {
	uint8_t digits[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
	
	if (data < 16) {
		retStr[0] = '0';
		retStr[1] = digits[data];
	} else {
		retStr[0] = digits[(data & 0xF0)>>4];
		retStr[1] = digits[(data & 0x0F)];
	}
}
/**
  * @brief  扫描RFID卡
  * @param  cardID 四字节数组
  * @retval 0扫描到RFID卡
  */
uint8_t RC522_cardScan(uint8_t *cardID)
{
	if(!MFRC522_Request(PICC_REQIDL, cardID)) {
		if(!MFRC522_Anticoll(cardID)) {
			
#ifdef DEBUG_printf
			uint8_t cardIDString[8] = {0};
			for(uint8_t i = 0; i < 4; i++) {
				char_to_hex(cardID[i], cardIDString+i*2);
			}
			printf("card id:%s\n", cardIDString);
#endif
			return 0;
		}
	}
	return 1;
}
/********************/


void SPI1_WriteReg(uint8_t address, uint8_t value) {
	cs_reset();
	SPISendByte(address);
	SPISendByte(value);
	cs_set();
}

uint8_t SPI1_ReadReg(uint8_t address) {
	uint8_t	val;

	cs_reset();
	SPISendByte(address);
	val = SPISendByte(0x00);
	cs_set();
	return val;
}

void MFRC522_WriteRegister(uint8_t addr, uint8_t val) {
	addr = (addr << 1) & 0x7E;															// Address format: 0XXXXXX0
  SPI1_WriteReg(addr, val);
}

uint8_t MFRC522_ReadRegister(uint8_t addr) {
	uint8_t val;

	addr = ((addr << 1) & 0x7E) | 0x80;
	val = SPI1_ReadReg(addr);
	return val;	
}

uint8_t MFRC522_Check(uint8_t* id) {
	uint8_t status;
	status = MFRC522_Request(PICC_REQIDL, id);							// Find cards, return card type
	if (status == MI_OK) status = MFRC522_Anticoll(id);			// Card detected. Anti-collision, return card serial number 4 bytes
	MFRC522_Halt();																					// Command card into hibernation 
	return status;
}

uint8_t MFRC522_Compare(uint8_t* CardID, uint8_t* CompareID) {
	uint8_t i;
	for (i = 0; i < 5; i++) {
		if (CardID[i] != CompareID[i]) return MI_ERR;
	}
	return MI_OK;
}

void MFRC522_SetBitMask(uint8_t reg, uint8_t mask) {
	MFRC522_WriteRegister(reg, MFRC522_ReadRegister(reg) | mask);
}

void MFRC522_ClearBitMask(uint8_t reg, uint8_t mask){
	MFRC522_WriteRegister(reg, MFRC522_ReadRegister(reg) & (~mask));
}

uint8_t MFRC522_Request(uint8_t reqMode, uint8_t* TagType) {
	uint8_t status;  
	uint16_t backBits;																			// The received data bits

	MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x07);		// TxLastBists = BitFramingReg[2..0]
	TagType[0] = reqMode;
	status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
	if ((status != MI_OK) || (backBits != 0x10)) status = MI_ERR;
	return status;
}

uint8_t MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen) {
	uint8_t status = MI_ERR;
	uint8_t irqEn = 0x00;
	uint8_t waitIRq = 0x00;
	uint8_t lastBits;
	uint8_t n;
	uint16_t i;

	switch (command) {
		case PCD_AUTHENT: {
			irqEn = 0x12;
			waitIRq = 0x10;
			break;
		}
		case PCD_TRANSCEIVE: {
			irqEn = 0x77;
			waitIRq = 0x30;
			break;
		}
		default:
		break;
	}

	MFRC522_WriteRegister(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
	MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
	MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
	MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_IDLE);

	// Writing data to the FIFO
	for (i = 0; i < sendLen; i++) MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, sendData[i]);

	// Execute the command
	MFRC522_WriteRegister(MFRC522_REG_COMMAND, command);
	if (command == PCD_TRANSCEIVE) MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80);		// StartSend=1,transmission of data starts 

	// Waiting to receive data to complete
	i = 2000;	// i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms
	do {
		// CommIrqReg[7..0]
		// Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
		n = MFRC522_ReadRegister(MFRC522_REG_COMM_IRQ);
		i--;
	} while ((i!=0) && !(n&0x01) && !(n&waitIRq));

	MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80);																// StartSend=0

	if (i != 0)  {
		if (!(MFRC522_ReadRegister(MFRC522_REG_ERROR) & 0x1B)) {
			status = MI_OK;
			if (n & irqEn & 0x01) status = MI_NOTAGERR;
			if (command == PCD_TRANSCEIVE) {
				n = MFRC522_ReadRegister(MFRC522_REG_FIFO_LEVEL);
				lastBits = MFRC522_ReadRegister(MFRC522_REG_CONTROL) & 0x07;
				if (lastBits) *backLen = (n-1)*8+lastBits; else *backLen = n*8;
				if (n == 0) n = 1;
				if (n > MFRC522_MAX_LEN) n = MFRC522_MAX_LEN;
				for (i = 0; i < n; i++) backData[i] = MFRC522_ReadRegister(MFRC522_REG_FIFO_DATA);		// Reading the received data in FIFO
			}
		} else status = MI_ERR;
	}
	return status;
}

uint8_t MFRC522_Anticoll(uint8_t* serNum) {
	uint8_t status;
	uint8_t i;
	uint8_t serNumCheck = 0;
	uint16_t unLen;

	MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x00);												// TxLastBists = BitFramingReg[2..0]
	serNum[0] = PICC_ANTICOLL;
	serNum[1] = 0x20;
	status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
	if (status == MI_OK) {
		// Check card serial number
		for (i = 0; i < 4; i++) serNumCheck ^= serNum[i];
		if (serNumCheck != serNum[i]) status = MI_ERR;
	}
	return status;
} 

void MFRC522_CalculateCRC(uint8_t*  pIndata, uint8_t len, uint8_t* pOutData) {
	uint8_t i, n;

	MFRC522_ClearBitMask(MFRC522_REG_DIV_IRQ, 0x04);													// CRCIrq = 0
	MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);													// Clear the FIFO pointer
	// Write_MFRC522(CommandReg, PCD_IDLE);

	// Writing data to the FIFO	
	for (i = 0; i < len; i++) MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, *(pIndata+i));
	MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_CALCCRC);

	// Wait CRC calculation is complete
	i = 0xFF;
	do {
		n = MFRC522_ReadRegister(MFRC522_REG_DIV_IRQ);
		i--;
	} while ((i!=0) && !(n&0x04));																						// CRCIrq = 1

	// Read CRC calculation result
	pOutData[0] = MFRC522_ReadRegister(MFRC522_REG_CRC_RESULT_L);
	pOutData[1] = MFRC522_ReadRegister(MFRC522_REG_CRC_RESULT_M);
}

uint8_t MFRC522_SelectTag(uint8_t* serNum) {
	uint8_t i;
	uint8_t status;
	uint8_t size;
	uint16_t recvBits;
	uint8_t buffer[9]; 

	buffer[0] = PICC_SElECTTAG;
	buffer[1] = 0x70;
	for (i = 0; i < 5; i++) buffer[i+2] = *(serNum+i);
	MFRC522_CalculateCRC(buffer, 7, &buffer[7]);		//??
	status = MFRC522_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);
	if ((status == MI_OK) && (recvBits == 0x18)) size = buffer[0]; else size = 0;
	return size;
}

uint8_t MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t* Sectorkey, uint8_t* serNum) {
	uint8_t status;
	uint16_t recvBits;
	uint8_t i;
	uint8_t buff[12]; 

	// Verify the command block address + sector + password + card serial number
	buff[0] = authMode;
	buff[1] = BlockAddr;
	for (i = 0; i < 6; i++) buff[i+2] = *(Sectorkey+i);
	for (i=0; i<4; i++) buff[i+8] = *(serNum+i);
	status = MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);
	if ((status != MI_OK) || (!(MFRC522_ReadRegister(MFRC522_REG_STATUS2) & 0x08))) status = MI_ERR;
	return status;
}

uint8_t MFRC522_Read(uint8_t blockAddr, uint8_t* recvData) {
	uint8_t status;
	uint16_t unLen;

	recvData[0] = PICC_READ;
	recvData[1] = blockAddr;
	MFRC522_CalculateCRC(recvData,2, &recvData[2]);
	status = MFRC522_ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen);
	if ((status != MI_OK) || (unLen != 0x90)) status = MI_ERR;
	return status;
}

uint8_t MFRC522_Write(uint8_t blockAddr, uint8_t* writeData) {
	uint8_t status;
	uint16_t recvBits;
	uint8_t i;
	uint8_t buff[18]; 

	buff[0] = PICC_WRITE;
	buff[1] = blockAddr;
	MFRC522_CalculateCRC(buff, 2, &buff[2]);
	status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);
	if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) status = MI_ERR;
	if (status == MI_OK) {
		// Data to the FIFO write 16Byte
		for (i = 0; i < 16; i++) buff[i] = *(writeData+i);
		MFRC522_CalculateCRC(buff, 16, &buff[16]);
		status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);
		if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) status = MI_ERR;
	}
	return status;
}

void MFRC522_Init(void) {
	MFRC522_Reset();
	MFRC522_WriteRegister(MFRC522_REG_T_MODE, 0x8D);
	MFRC522_WriteRegister(MFRC522_REG_T_PRESCALER, 0x3E);
	MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_L, 30);           
	MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_H, 0);
	MFRC522_WriteRegister(MFRC522_REG_RF_CFG, 0x70);				// 48dB gain	
	MFRC522_WriteRegister(MFRC522_REG_TX_AUTO, 0x40);
	MFRC522_WriteRegister(MFRC522_REG_MODE, 0x3D);
	MFRC522_AntennaOn();																		// Open the antenna
}

void MFRC522_Reset(void) {
	MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_RESETPHASE);
}

void MFRC522_AntennaOn(void) {
	uint8_t temp;

	temp = MFRC522_ReadRegister(MFRC522_REG_TX_CONTROL);
	if (!(temp & 0x03)) MFRC522_SetBitMask(MFRC522_REG_TX_CONTROL, 0x03);
}

void MFRC522_AntennaOff(void) {
	MFRC522_ClearBitMask(MFRC522_REG_TX_CONTROL, 0x03);
}

void MFRC522_Halt(void) {
	uint16_t unLen;
	uint8_t buff[4]; 

	buff[0] = PICC_HALT;
	buff[1] = 0;
	MFRC522_CalculateCRC(buff, 2, &buff[2]);
	MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &unLen);
}

RC522.h

#ifndef __RC522_H
#define __RC522_H

#include "main.h"

// RC522 use SPIx define
#define RC522_SPI					SPI1
// SPI write read define
#define SPISendByte(data)			SPIClass.WriteRead(RC522_SPI, data, 1000)
// SPI CS define
#define cs_reset() 					SPIClass.WriteCSPin(RC522_SPI, Bit_RESET)
#define cs_set() 					SPIClass.WriteCSPin(RC522_SPI, Bit_SET)

// Status enumeration, Used with most functions
#define MI_OK											0
#define MI_NOTAGERR										1
#define MI_ERR											2

// MFRC522 Commands
#define PCD_IDLE										0x00	// NO action; Cancel the current command
#define PCD_AUTHENT										0x0E  	// Authentication Key
#define PCD_RECEIVE										0x08   	// Receive Data
#define PCD_TRANSMIT									0x04   	// Transmit data
#define PCD_TRANSCEIVE									0x0C   	// Transmit and receive data,
#define PCD_RESETPHASE									0x0F   	// Reset
#define PCD_CALCCRC										0x03   	// CRC Calculate

// Mifare_One card command word
#define PICC_REQIDL										0x26   	// find the antenna area does not enter hibernation
#define PICC_REQALL										0x52   	// find all the cards antenna area
#define PICC_ANTICOLL									0x93   	// anti-collision
#define PICC_SElECTTAG									0x93   	// election card
#define PICC_AUTHENT1A									0x60   	// authentication key A
#define PICC_AUTHENT1B									0x61   	// authentication key B
#define PICC_READ										0x30   	// Read Block
#define PICC_WRITE										0xA0   	// write block
#define PICC_DECREMENT									0xC0   	// debit
#define PICC_INCREMENT									0xC1   	// recharge
#define PICC_RESTORE									0xC2   	// transfer block data to the buffer
#define PICC_TRANSFER									0xB0   	// save the data in the buffer
#define PICC_HALT										0x50   	// Sleep

// MFRC522 Registers
// Page 0: Command and Status
#define MFRC522_REG_RESERVED00					0x00
#define MFRC522_REG_COMMAND						0x01
#define MFRC522_REG_COMM_IE_N					0x02
#define MFRC522_REG_DIV1_EN						0x03
#define MFRC522_REG_COMM_IRQ					0x04
#define MFRC522_REG_DIV_IRQ						0x05
#define MFRC522_REG_ERROR						0x06
#define MFRC522_REG_STATUS1						0x07
#define MFRC522_REG_STATUS2						0x08
#define MFRC522_REG_FIFO_DATA					0x09
#define MFRC522_REG_FIFO_LEVEL					0x0A
#define MFRC522_REG_WATER_LEVEL					0x0B
#define MFRC522_REG_CONTROL						0x0C
#define MFRC522_REG_BIT_FRAMING					0x0D
#define MFRC522_REG_COLL						0x0E
#define MFRC522_REG_RESERVED01					0x0F
// Page 1: Command
#define MFRC522_REG_RESERVED10					0x10
#define MFRC522_REG_MODE						0x11
#define MFRC522_REG_TX_MODE						0x12
#define MFRC522_REG_RX_MODE						0x13
#define MFRC522_REG_TX_CONTROL					0x14
#define MFRC522_REG_TX_AUTO						0x15
#define MFRC522_REG_TX_SELL						0x16
#define MFRC522_REG_RX_SELL						0x17
#define MFRC522_REG_RX_THRESHOLD				0x18
#define MFRC522_REG_DEMOD						0x19
#define MFRC522_REG_RESERVED11					0x1A
#define MFRC522_REG_RESERVED12					0x1B
#define MFRC522_REG_MIFARE						0x1C
#define MFRC522_REG_RESERVED13					0x1D
#define MFRC522_REG_RESERVED14					0x1E
#define MFRC522_REG_SERIALSPEED					0x1F
// Page 2: CFG
#define MFRC522_REG_RESERVED20					0x20
#define MFRC522_REG_CRC_RESULT_M				0x21
#define MFRC522_REG_CRC_RESULT_L				0x22
#define MFRC522_REG_RESERVED21					0x23
#define MFRC522_REG_MOD_WIDTH					0x24
#define MFRC522_REG_RESERVED22					0x25
#define MFRC522_REG_RF_CFG						0x26
#define MFRC522_REG_GS_N						0x27
#define MFRC522_REG_CWGS_PREG					0x28
#define MFRC522_REG__MODGS_PREG					0x29
#define MFRC522_REG_T_MODE						0x2A
#define MFRC522_REG_T_PRESCALER					0x2B
#define MFRC522_REG_T_RELOAD_H					0x2C
#define MFRC522_REG_T_RELOAD_L					0x2D
#define MFRC522_REG_T_COUNTER_VALUE_H			0x2E
#define MFRC522_REG_T_COUNTER_VALUE_L			0x2F
// Page 3:TestRegister
#define MFRC522_REG_RESERVED30					0x30
#define MFRC522_REG_TEST_SEL1					0x31
#define MFRC522_REG_TEST_SEL2					0x32
#define MFRC522_REG_TEST_PIN_EN					0x33
#define MFRC522_REG_TEST_PIN_VALUE				0x34
#define MFRC522_REG_TEST_BUS					0x35
#define MFRC522_REG_AUTO_TEST					0x36
#define MFRC522_REG_VERSION						0x37
#define MFRC522_REG_ANALOG_TEST					0x38
#define MFRC522_REG_TEST_ADC1					0x39
#define MFRC522_REG_TEST_ADC2					0x3A
#define MFRC522_REG_TEST_ADC0					0x3B
#define MFRC522_REG_RESERVED31					0x3C
#define MFRC522_REG_RESERVED32					0x3D
#define MFRC522_REG_RESERVED33					0x3E
#define MFRC522_REG_RESERVED34					0x3F

#define MFRC522_DUMMY							0x00		// Dummy byte
#define MFRC522_MAX_LEN							16			// Buf len byte

// RC522
uint8_t MFRC522_Check(uint8_t* id);
uint8_t MFRC522_Compare(uint8_t* CardID, uint8_t* CompareID);
void MFRC522_WriteRegister(uint8_t addr, uint8_t val);
uint8_t MFRC522_ReadRegister(uint8_t addr);
void MFRC522_SetBitMask(uint8_t reg, uint8_t mask);
void MFRC522_ClearBitMask(uint8_t reg, uint8_t mask);
uint8_t MFRC522_Request(uint8_t reqMode, uint8_t* TagType);
uint8_t MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen);
uint8_t MFRC522_Anticoll(uint8_t* serNum);
void MFRC522_CalulateCRC(uint8_t* pIndata, uint8_t len, uint8_t* pOutData);
uint8_t MFRC522_SelectTag(uint8_t* serNum);
uint8_t MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t* Sectorkey, uint8_t* serNum);
uint8_t MFRC522_Read(uint8_t blockAddr, uint8_t* recvData);
uint8_t MFRC522_Write(uint8_t blockAddr, uint8_t* writeData);
void MFRC522_Init(void);
void MFRC522_Reset(void);
void MFRC522_AntennaOn(void);
void MFRC522_AntennaOff(void);
void MFRC522_Halt(void);

// user template
uint8_t RC522_cardScan(uint8_t *cardID);

#endif

驱动下载地址:

https://download.csdn.net/download/m0_50669075/87672906

STM32工程模板、外设模板、模块模板下载地址:

stm32_template: STM32F103工程模板,外设模板,模块模板。模块模板包括:DHT11温湿度传感器,OLED屏幕,DS18B20温度传感器,DS1302时钟模块,红外测温模块,RFID模块,SIM900A短信模块,OneNET入网,ADXL345三轴传感器,离线语音识别模块,语音播报模块,甲醛传感器,PM2.5模块,SG90舵机,健康检测模块,消息队列示例,链表示例,分时调度系统示例等。

  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
STM32F407IGT6单片机RFID射频(RC522)模块实验KEIL软件DEMO工程源码,可做为你的人学习设计参考。 int main(void) { /* 复位所有外设,初始化Flash接口和系统滴答定时器 */ HAL_Init(); /* 配置系统时钟 */ SystemClock_Config(); /* 初始化串口并配置串口中断优先级 */ MX_DEBUG_USART_Init(); /* 初始化3.5寸TFT液晶模组,一般优先于调试串口初始化 */ BSP_LCD_Init(); LCD_Clear(0,0,LCD_DEFAULT_WIDTH,LCD_DEFAULT_HEIGTH,BLACK); /* 开背光 */ LCD_BK_ON(); LCD_DispString_EN_CH(70,50,(uint8_t *)"YS-F4Pro开发板",BLACK,BLUE,USB_FONT_24); printf("RC522初始化\n"); RC522_Init(); PcdReset(); M500PcdConfigISOType ( 'A' );/* 设置工作方式 */ printf("RC522初始化完成\n"); while ( 1 ) { IC_test ();/* IC卡检测 */ } } /** * 函数功能: 门禁测试函数 * 输入参数: 无 * 返 回 值: 无 * 说 明: 无 */ void IC_test ( void ) { char cStr [ 30 ]; unsigned char ucArray_ID [ 4 ]; /* 先后存放IC卡的类型和UID(IC卡序列号) */ uint8_t ucStatusReturn; /* 返回状态*/ while ( 1 ) { /*寻卡*/ if ( ( ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ) ) != MI_OK ) /*若失败再次寻卡*/ ucStatusReturn = PcdRequest ( PICC_REQALL, ucArray_ID ); if ( ucStatusReturn == MI_OK ) { /*防冲撞(当有多张卡进入读写器操作范围时,防冲突机制会从其中选择一张进行操作)*/ if ( PcdAnticoll ( ucArray_ID ) == MI_OK ) { sprintf ( cStr, "The Card ID is: %02X%02X%02X%02X", ucArray_ID [ 0 ], ucArray_ID [ 1 ], ucArray_ID [ 2 ], ucArray_ID [ 3 ] ); printf ( "%s\r\n",cStr ); LCD_DispString_EN(10,200,cStr,BLACK,RED,USB_FONT_24); } } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿衰0110

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值