RC522读卡器 M1卡学习总结(二)

RC522读卡器 M1卡学习总结(二)二、说说RC522读卡器       我从淘宝里买来的读卡器模块如下:M1卡 学习总结(二)”title=”RC522读卡器 M1卡 学习总结(二)”style=”margin:0px;padding:0px;border:0px;list-style:none”>它带有一组接口:SDA  SCK  MOSI  MISO  IRQ(NG)  GND  RST  3

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

二、说说RC522读卡器

       我从淘宝里买来的读卡器模块如下:

                                            —-》防冲突检查(Anticollision Loop)选择一张卡片,返回该卡序列号;

                                           —–》选择卡片(Select Tag),选择被选中的卡的序列号,返回卡的容量代码;

                                           —–》三次互相确认(3 Pass Authentication)通过密码校验之后,三次互相认                                             证                                                   之后可以通讯。

 

M1卡指令:

                 读(Read):读一个块;

                 写(Write):写一个块;

                 加值(Increment):对数值块进行加值;

                 减值(Decrement):对数值块进行减值;

                 存储(Restore):将块中数据保存到数据寄存器中;

                 传输(Transfer):将数据寄存器中内容写入到块中;

                 终止(Halt):将卡置于暂停工作状体。


三、RC522读卡器的使用–硬件部分

       我使用了stm8s103来驱动RC522读卡器,硬件连接如下:

      stm8s103引脚                      RC522接口

      3.3v                    ———-   3.3v

      GND                   ———    GND

      PC4                    ———     SDA(NSS)

      PC5(SPI_SCK)    ———     SCK

      PC6(SPI_MISO) ———     MISO

      PC7(SPI_MOSI) ———     MOSI

      至少接这6针。

 

     使用stm8s芯片的spi接口来和rc522通讯,通过相应的寄存器可控制SPI接口的数据传输率、数据时钟相位等通信参数。

     这里使用spi通讯,1/4分频,空闲低电平,第一个时钟周期开始采样,第一个时钟边缘开始数据采样。

注意:片选信号必须保证在写入数据流期间为低电平,而在无数据流写入时为高电平,不得为了省事而一直将NSS置为低电平。


四、单片机stm8s与读卡器RC522通讯—-软件部分

      单片机与读卡器的接口

      RC522读卡器提供三种接口,分别是UART,I2C,SPI这三种接口。我们这里选择了spi接口。关于stm8s为主机,rc522读卡器为从机。spi使用4个管脚与从设备相连,MISO,MOSI,SCK,NSS.

       这里有一点需要注意:MOSI管脚相互连接,MISO脚相互连接。这样,数据在主和从之间串行地传输(MSB位在前)。通信总是由主设备发起。主设备通过MOSI脚把数据发送给从设备,从设备通过MISO引脚回传数据。这意味全双工通信的数据输出和数据输入是用同一个时钟信号同步的:时钟信号由主设备通过SCK脚提供。

(1)SPI初始化如下:

void init_SPI_Master(void)
       
        SPI_CR1 = 0x04;          //fMaster/2, 配置为主设备,空闲低电平,第一个时钟周期开始采样
        SPI_CR2 = 0x03;           //内部指定主模式,NSS上电平决定该位值
        SPI_CRCPR = 0x07;
        SPI_ICR = 0x00;            //中断禁止
        SPI_CR1 |= 0x40;          //开启SPI

}

(2)UART初始化,这里为了调试方便,我们使用uart接口来观察执行情况。

void init_UART(void)
{

       UART1_CR2=0x00;//使发送禁用TEN=0;
       UART1_CR1=0x00;//设置M字长,8位数据位
       UART1_CR3=0x00;//1位停止位
 
       UART1_BRR2=0X00;      //波特率9600,分频系数=2000000/9600=208
       UART1_BRR1=0X0D;       //208=0X0D;
       UART1_CR2=0X2C;       //b3=1,允许发送  b2=1,允许接收  b5=1,允许产生接收中断
}

 (3)UART发送数据函数

