打印
[STM32F0]

基于STM32F030实现RFID射频识别

[复制链接]
手机看帖
扫描二维码
随时随地手机跟帖
21
个百zz分点个|  楼主 | 2022-9-29 15:10 | 只看该作者 回帖奖励 |倒序浏览
// 读RC522寄存器
uint8_t RC522_ReadData(uint8_t address)
{
        uint8_t data = 0;
       
        SPI2_CS_ENABLE;       
        SPI2_ReadWriteByte(((address << 1) | 0x80) & 0xfe);
        data = SPI2_ReadWriteByte(DUMMY_BYTE);
        SPI2_CS_DISABLE;
       
        return data;
}

使用特权

评论回复
22
个百zz分点个|  楼主 | 2022-9-29 15:11 | 只看该作者
在sensor_rfid.c文件中定义RC522_WriteData()函数,函数通过SPI时序实现写RC522寄存器操作

使用特权

评论回复
23
个百zz分点个|  楼主 | 2022-9-29 15:12 | 只看该作者
// 写RC522寄存器
void RC522_WriteData(uint8_t address, uint8_t data)
{   
        SPI2_CS_ENABLE;
        SPI2_ReadWriteByte((address << 1) & 0x7e);
        SPI2_ReadWriteByte(data);
        SPI2_CS_DISABLE;
}

使用特权

评论回复
24
个百zz分点个|  楼主 | 2022-9-29 15:14 | 只看该作者
在sensor_rfid.c文件中添加RC522_SetReg()函数,将RC522某寄存器进行置位

使用特权

评论回复
25
个百zz分点个|  楼主 | 2022-9-29 15:15 | 只看该作者
// 置RC522寄存器位
void RC522_SetReg(uint8_t reg, uint8_t data)  
{
        uint8_t reg_data = RC522_ReadData(reg);
        RC522_WriteData(reg, reg_data|data);  
}

使用特权

评论回复
26
个百zz分点个|  楼主 | 2022-9-29 15:19 | 只看该作者
在sensor_rfid.c文件中添加RC522_ClearReg()函数,将RC522某寄存器进行复位

使用特权

评论回复
27
个百zz分点个|  楼主 | 2022-9-29 15:20 | 只看该作者
// 清RC522寄存器位
void RC522_ClearReg(uint8_t reg, uint8_t data)
{
uint8_t reg_data = RC522_ReadData(reg);
          RC522_WriteData(reg, reg_data & ~data);
}

使用特权

评论回复
28
个百zz分点个|  楼主 | 2022-9-29 15:23 | 只看该作者
在sensor_rfid.c文件中定义RC522_Reset()函数,实现对芯片进行复位。函数通过向RC522中寄存器写相应数据实现对RC522芯片的复位操作

使用特权

评论回复
29
个百zz分点个|  楼主 | 2022-9-29 15:25 | 只看该作者
// 对RCC522芯片进行复位
void RC522_Reset(void)
{
        RC522_WriteData(CommandReg, PCD_RESETPHASE);
        RC522_WriteData(ModeReg, 0x3D);           
        RC522_WriteData(TReloadRegL, 30);           
        RC522_WriteData(TReloadRegH, 0);
        RC522_WriteData(TModeReg, 0x8D);
        RC522_WriteData(TPrescalerReg, 0x3E);
        RC522_WriteData(TxASKReg, 0x40);
}

使用特权

评论回复
30
个百zz分点个|  楼主 | 2022-9-29 15:27 | 只看该作者
在sensor_rfid.c文件中添加RC522_AntennaOn()函数,打开RC522天线

使用特权

评论回复
31
个百zz分点个|  楼主 | 2022-9-29 15:28 | 只看该作者
// 打开天线
void RC522_AntennaOn(void)
{
if(!(RC522_ReadData(TxControlReg) & 0x03))
          {
                RC522_SetReg(TxControlReg, 0x03);
          }
}

使用特权

评论回复
32
个百zz分点个|  楼主 | 2022-9-29 15:29 | 只看该作者
在sensor_rfid.c文件中添加RC522_AntennaOff()函数,关闭RC522天线
// 关闭天线
void RC522_AntennaOff(void)
{
        RC522_ClearReg(TxControlReg, 0x03);
}

使用特权

评论回复
33
个百zz分点个|  楼主 | 2022-9-29 15:33 | 只看该作者
在sensor_rfid.c文件中添加M1Card_Config()函数,实现ISO14443A型卡初始化

使用特权

评论回复
34
个百zz分点个|  楼主 | 2022-9-29 15:34 | 只看该作者
// 针对M1卡进行初始化
void M1Card_Config(void)
{
        RC522_ClearReg(Status2Reg, 0x08);
        RC522_WriteData(ModeReg, 0x3D);
        RC522_WriteData(RxSelReg, 0x86);
        RC522_WriteData(RFCfgReg, 0x7F);   
        RC522_WriteData(TReloadRegL, 30);
        RC522_WriteData(TReloadRegH, 0);
        RC522_WriteData(TModeReg, 0x8D);
        RC522_WriteData(TPrescalerReg, 0x3E);
        RC522_AntennaOn();
}

使用特权

