GD32F303RCT6 RC522模块的使用
1、rc522接口为spi,21节我们已经初始化了spi1,这一节我们继续使用spi1与rc522进行通信。
接口如下:
gd32 -------- rc522
pc7 -------- rst
pb12 -------- cs
pb13 -------- clk
pb14 -------- miso
pb15 -------- mosi
2、利用上节freertos的两个任务,我们一个任务去寻卡,读卡,另一个任务控制led的闪烁,没读到卡的时候,200ms频率闪烁,当读到卡时,改为50ms频率闪烁,闪烁二十次后,再次改为200ms闪烁。其中,快速闪烁的时候,不再响应卡片。
3、Rc522的驱动网上很多,直接套用就行,主要的是要替换成自己的spi读写函数。
spi.c里初始化spi的函数,之前讲过。
void spi1_config(void)
{
spi_parameter_struct spi_init_struct;
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_SPI1);
rcu_periph_clock_enable(RCU_AF);
/* SPI1 GPIO config:SCK/PB13, MISO/PB14, MOSI/PB15 */
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_15);
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_14);
/* PB12 as NSS */
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
/* SPI1 parameter config */
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_struct.device_mode = SPI_MASTER;
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
spi_init_struct.nss = SPI_NSS_SOFT;
spi_init_struct.prescale = SPI_PSC_16; //速率
spi_init_struct.endian = SPI_ENDIAN_MSB;
spi_init(SPI1, &spi_init_struct);
spi_enable(SPI1);
}
spi的读写函数,写一个读一个
uint8_t spi1_rw_onebyte(uint8_t w_data)
{
uint8_t value;
while(RESET == spi_i2s_flag_get(SPI1, SPI_FLAG_TBE));
spi_i2s_data_transmit(SPI1, w_data);
while(RESET == spi_i2s_flag_get(SPI1, SPI_FLAG_RBNE));
value = spi_i2s_data_receive(SPI1);
return value;
}
4、Rc522驱动
Rc522.c,主要替换自己的管脚。
#include "rc522.h"
#include "systick.h"
#include "spi.h"
#include "type.h"
#ifdef ENABLE_FREERTOS
#include "FreeRTOS.h"
#include "task.h"
#endif
// PC 07 Rst
// PB 12 CS
#define RS522_RST_HIGH gpio_bit_set(GPIOC, GPIO_PIN_7)
#define RS522_RST_LOW gpio_bit_set(GPIOC, GPIO_PIN_7)
#define RS522_NSS_HIGH gpio_bit_set(GPIOB,GPIO_PIN_12)
#define RS522_NSS_LOW gpio_bit_reset(GPIOB,GPIO_PIN_12)
static void RC522_Delay(uint32_t ms)
{
#ifdef ENABLE_FREERTOS
vTaskDelay(ms);
#else
delay_1ms(ms);
#endif
}
static void RC522_Rst_Gpio_Init(void)
{
rcu_periph_clock_enable(RCU_GPIOC);
/* PC7 as Rst */
gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
}
/***************************************************************************************
* 函数名称:PCD_Init
* 功能描述:读写器初始化
* 入口参数:无
* 出口参数:无
* 返 回 值:无
* 说 明:无
***************************************************************************************/
void PCD_Init(void)
{
RC522_Rst_Gpio_Init();
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;
}
/**************************************************************************************
* 函数名称:MFRC_Init
* 功能描述:MFRC初始化
* 入口参数:无
* 出口参数:无
* 返 回 值:无
* 说 明:MFRC的SPI接口速率为0~10Mbps
***************************************************************************************/
void MFRC_Init(void)
{
RS522_NSS_HIGH;
RS522_RST_HIGH;
}
/**************************************************************************************
* 函数名称:PCD_Reset
* 功能描述:PCD复位
* 入口参数:无
* 出口参数:无
* 返 回 值:无
* 说 明:无
***************************************************************************************/
void PCD_Reset(void)
{
/*硬复位*/
RS522_RST_HIGH;//用到我们的复位引脚
RC522_Delay(2);
RS522_RST_LOW;
RC522_Delay(2);
RS522_RST_HIGH;
RC522_Delay(2);
/*软复位*/
MFRC_WriteReg(MFRC_CommandReg, MFRC_RESETPHASE);
RC522_Delay(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(); //关天线
RC522_Delay(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);
}
/**************************************************************************************
* 函数名称: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;
}
/**************************************************************************************
* 函数名称:MFRC_ReadReg
* 功能描述:读一个寄存器
* 入口参数:-addr:待读的寄存器地址
* 出口参数:无
* 返 回 值:-data:读到寄存器的数据
* 说 明:无
***************************************************************************************/
uint8_t MFRC_ReadReg(uint8_t addr)
{
uint8_t AddrByte, data;
AddrByte = ((addr << 1 ) & 0x7E ) | 0x80; //求出地址字节
RS522_NSS_LOW; //NSS拉低
spi1_rw_onebyte(AddrByte); //写地址字节
data = spi1_rw_onebyte(0x00); //读数据
RS522_NSS_HIGH; //NSS拉高
return data;
}
/**************************************************************************************
* 函数名称:MFRC_WriteReg
* 功能描述:写一个寄存器
* 入口参数:-addr:待写的寄存器地址 data 待写的数据
* 出口参数:无
* 说 明:无
***************************************************************************************/
void MFRC_WriteReg(uint8_t addr, uint8_t data)
{
uint8_t tmp_addr;
tmp_addr = ((addr << 1) & 0x7E);
RS522_NSS_LOW;
RC522_Delay(1);
spi1_rw_onebyte(tmp_addr);
spi1_rw_onebyte(data);
RS522_NSS_HIGH;
}
/**************************************************************************************
* 函数名称: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); //处理过的数据再写入寄存器
}
RC522.h
#ifndef _RC522_H
#define _RC522_H
//头文件
//************************************************
#include "gd32f30x.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、main函数调用:
我只有一个卡,卡的id为0x7a2e7989,当匹配成功后,灯快速闪烁。后面继续增加存储卡片id的功能,然后可增加删减,这样是不是就可以做一个智能锁了呢?
#ifdef ENABLE_FREERTOS
#define RC522_TASK_PRIO ( tskIDLE_PRIORITY + 1)
#define LED2_TASK_PRIO ( tskIDLE_PRIORITY + 3 )
void RC522_task(void * pvParameters);
void LED2_task(void * pvParameters);
static int led_freq = 200;
static int get_card_flag = 0;
static int led_num = 0;
void RC522_task(void * pvParameters)
{
//RC522 Config
PCD_Init();
uint8_t card_type[2] = {0};
uint8_t card_id[4] = {0};
for( ;; ){
vTaskDelay(100);
if (0 == PCD_Request(0x26,card_type))
{
uint16_t type = (card_type[0]<<8 | card_type[1]);
if (type == 0x0400)
{
if (PCD_Anticoll(card_id) == 0)
{
if (((card_id[0]<<24) |(card_id[1] << 16) | (card_id[2] << 8) | card_id[3]) == 0x7a2e7989)
{
if (get_card_flag == 0)
{
led_freq = 50;
led_num = 0;
get_card_flag = 1;
}
}
}
}
}
}
}
void LED2_task(void * pvParameters)
{
for( ;; ){
if (get_card_flag == 1)
{
if (led_num == 20 )
{
led_num = 0;
get_card_flag = 0;
led_freq = 1000;
}
led_num++;
}
gpio_bit_set(GPIOB, GPIO_PIN_4);
vTaskDelay(led_freq);
gpio_bit_reset(GPIOB, GPIO_PIN_4);
vTaskDelay(led_freq);
}
}
#ifdef ENABLE_FREERTOS
xTaskCreate(RC522_task, "RC522", 128*4, NULL, RC522_TASK_PRIO, NULL);
xTaskCreate(LED2_task, "LED2", configMINIMAL_STACK_SIZE, NULL, LED2_TASK_PRIO, NULL);
/* start scheduler */
vTaskStartScheduler();
#endif
6、视频如下:
IMG_4164
7、代码路径:https://gitee.com/xiaoguo-tec_0/gd32-iap-code.git