void UARTSend(uchar aa)
{

  UART1_CR2=0x00;
  UART1_DR=aa;                   

  UART1_CR2=0x08;
  while((UART1_SR & 0x40) ==0);
  UART1_CR2=0x2c;//0x2c;//0x08; 2位 rev使能 3位 发送使能 5–rien 
}

(4)UART接收中断处理函数

@far @interrupt void UART1_RX_IRQHandler(void)  //UART1_Receiver(void)
{

     unsigned char i;
     _asm(“sim”);    //关总中断
      a=UART1_DR;      //将接收的字符放到a中
     _asm(“rim”);    //开总中断
    return;
}

(5)SPI接收发送字节

//spi接口在写的时候要先发送,发送不一定要传送内容,只是为了
//给从机提供时钟,因为sck是主机来发出的,所以写函数里面要有发送指令,目的是提供从机写时钟
uchar SPIWriteByte(uchar spiData)
{

   uchar retry=0;
  while((SPI_SR & 0X02)==0)  //等待发送区空
  {

   retry++;
   if(retry>200) return 0;  //防止死机
  }
 
  SPI_DR=spiData;             //发送一个byte
  retry=0;
  while((SPI_SR|0X80)==0X80);  //等待通信结束
 
  while((SPI_SR & 0X01)==0);  //等待接收缓冲区空
  {

     retry++;
    if(retry>200) return 0;
  }
  return SPI_DR;    //返回受到的数
 

}

(6)main.c主程序函数

void main()
{

 uchar i;
 uchar Card_Type1[2];
 uchar Card_ID[4];
 uchar Card_KEY[6] = {0xff,0xff,0xff,0xff,0xff,0xff};  
 uchar Card_Data[16];
 uchar status;
  //fmaster=fcpu=2MHz
 CLK_ECKR=0x00;
 CLK_ICKR=0x01;
 CLK_CMSR=0xe1;
 
 CLK_SWR=0xe1;
 CLK_CKDIVR=0x18;

 init_IO();
 init_UART();
 init_SPI_Master();
 
 _asm(“rim”);    //开总中断,便于产生串口接收中断

 status=PcdReset();
 PcdAntennaOff();
 delay(20);
 PcdAntennaOn();
 M500PcdConfigISOType( ‘A’ );
 a=0x63;
 nblock=4;//kuan 0
 t=0;
 while(1)
 {

  

        //    PcdAntennaOff();
        //测试一下接口是否正确
        status = CheckMCURC522interface();
        if(status != MI_OK)
        {

             UARTSend(0x04);
             continue;
        }
    
         status = PcdRequest(PICC_REQALL, g_ucTempbuf);
           if (status != MI_OK)
          {    
              continue;
           }
         //  UARTSend(a);//0x11);
         //  for(i=0;i<8;i++)
         //  UARTSend(g_ucTempbuf[i]);//0400 e52b 0000000000
       

         delay(20);//

         status = PcdAnticoll(g_ucTempbuf);
         if (status != MI_OK)
         {    continue;    }
         //   UARTSend(0x12);
         delay(20);//delay_ms(2);
         status = PcdSelect(g_ucTempbuf);
         if (status != MI_OK)
         {    continue;    }
        //   UARTSend(0x13);
         delay(20);//

       //   UARTSend(nblock);
       //认证卡
         status = PcdAuthState(PICC_AUTHENT1A, nblock, DefaultKey, g_ucTempbuf);
         if (status != MI_OK)
         {    continue;    }
        //   UARTSend(0x14);
        delay(20);//

       if(a==b) continue;
       else b=a;
       UARTSend(a);  //发送执行的命令代码
     switch(a)
     {

     case 0x91://写电子钱包数据到块nblock
       status = PcdWrite(nblock, data1);
         if(status==MI_OK)
       {

        UARTSend(0x88);
        
       }
       else UARTSend(0x44);
       break;
     case 0x92://写普通数据到块nblock
       status = PcdWrite(nblock, data3);
         if(status==MI_OK)
       {

        UARTSend(0x88);
        
       }
       else UARTSend(0x44);
         break;
     case 0x93://从块n中读取数据
       status = PcdRead(nblock, g_ucTempbuf);//PcdRead(2, g_ucTempbuf);
        if (status == MI_OK)
        {   
        UARTSend(0x88);
        for(i=0;i<16;i++)
         UARTSend(g_ucTempbuf[i]);//把写进去的数
        }
        else  UARTSend(0x44);
        break;
     case 0x94://从块n中读取数据
       status = PcdRead(nblock, g_ucTempbuf);//PcdRead(2, g_ucTempbuf);
        if (status == MI_OK)
        {   
        UARTSend(0x88);
        for(i=0;i<16;i++)
         UARTSend(g_ucTempbuf[i]);//把写进去的数
        }
        else  UARTSend(0x44);
        break;
     case 0x95://操作电子钱包
       status = PcdValue(PICC_DECREMENT,nblock,data2);
       if (status == MI_OK)
        
         UARTSend(0x88);
         for(i=0;i<4;i++)
           UARTSend(data2[i]);//
       }
        else  UARTSend(0x44);
       break;
     case 0x96: //备份电子钱包
       status = PcdBakValue(nblock, nblock+1);
        if (status == MI_OK)
        
         UARTSend(0x88);
        
       }
        else  UARTSend(0x44);
        break;
     default:break;
     
     }
    
       
  //    PcdHalt();
  //    PcdAntennaOff();
 }
}