评论回复
35
个百zz分点个|  楼主 | 2022-9-29 15:35 | 只看该作者
在sensor_rfid.c文件中添加RC522_Init()函数,函数中实现了RC522复位、关闭天线、打开天线和ISO14443A型卡初始化

使用特权

评论回复
36
个百zz分点个|  楼主 | 2022-9-29 15:37 | 只看该作者
// 初始化RC522
void RC522_Init(void)
{
RC522_Reset();        // 对RC522芯片进行复位
          RC522_AntennaOff(); // 关闭天线
          RC522_AntennaOn();        // 打开天线
          M1Card_Config(); // 针对M1卡进行初始化
}

使用特权

评论回复
37
个百zz分点个|  楼主 | 2022-9-29 15:38 | 只看该作者
// 初始化RC522
void RC522_Init(void)
{
RC522_Reset();        // 对RC522芯片进行复位
          RC522_AntennaOff(); // 关闭天线
          RC522_AntennaOn();        // 打开天线
          M1Card_Config(); // 针对M1卡进行初始化
}

使用特权

评论回复
38
个百zz分点个|  楼主 | 2022-9-29 15:39 | 只看该作者
在sensor_rfid.c文件中添加RC522_CardCom()函数,实现RC522和IC卡通讯,函数如下

使用特权

评论回复
39
个百zz分点个|  楼主 | 2022-9-29 15:41 | 只看该作者
// 通过RC522和ISO14443卡通讯
int8_t RC522_CardCom(uint8_t Command, uint8_t *InData, uint8_t InLength, uint8_t *OutData, uint32_t *OutLength)
{
        uint8_t  waitFor = 0x00;
        switch(Command)
        {
            case PCD_AUTHENT: // 验证密钥
                waitFor = 0x10; // 认证寻卡等待时间 查询空闲中断标志位
                break;
            case PCD_TRANSCEIVE: // 接收发送 发送接收
                waitFor = 0x30;
                break;
            default:
                break;
        }

        RC522_ClearReg(ComIrqReg, 0x80); // 清楚中断标志
        RC522_WriteData(CommandReg, PCD_IDLE); // 关闭接收机的模拟部分,进入软关机模式,进入IDLE模式
        RC522_SetReg(FIFOLevelReg, 0x80); // 清楚Fifo缓冲区及状态位

        // 写数据进FIFOdata
        for(uint32_t i=0; i<InLength; i++)
        {
            RC522_WriteData(FIFODataReg, InData[i]);
        }
       
        // 写入命令(PCD_TRANSCEIVE:开始传输并且传输完成后自动接收数据    PCD_AUTHENT:作为读取器执行MIFARE®标准身份验证)
        RC522_WriteData(CommandReg, Command);          
  
        if(Command == PCD_TRANSCEIVE)
        {
            // 开始传输数据
            RC522_SetReg(BitFramingReg, 0x80);
        }
       
        // 读取中断状态。PCD_TRANSCEIVE:等待接收完成或空闲模式  PCD_AUTHENT:等待系统进入空闲模式。
        uint8_t state;
        uint16_t i;
        for(i=1200; i>0; i--)
        {
            state = RC522_ReadData(ComIrqReg);
            if(state&waitFor || state&0x01)
            {
                break;
            }
        }       
        // 停止传输数据
        RC522_ClearReg(BitFramingReg, 0x80);

        int8_t status = MI_ERR;
        if(i!=0) // 如果进入空闲模式
        {   
            if(!(RC522_ReadData(ErrorReg)&0x1B)) // 判断是否存在错误。FIFO溢出、位冲突、奇偶校验错误、协议错误
            {
                status = MI_OK;
                if(Command == PCD_TRANSCEIVE)
                {
                    // 计算输出数据长度(位)
                    uint8_t number = RC522_ReadData(FIFOLevelReg); // 读FIFO中保存的字节数
                    uint8_t rxLastBits = RC522_ReadData(ControlReg) & 0x07; // 最后接收到的字节的有效位数
                    if(rxLastBits)
                    {
                        *OutLength = (number-1) * 8 + rxLastBits; // 读取到的数据总位数
                    }
                    else
                    {
                        *OutLength = number * 8; // 最后接收到的字节整个字节有效
                    }
                               
                    // 计算输出数据长度(位)
                    if(number == 0)
                    {
                        number = 1;
                    }
                    if(number > MAXRLEN)
                    {
                        number = MAXRLEN;
                    }
                    for(i=0; i<number; i++)
                    {
                        OutData[i] = RC522_ReadData(FIFODataReg);
                    }
                }
            }
            else
            {
                status = MI_ERR;
            }
        }
        RC522_SetReg(ControlReg, 0x80);
        RC522_WriteData(CommandReg, PCD_IDLE);
        return status;
}

使用特权

评论回复
40
个百zz分点个|  楼主 | 2022-9-29 15:42 | 只看该作者
在sensor_rfid.c文件中添加Card_Find()函数,实现寻卡操作。函数将我们的寻卡命令PICC_REQIDL装填入要发送的数组,通过PcdComMF522()函数发送出去,如果此时在PCD有效范围内没有寻找到卡,则函数返回MI_ERR,若函数返回MI_OK,并且OutLen为0x10(16bit)为两个字节则说明寻卡成功,返回的两字节被装填入CardRevBuf数组

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则