发新帖我要提问
12
返回列表
打印
[应用相关]

STM32 RC522相关驱动

[复制链接]
楼主: gaoke231
手机看帖
扫描二维码
随时随地手机跟帖
21
gaoke231|  楼主 | 2018-2-28 21:47 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
首先来了解RC522的数字通信接口问题。RC522支持SPI、I2C和UART接口。我手里的模块使用的是SPI接口。那么,使用不同的通信接口是如何选择的呢?在RC522的数据手册中给出了检测方式。

使用特权

评论回复
22
gaoke231|  楼主 | 2018-2-28 21:47 | 只看该作者

使用特权

评论回复
23
gaoke231|  楼主 | 2018-2-28 21:48 | 只看该作者
RC522的SPI总线接口有其自身的时序要求。它只能工作于从模式,最高传输速率为10 Mbps,数据与时钟相位关系满足“空闲态时钟为低电平,在时钟上升沿同步接收和发送数据,在下降沿数据转换”的约束关系。

使用特权

评论回复
24
gaoke231|  楼主 | 2018-2-28 21:48 | 只看该作者
本文中配置STM32的SPI1工作于主模式下,时钟小于10Mbps,接收和发送数据都在时钟上升沿发生。提前说一下,针对SPI的时钟,通过SPI_InitStructure.SPI_BaudRatePrescaler= SPI_BaudRatePrescaler_n;这句话来配置,其中n=2、4、8、16、32、64、128、256.SPI1的输入时钟是72MHz,72/8=9<10,所以n的取值必须要大于8,我在开始调试程序时,使用的SPI_BaudRatePrescaler_8,但调试发现,只能实现read功能,其它功能都报错。后来改成SPI_BaudRatePrescaler_256.然后其它功能都正常工作了。所以通信速率低一点好像更好!

使用特权

评论回复
25
gaoke231|  楼主 | 2018-2-28 21:49 | 只看该作者
本程序使用的是RFID-RC522射频模块设计的一个门禁系统,当感应卡放到射频模块区域内会感应到
        卡,如果卡序列号和程序设计一致就会认为是正确开锁,D2指示灯亮,LCD上显示开锁,5秒钟以后
        自动关锁,D2指示灯灭。当卡错误时候不会显示,D2也不会亮。卡的序列号是唯一的。
       
        管脚接线图:
        RST---PF4
        MISO---PF3
        MOSI---PF2
        SCK---PF1
        NSS(SDA)--PF0

使用特权

评论回复
26
gaoke231|  楼主 | 2018-2-28 21:49 | 只看该作者
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd_driver.h"
#include "gui.h"
#include "tim.h"
#include "RC522.h"



unsigned char data1[16] = {0x12,0x34,0x56,0x78,0xED,0xCB,0xA9,0x87,0x12,0x34,0x56,0x78,0x01,0xFE,0x01,0xFE};
//M1卡的某一块写为如下格式,则该块为钱包,可接收扣款和充值命令
//4字节金额(低字节在前)+4字节金额取反+4字节金额+1字节块地址+1字节块地址取反+1字节块地址+1字节块地址取反
unsigned char data2[4]  = {0,0,0,0x01};
unsigned char DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};


unsigned char g_ucTempbuf[20]

使用特权

评论回复
27
gaoke231|  楼主 | 2018-2-28 21:50 | 只看该作者
主函数
int main(void)
{       
        unsigned char status,i;
        unsigned int temp;
        delay_init();
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
       
        led_init();
        TFT_Init();
        lcd_display();
        RC522_Init();
        PcdReset();
        PcdAntennaOff();
        delay_ms(10);
        PcdAntennaOn();
        delay_ms(10);
        tim3_init(1000,7199);
        uart_init(9600);         //波特率使用9600
        printf("Start \r\n");
        while ( 1 )
     {   
                 status = PcdRequest(PICC_REQALL, g_ucTempbuf);//寻卡
         if (status != MI_OK)
         {   
                     PcdReset();
                     PcdAntennaOff();
                     PcdAntennaOn();
                          continue;
         }                     
                 printf("卡的类型:");
            for(i=0;i<2;i++)
                {
                        temp=g_ucTempbuf[i];
                        printf("%X",temp);
                       
                }       
         status = PcdAnticoll(g_ucTempbuf);//防冲撞
         if(status != MI_OK)
         {    continue;    }
                  
                ////////以下为超级终端打印出的内容////////////////////////
       
                printf("卡序列号:");        //超级终端显示,
                for(i=0;i<4;i++)
                {
                        temp=g_ucTempbuf[i];
                        printf("%X",temp);
                       
                }

                if(g_ucTempbuf[0]==0xd4&&g_ucTempbuf[1]==0xd5&&g_ucTempbuf[2]==0x34&&g_ucTempbuf[3]==0x00)
                {
                        led1=0;
                        GUI_Show12ASCII(10,110,"Open Door...  ",RED,BLACK);        //开门
                }
                else
                {       
                        led1=1;       
                        GUI_Show12ASCII(10,110,"               ",RED,BLACK);
                }

                ///////////////////////////////////////////////////////////

             status = PcdSelect(g_ucTempbuf);//选定卡片
             if (status != MI_OK)
             {    continue;    }
             
             status = PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, g_ucTempbuf);//验证卡片密码
             if (status != MI_OK)
             {    continue;    }
             
             status = PcdWrite(1, data1);//写块
         if (status != MI_OK)
         {    continue;    }

                while(1)
                {
                 status = PcdRequest(PICC_REQALL, g_ucTempbuf);//寻卡
                 if (status != MI_OK)
                 {   
                        
                             PcdReset();
                             PcdAntennaOff();
                             PcdAntennaOn();
                                  continue;
                 }
                         status = PcdAnticoll(g_ucTempbuf);//防冲撞
                 if (status != MI_OK)
                 {    continue;    }

                        status = PcdSelect(g_ucTempbuf);//选定卡片
                 if (status != MI_OK)
                 {    continue;    }
                
                 status = PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, g_ucTempbuf);//验证卡片密码
                 if (status != MI_OK)
                 {    continue;    }


                 status = PcdValue(PICC_DECREMENT,1,data2);//扣款
                 if (status != MI_OK)
                 {    continue;    }
                         
                 status = PcdBakValue(1, 2);//块备份
                 if (status != MI_OK)
                 {    continue;    }
                
                 status = PcdRead(2, g_ucTempbuf);//读块
                 if (status != MI_OK)
                 {    continue;    }
                printf("卡读块:");        //超级终端显示,
                 for(i=0;i<16;i++)
                        {
                                temp=g_ucTempbuf[i];
                                printf("%X",temp);
                               
                        }

                        printf("\n");                                                         
                        PcdHalt();
                }       
    }
       
}

使用特权

评论回复
28
gaoke231|  楼主 | 2018-2-28 21:51 | 只看该作者
按照GPIO引脚连接后 烧录RC522代码上电,可以识别卡号和类型

使用特权

评论回复
29
gaoke231|  楼主 | 2018-2-28 21:58 | 只看该作者
当识别正确时LCD显示开门信息,验证卡号正确。

使用特权

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

本版积分规则