(7)RC522的库函数和网上都基本一样,就不写了。

以上程序本人已经测试过了。

 

(8)本人在学习rc522的过程中参考了很多文章,在此表示感谢!

M1卡介绍  http://wenku.baidu.com/view/62cccb122e3f5727a4e9625c.html

M1卡激活成功教程密码控制位及控制规则http://www.docin.com/p-624326551.html

Mifare1技术说明(M1卡说明文档) http://www.docin.com/p-379085837.html

基于非接触式ic卡的读卡器的设计与开发http://www.docin.com/p-906980594.html

      13.56M读卡器开发详解二http://blog.sina.com.cn/s/blog_6754612e0101c0pe.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/193779.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • C++写一个CSGO开箱模拟器「建议收藏」

    C++写一个CSGO开箱模拟器「建议收藏」head玩过csgo的人类都知道,开箱是很有趣的。————名人名言Appstore上有专门的开箱模拟器,但是啊,他有广告。(;′⌒`)所以心善的博主决定自己用C++手撸一款开箱模拟器:3A大作,有整整一种箱子可供选择附加开箱动画,效果及其逼真…

  • Moya 浅析_motivationally

    Moya 浅析_motivationallyMoya是一个高度抽象的网络库,他的理念是让你不用关心网络请求的底层的实现细节,只用定义你关心的业务。且Moya采用桥接和组合来进行封装(默认桥接了Alamofire),使得Moya非常好扩展,让你不用修改Moya源码就可以轻易定制。官方给出几个Moya主要优点:编译时检查APIendpoint权限让你使用枚举定义各种不同Target,endpoints把stubs当做…

    2022年10月25日
  • javascript中Date常用方法[通俗易懂]

    javascript中Date常用方法[通俗易懂]一、Date的构造函数有四种形式的Date构造函数:二、返回日期对应的毫秒数1.Date.parse()Date.parse()接收一个日期字符串,返回该日期对应的毫秒数。2.Date.UT

  • Linux防火墙关闭方法[通俗易懂]

    Linux防火墙关闭方法[通俗易懂]Linux防火墙关闭方法关闭防火墙:1、查看状态:systemctlstatusfirewalld2、关闭:systemctlstopfirewalld(只执行这个,重启后不行,还必须执行systemcltdisablefirewalld)1.1、查看selinux状态:getenforce2.2、关闭:编辑文件/etc/selinux…

  • Pytorch深度学习实战教程:UNet模型训练

    Pytorch深度学习实战教程:UNet模型训练1前言本文属于Pytorch深度学习语义分割系列教程。该系列文章的内容有:Pytorch的基本使用语义分割算法讲解由于微信不允许外部链接,你需要点击页尾左下角的“阅读原文”,才能访…

  • 我是如何利用“王宝强离婚”事件来吸粉的

    我是如何利用“王宝强离婚”事件来吸粉的

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号