本帖最后由 李浔玖 于 2023-8-30 17:35 编辑
基于STM32F103RCT6(HAL库)+RC522RFID模块开发读写模块
首先准备好需要使用的硬件设备: 正点原子MiniSTM32开发板一块, MiniRFID-RC522模块一个, 杜邦线七条, miniUSB线一条, ST_Link一个(ST_Link是需要一根miniUSB线与20pin接口线的,也可采用4条杜邦线连接;也可换为J_Link),M1白卡一张,
STM32 Cobe MX配置: 配置外部时钟72M 配置引脚: PA3->input PA4->output PD2->output PA8->outpu 配置SPI1默认引脚,打开中断,Parameter Settings界面下Prescaile(for Baud Rate)配置为16 配置USART1默认引脚,打开中断 然后就正常生成代码.
代码部分: rc522.c /*************笔记****************
1、接线方式:
STM32 RFID
PA4 -> SDA
PA5 -> SCK
PA7 -> MOSI
PA6 -> MISO
悬空 -> IKQ
GND -> GND
PA3 -> RST
3.3V -> 3.3V
​
2、应用函数
MFRC_Init();//初始化
PCD_Reset();//器件复位
PCD_Request(PICC_REQALL, RxBuffer);//返回值为0,代表寻卡成功;并把卡类型存入RxBuffer中
PCD_Anticoll(RxBuffer); //把(十六进制)的4个字节卡号存储在数组RxBuffer中
***********************************/
​
#include "rc522.h"
#include "usart.h"
​
extern SPI_HandleTypeDef hspi1;
​
/**************************************************************************************
* 函数名称: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(&hspi1, &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);
}
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 = 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(); //开天线
}
/**************************************************************************************
* 函数名称: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;
snr_check ^= CmdFrameBuf;
}
if(snr_check != CmdFrameBuf)
{
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 = *(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;
}
}
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 = *(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;
}
​
​rc522.h #ifndef _RC522_H
#define _RC522_H
​
#include "main.h"
#include <stdint.h>
​
/*******************************************************************************
* rc522.c文件宏定义 *
*********************************************************************************/
#define RC522_CS_GPIO_Port GPIOA
#define RC522_CS_Pin GPIO_PIN_4//cs nss sda是一个东西
#define RC522_RST_GPIO_Port GPIOA
#define RC522_RST_Pin GPIO_PIN_3
​
#define osDelay HAL_Delay
​
#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)
​
/***********************************************************************************
* 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);//初始化RC522
void MFRC_WriteReg(uint8_t addr, uint8_t data);//向RC522写寄存器
uint8_t MFRC_ReadReg(uint8_t addr);//读RC522寄存器
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);//用MFRC计算CRC结果
char MFRC_CmdFrame(uint8_t cmd, uint8_t *pInData, uint8_t InLenByte, uint8_t *pOutData, uint16_t *pOutLenBit);//MFRC522和ISO14443A卡通讯的命令帧函数
​
/***********************************************************************************
* 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);//初始化PCD
void PCD_Reset(void);//复位PCD
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 StartIDcardTask(void const * argument);//启动ID卡任务
​
#endif
​rfid.c #include "rfid.h"
#include "rc522.h"
#include <ctype.h>
#include <stdio.h>
#include <string.h>
​
​
int RFID_WritFlag = 0;//写RFID标志位
char RFID_FLAG = PCD_ERR;//RFID状态
uint8_t RFID_WriteData[16] = "1234567890ABCDEF";//需要写入IC卡内的数据
uint8_t key_A[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};//密钥A
uint8_t key_B[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};//密钥B
​
/*******************************************************************************
*函数名 :RFID_Handl RFID处理
*补充 :此函数只做RFID逻辑处理
*作者 i Xunjiu
*********************************************************************************/
void RFID_Handl(void)
{
uint8_t CardType[4];//卡类型
uint8_t Card_ID[4];//卡ID
char RFID_ReadData[16];//读取卡内的数据
​
RFID_FLAG = PCD_Request(PICC_REQIDL, CardType);//返回值为0,代表寻卡成功;并把卡类型存入CardType中
if(RFID_FLAG == PCD_OK)
{
RFID_FLAG = PCD_ERR;
AntiCollision(Card_ID);//进行防冲撞及获取ID
SIM_Card(Card_ID);//选卡
Key_Verification(PICC_AUTHENT1A,7,key_A,Card_ID);//验证
WriteCard(6,RFID_WriteData);//写卡
ReadCard(6,(uint8_t *)RFID_ReadData);//读卡
PCD_Halt();//RFID进入休眠
memset(Card_ID, 0, sizeof(Card_ID));//清空字符串
memset(RFID_WriteData, 0, sizeof(RFID_WriteData));//清空字符串
memset(RFID_ReadData, 0, sizeof(RFID_ReadData));//清空字符串
HAL_Delay(1000);
}
HAL_Delay(100);
return;
}
​
/*******************************************************************************
* 函数名 :convertToUpper
*函数参数 :str ->需要更改大小写的数组
*补充 :将数组内的元素大写
*作者 i Xunjiu
*********************************************************************************/
void convertToUpper(uint8_t *str)
{
int i = 0;
while (str)
{
str = toupper(str);
i++;
}
}
/*******************************************************************************
* 函数名 :SIM_Card 选择卡
*函数参数 :cardID ->卡号ID
*作者 i Xunjiu
*********************************************************************************/
void SIM_Card(uint8_t * cardID)
{
RFID_FLAG = PCD_Select(cardID);//选卡
if(RFID_FLAG == PCD_OK)
{
RFID_FLAG = PCD_ERR;
printf("选卡成功\r\n");
return;
}
else
{
printf("选卡失败\r\n");
return;
}
}
​
/*******************************************************************************
* 函数名 :AntiCollision 防冲撞并获取卡ID
*函数参数 :readUid 读取RFID的卡号
*作者 i Xunjiu
*********************************************************************************/
​
void AntiCollision(uint8_t * cardID)
{
RFID_FLAG = PCD_Anticoll(cardID); //防冲撞,完成这步就可以简单地读取卡号,本次不涉及更高层次应用
if(RFID_FLAG == PCD_OK)
{
char CardTem[4];
RFID_FLAG = PCD_ERR;
sprintf(CardTem,"%x%x%x%x",cardID[0],cardID[1],cardID[2],cardID[3]);
convertToUpper((uint8_t *) CardTem);
printf("ID=%s\r\n",(uint8_t *)CardTem);
return;
}
}
​
/*******************************************************************************
* 函数名 :Key_Verification 密钥验证
*函数参数 :authmode ->密钥验证模式(A或是B)
* addr ->密钥验证地址(每个扇区的区块3)
* key ->验证的密钥值
* UID ->卡的序列号(4位)
*作者 i Xunjiu
*********************************************************************************/
void Key_Verification(uint8_t authmode,uint8_t addr,uint8_t * key,uint8_t * UID)
{
​
RFID_FLAG = PCD_AuthState(authmode, addr, key, UID);//解密
if(RFID_FLAG == PCD_OK)
{
RFID_FLAG = PCD_ERR;
printf("密钥验证成功\r\n");
return;
}
else
{
printf("密钥验证成功\r\n");
return;
}
}
​
/*******************************************************************************
* 函数名 :WriteCard 向IC卡内写数据
*函数参数 :addr ->需要写入数据的区块地址
* RFID_WriteData ->需要写入的数据
*作者 i Xunjiu
*********************************************************************************/
void WriteCard(uint8_t addr,uint8_t *RFID_WriteData)
{
if(RFID_WritFlag == 1)
{
uint8_t EmptyStr[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
PCD_WriteBlock(addr,(uint8_t *)EmptyStr);
printf("数据块已清空,开始写入新数据!\r\n");
RFID_FLAG = PCD_WriteBlock(addr, (uint8_t *)RFID_WriteData);//写卡
if(RFID_FLAG == PCD_OK)
{
RFID_FLAG = PCD_ERR;
printf("写卡成功\r\n");
RFID_WritFlag = 0;
return;
}
else
{
printf("写卡失败:%d\r\n",RFID_FLAG);
RFID_WritFlag = 0;
return;
}
}
else printf("未开启RFID写标志!\r\n");
RFID_WritFlag = 0;
return;
}
​
/*******************************************************************************
* 函数名 :ReadCard 读取卡的数据
*函数参数 :addr ->需要读的区块地址0~15(8扇区每个扇区4个数据块一个数代表一个数据块)
* RFID_ReadData ->卡内读出的数据
*作者 i Xunjiu
*********************************************************************************/
void ReadCard(uint8_t addr,uint8_t *RFID_ReadData)
{
char RFID_FLAG = PCD_ERR;
RFID_FLAG = PCD_ReadBlock(addr, RFID_ReadData);//读卡
if(RFID_FLAG == PCD_OK)
{
RFID_FLAG = PCD_ERR;
printf("读卡成功:%s\r\n",(char *) RFID_ReadData);//这里输出的数据后面后跟所读数据的卡号
HAL_Delay(500);
return;
}
else
{
printf("读卡失败:%d\r\n",RFID_FLAG);
return;
}
}
​rfid.h #ifndef _RFID_H
#define _RFID_H
​
#include "main.h"
​
extern int RFID_WritFlag;
extern char RFID_FLAG;
​
extern uint8_t key_A[6];
extern uint8_t key_B[6];
extern uint8_t RFID_WriteData[16];
​
void RFID_Handl(void);//RFID处理函数
​
void convertToUpper(uint8_t *str); //将字符格式标注仅大写
​
void SIM_Card(uint8_t * cardID);//选卡
​
void AntiCollision(uint8_t * cardID);//防冲撞及获取ID
​
void Key_Verification(uint8_t authmode,uint8_t addr,uint8_t * key,uint8_t * UID);//验证密钥
​
void WriteCard(uint8_t addr,uint8_t *RFID_WriteData);//向卡内写入数据
​
void ReadCard(uint8_t addr,uint8_t *RFID_ReadData);//读卡数据
uint8_t RFIDReadCard(uint8_t *readUid, uint8_t *cardID);
​
​
​
#endif
​
​
​
​usart.c /* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usart.c
* @brief This file provides code for the configuration
* of the USART instances.
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"
​
/* USER CODE BEGIN 0 */
#include "rfid.h"
​
int UartDataReceived = 0;//串口开启标志位
int UartFalg = 0;//串口接收数据标志
int UartRxLen =0;//串口接收数据长度
uint8_t Uart_Rx_Buf[1];//串口接收缓冲
uint8_t UartData[300];//串口数据
/* USER CODE END 0 */
​
UART_HandleTypeDef huart1;
​
/* USART1 init function */
​
void MX_USART1_UART_Init(void)
{
​
/* USER CODE BEGIN USART1_Init 0 */
​
/* USER CODE END USART1_Init 0 */
​
/* USER CODE BEGIN USART1_Init 1 */
​
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
__enable_irq();//使能串口中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)Uart_Rx_Buf, 1);
/* USER CODE END USART1_Init 2 */
​
}
​
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
​
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
​
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
​
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
​
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
​
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
​
/* USER CODE END USART1_MspInit 1 */
}
}
​
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
​
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
​
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
​
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
​
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
​
/* USER CODE END USART1_MspDeInit 1 */
}
}
​
/* USER CODE BEGIN 1 */
/*******************************************************************************
* 函数名 :printf
*功能描述:输出函数
*函数参数:ch,*p
* 返回值 :ch
*补充说明:该函数是标准库stdio.h内的输出函数,在这只是重定向其输出方向
*作者 i Xunjiu
*********************************************************************************/
int fputc(int ch,FILE *p)
{
char c = ch;
HAL_UART_Transmit(&huart1,(unsigned char *)&c, 1, 50);
return ch;
}
/*******************************************************************************
* 函数名 :HAL_UART_RxCpltCallback
*功能描述:串口回调函数
*函数参数:
* 返回值 :无
*补充说明:该函数是HAL库内的函数,只是在这重写了
*作者 i Xunjiu
*********************************************************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
uint8_t Uart_Data_Buf[300];//串口数据缓冲
if (huart == &huart1) // 处理串口1的数据
{
UartDataReceived = 1;//开启串标志位
UartFalg++; //每接收到一个数据,进入回调数据长度加1
Uart_Data_Buf[UartFalg-1] = Uart_Rx_Buf[0]; //把每次接收到的数据保存到缓存数组
​
if (Uart_Data_Buf[UartFalg-1]== ';')//接收结束标志判断
{
memcpy(UartData, Uart_Data_Buf, UartFalg * sizeof(uint8_t)); //将数组Uart_Data_Buf中的数据转交给Uart_Data
memset(Uart_Data_Buf, 0, sizeof(Uart_Data_Buf)); //清空缓存数组
UartRxLen = UartFalg; //将UartFalg的值赋给UartRxLen
UartFalg = 0; //清空接收标志
}
​
Uart_Rx_Buf[0] = 0; //重置接收缓冲
​
// 每接收一个数据,打开一次串口中断接收,否则只会接收一个数据就停止接收
HAL_UART_Receive_IT(&huart1, (uint8_t *)Uart_Rx_Buf, 1);
}
}
​
​
/*******************************************************************************
* 函数名 :USART_Handl
*功能描述:串口数据处理
*函数参数:无
* 返回值 :无
*补充说明:该函数只做接收的的函数处理,所有串口数据皆在该函数内进行,外部只需调用即可
*作者 i Xunjiu
*********************************************************************************/
void USART_Handl(void)
{
if(UartDataReceived == 0)//串口标志未开启
{
HAL_UART_Receive_IT(&huart1, (uint8_t *)Uart_Rx_Buf, 1);
}
if(UartDataReceived == 1)//串口标志已开启
{
printf("串口开启接收数据成功!\r\n");
if(memcmp(UartData, "Set_CardData:", 13) == 0)
{
if(UartRxLen-14<=16)
{
RFID_WritFlag = 1;//开启RFID写标志
for(int i = 0;i<UartRxLen-14;i++)
{
RFID_WriteData=UartData[i+13];
}
printf("数据获取完成开始写数据:%s\r\n",RFID_WriteData);
RFID_Handl();
}
else printf("只支持16位数据修改,您的数据不合法!\n\r");
}
UartDataReceived = 0;
}
return;
}
​
/* USER CODE END 1 */
​main.c(注意:main.c这个文件因为cobe生成的代码太多部分以删除) /* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "spi.h"
#include "usart.h"
#include "gpio.h"
​
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "rc522.h"
#include "rfid.h"
/* USER CODE END Includes */
​
int main(void)
{
/* USER CODE BEGIN 1 */
​
/* USER CODE END 1 */
​
/* MCU Configuration--------------------------------------------------------*/
​
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
​
/* USER CODE BEGIN Init */
​
/* USER CODE END Init */
​
/* Configure the system clock */
SystemClock_Config();
​
/* USER CODE BEGIN SysInit */
PCD_Init();//初始化RC522
/* USER CODE END SysInit */
​
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI1_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
LED0 = 0;
LED1 = 1;
printf("初始化完成,程序开始运行中...\r\n");
/* USER CODE END 2 */
​
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
//USART_Handl();//串口处理函数
RFID_Handl();//RFID处理函数
/* USER CODE END WHILE */
​
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
​最终实验现象
|